@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.
- package/.npm-cache/_logs/{2026-01-11T13_30_32_048Z-debug-0.log → 2026-01-16T16_53_49_411Z-debug-0.log} +2 -2
- package/package.json +4 -4
- package/v1/protocol/SolanaProtocol.d.ts +13 -1
- package/v1/protocol/SolanaProtocol.js +373 -70
- package/v1/protocol/SolanaProtocol.js.map +1 -1
- package/v1/protocol/SolanaSPLTokenProtocol.d.ts +11 -1
- package/v1/protocol/SolanaSPLTokenProtocol.js +616 -199
- package/v1/protocol/SolanaSPLTokenProtocol.js.map +1 -1
- package/v1/types/protocol.d.ts +20 -0
|
@@ -79,16 +79,192 @@ var SolanaProtocol_1 = require("./SolanaProtocol");
|
|
|
79
79
|
// SPL Token Program ID
|
|
80
80
|
var TOKEN_PROGRAM_ID = new solanaWeb3.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
|
|
81
81
|
var ASSOCIATED_TOKEN_PROGRAM_ID = new solanaWeb3.PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
|
|
82
|
-
|
|
83
|
-
//
|
|
84
|
-
var
|
|
82
|
+
var MEMO_PROGRAM_ID = new solanaWeb3.PublicKey('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr');
|
|
83
|
+
// Memo prefix for wallet address hints (used for offline ATA resolution in Vault)
|
|
84
|
+
var WALLET_HINT_PREFIX = 'wallet:';
|
|
85
|
+
// Token account size in bytes (for rent exemption calculation)
|
|
86
|
+
var TOKEN_ACCOUNT_SIZE = 165;
|
|
87
|
+
// Default fee constants (fallback when network queries fail)
|
|
88
|
+
var DEFAULT_BASE_FEE_LAMPORTS = 5000;
|
|
89
|
+
var DEFAULT_TOKEN_ACCOUNT_RENT = 2039280; // Fallback rent exemption
|
|
90
|
+
var DEFAULT_SPL_TRANSFER_CU = 30000; // Fallback CU for SPL transfer
|
|
91
|
+
var DEFAULT_ATA_CREATE_CU = 25000; // Fallback CU for ATA creation
|
|
92
|
+
// Cache TTL configuration
|
|
93
|
+
var RENT_EXEMPTION_CACHE_TTL = 300000; // 5 minutes
|
|
85
94
|
// Implementation
|
|
86
95
|
var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
87
96
|
function SolanaSPLTokenProtocolImpl(options) {
|
|
88
97
|
this.options = options;
|
|
98
|
+
// Caches
|
|
99
|
+
this.priorityFeeCache = { data: null, timestamp: 0 };
|
|
100
|
+
this.rentExemptionCache = { value: null, timestamp: 0 };
|
|
89
101
|
this.units = options.units;
|
|
90
102
|
this.mainUnit = options.mainUnit;
|
|
91
103
|
}
|
|
104
|
+
// Get minimum balance for rent exemption for token accounts (dynamic)
|
|
105
|
+
SolanaSPLTokenProtocolImpl.prototype.getTokenAccountRentExemption = function () {
|
|
106
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
107
|
+
var now, rentExemption, e_1;
|
|
108
|
+
var _this = this;
|
|
109
|
+
return __generator(this, function (_a) {
|
|
110
|
+
switch (_a.label) {
|
|
111
|
+
case 0:
|
|
112
|
+
now = Date.now();
|
|
113
|
+
if (this.rentExemptionCache.value !== null &&
|
|
114
|
+
(now - this.rentExemptionCache.timestamp) < RENT_EXEMPTION_CACHE_TTL) {
|
|
115
|
+
return [2 /*return*/, this.rentExemptionCache.value];
|
|
116
|
+
}
|
|
117
|
+
_a.label = 1;
|
|
118
|
+
case 1:
|
|
119
|
+
_a.trys.push([1, 3, , 4]);
|
|
120
|
+
return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
|
|
121
|
+
return __generator(this, function (_a) {
|
|
122
|
+
return [2 /*return*/, connection.getMinimumBalanceForRentExemption(TOKEN_ACCOUNT_SIZE)];
|
|
123
|
+
});
|
|
124
|
+
}); })];
|
|
125
|
+
case 2:
|
|
126
|
+
rentExemption = _a.sent();
|
|
127
|
+
this.rentExemptionCache = { value: rentExemption, timestamp: now };
|
|
128
|
+
return [2 /*return*/, rentExemption];
|
|
129
|
+
case 3:
|
|
130
|
+
e_1 = _a.sent();
|
|
131
|
+
console.warn('[solana-spl][getTokenAccountRentExemption] Failed, using default:', e_1);
|
|
132
|
+
return [2 /*return*/, DEFAULT_TOKEN_ACCOUNT_RENT];
|
|
133
|
+
case 4: return [2 /*return*/];
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
// Simulate a transaction to get actual compute units consumed
|
|
139
|
+
SolanaSPLTokenProtocolImpl.prototype.simulateTransaction = function (transaction) {
|
|
140
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
141
|
+
var result, e_2;
|
|
142
|
+
var _this = this;
|
|
143
|
+
return __generator(this, function (_a) {
|
|
144
|
+
switch (_a.label) {
|
|
145
|
+
case 0:
|
|
146
|
+
_a.trys.push([0, 2, , 3]);
|
|
147
|
+
return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
|
|
148
|
+
var blockhash;
|
|
149
|
+
return __generator(this, function (_a) {
|
|
150
|
+
switch (_a.label) {
|
|
151
|
+
case 0:
|
|
152
|
+
if (!!transaction.recentBlockhash) return [3 /*break*/, 2];
|
|
153
|
+
return [4 /*yield*/, connection.getLatestBlockhash()];
|
|
154
|
+
case 1:
|
|
155
|
+
blockhash = (_a.sent()).blockhash;
|
|
156
|
+
transaction.recentBlockhash = blockhash;
|
|
157
|
+
_a.label = 2;
|
|
158
|
+
case 2:
|
|
159
|
+
// For legacy Transaction, use the simple overload without config
|
|
160
|
+
return [2 /*return*/, connection.simulateTransaction(transaction)];
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
}); })];
|
|
164
|
+
case 1:
|
|
165
|
+
result = _a.sent();
|
|
166
|
+
if (result.value.err) {
|
|
167
|
+
return [2 /*return*/, {
|
|
168
|
+
success: false,
|
|
169
|
+
unitsConsumed: 0,
|
|
170
|
+
error: JSON.stringify(result.value.err)
|
|
171
|
+
}];
|
|
172
|
+
}
|
|
173
|
+
return [2 /*return*/, {
|
|
174
|
+
success: true,
|
|
175
|
+
unitsConsumed: result.value.unitsConsumed || 0
|
|
176
|
+
}];
|
|
177
|
+
case 2:
|
|
178
|
+
e_2 = _a.sent();
|
|
179
|
+
console.warn('[solana-spl][simulateTransaction] Simulation failed:', e_2);
|
|
180
|
+
return [2 /*return*/, {
|
|
181
|
+
success: false,
|
|
182
|
+
unitsConsumed: 0,
|
|
183
|
+
error: String(e_2)
|
|
184
|
+
}];
|
|
185
|
+
case 3: return [2 /*return*/];
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
// Get recent priority fees from the network
|
|
191
|
+
SolanaSPLTokenProtocolImpl.prototype.getRecentPriorityFees = function () {
|
|
192
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
193
|
+
var now, recentFees, allFeeValues, hasNonZeroFees, feeValues, getPercentile, estimate, e_3;
|
|
194
|
+
var _this = this;
|
|
195
|
+
return __generator(this, function (_a) {
|
|
196
|
+
switch (_a.label) {
|
|
197
|
+
case 0:
|
|
198
|
+
now = Date.now();
|
|
199
|
+
if (this.priorityFeeCache.data && (now - this.priorityFeeCache.timestamp) < SolanaSPLTokenProtocolImpl.PRIORITY_FEE_CACHE_TTL) {
|
|
200
|
+
return [2 /*return*/, this.priorityFeeCache.data];
|
|
201
|
+
}
|
|
202
|
+
_a.label = 1;
|
|
203
|
+
case 1:
|
|
204
|
+
_a.trys.push([1, 3, , 4]);
|
|
205
|
+
return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
|
|
206
|
+
return __generator(this, function (_a) {
|
|
207
|
+
return [2 /*return*/, connection.getRecentPrioritizationFees()];
|
|
208
|
+
});
|
|
209
|
+
}); })];
|
|
210
|
+
case 2:
|
|
211
|
+
recentFees = _a.sent();
|
|
212
|
+
if (!recentFees || recentFees.length === 0) {
|
|
213
|
+
return [2 /*return*/, this.getDefaultPriorityFees()];
|
|
214
|
+
}
|
|
215
|
+
allFeeValues = recentFees.map(function (f) { return f.prioritizationFee; });
|
|
216
|
+
hasNonZeroFees = allFeeValues.some(function (f) { return f > 0; });
|
|
217
|
+
if (!hasNonZeroFees) {
|
|
218
|
+
// Network is idle, no priority fee needed
|
|
219
|
+
return [2 /*return*/, {
|
|
220
|
+
none: 0,
|
|
221
|
+
low: 0,
|
|
222
|
+
medium: 0,
|
|
223
|
+
high: 0,
|
|
224
|
+
veryHigh: 0
|
|
225
|
+
}];
|
|
226
|
+
}
|
|
227
|
+
feeValues = allFeeValues
|
|
228
|
+
.filter(function (f) { return f > 0; })
|
|
229
|
+
.sort(function (a, b) { return a - b; });
|
|
230
|
+
if (feeValues.length === 0) {
|
|
231
|
+
return [2 /*return*/, this.getDefaultPriorityFees()];
|
|
232
|
+
}
|
|
233
|
+
getPercentile = function (arr, p) {
|
|
234
|
+
var index = Math.ceil((p / 100) * arr.length) - 1;
|
|
235
|
+
return arr[Math.max(0, Math.min(index, arr.length - 1))];
|
|
236
|
+
};
|
|
237
|
+
estimate = {
|
|
238
|
+
none: 0,
|
|
239
|
+
low: getPercentile(feeValues, 25),
|
|
240
|
+
medium: getPercentile(feeValues, 50),
|
|
241
|
+
high: getPercentile(feeValues, 75),
|
|
242
|
+
veryHigh: getPercentile(feeValues, 90)
|
|
243
|
+
};
|
|
244
|
+
this.priorityFeeCache = { data: estimate, timestamp: now };
|
|
245
|
+
return [2 /*return*/, estimate];
|
|
246
|
+
case 3:
|
|
247
|
+
e_3 = _a.sent();
|
|
248
|
+
console.warn('[solana-spl][getRecentPriorityFees] Failed:', e_3);
|
|
249
|
+
return [2 /*return*/, this.getDefaultPriorityFees()];
|
|
250
|
+
case 4: return [2 /*return*/];
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
};
|
|
255
|
+
SolanaSPLTokenProtocolImpl.prototype.getDefaultPriorityFees = function () {
|
|
256
|
+
return {
|
|
257
|
+
none: 0,
|
|
258
|
+
low: 1000,
|
|
259
|
+
medium: 10000,
|
|
260
|
+
high: 100000,
|
|
261
|
+
veryHigh: 1000000
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
SolanaSPLTokenProtocolImpl.prototype.calculateTotalFee = function (baseFee, priorityFeePerCU, computeUnits) {
|
|
265
|
+
var priorityFeeLamports = Math.ceil((computeUnits * priorityFeePerCU) / 1000000);
|
|
266
|
+
return baseFee + priorityFeeLamports;
|
|
267
|
+
};
|
|
92
268
|
// Helper for RPC calls with fallback to backup endpoints
|
|
93
269
|
SolanaSPLTokenProtocolImpl.prototype.withFallback = function (fn, maxRetries) {
|
|
94
270
|
var _a, _b, _c, _d, _e;
|
|
@@ -105,7 +281,7 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
105
281
|
if (!(_i < allUrls_1.length)) return [3 /*break*/, 6];
|
|
106
282
|
rpcUrl = allUrls_1[_i];
|
|
107
283
|
_loop_1 = function (retry) {
|
|
108
|
-
var connection, _g,
|
|
284
|
+
var connection, _g, e_4, isTemporaryError;
|
|
109
285
|
return __generator(this, function (_h) {
|
|
110
286
|
switch (_h.label) {
|
|
111
287
|
case 0:
|
|
@@ -115,13 +291,13 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
115
291
|
return [4 /*yield*/, fn(connection)];
|
|
116
292
|
case 1: return [2 /*return*/, (_g.value = _h.sent(), _g)];
|
|
117
293
|
case 2:
|
|
118
|
-
|
|
119
|
-
lastError =
|
|
120
|
-
isTemporaryError = ((_a =
|
|
121
|
-
((_b =
|
|
122
|
-
((_c =
|
|
123
|
-
((_d =
|
|
124
|
-
((_e =
|
|
294
|
+
e_4 = _h.sent();
|
|
295
|
+
lastError = e_4;
|
|
296
|
+
isTemporaryError = ((_a = e_4 === null || e_4 === void 0 ? void 0 : e_4.message) === null || _a === void 0 ? void 0 : _a.includes('500')) ||
|
|
297
|
+
((_b = e_4 === null || e_4 === void 0 ? void 0 : e_4.message) === null || _b === void 0 ? void 0 : _b.includes('502')) ||
|
|
298
|
+
((_c = e_4 === null || e_4 === void 0 ? void 0 : e_4.message) === null || _c === void 0 ? void 0 : _c.includes('503')) ||
|
|
299
|
+
((_d = e_4 === null || e_4 === void 0 ? void 0 : e_4.message) === null || _d === void 0 ? void 0 : _d.includes('code":19')) ||
|
|
300
|
+
((_e = e_4 === null || e_4 === void 0 ? void 0 : e_4.message) === null || _e === void 0 ? void 0 : _e.includes('Temporary'));
|
|
125
301
|
if (!isTemporaryError) {
|
|
126
302
|
return [2 /*return*/, "break"];
|
|
127
303
|
}
|
|
@@ -285,7 +461,7 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
285
461
|
// Returns the owner (wallet) address of a token account
|
|
286
462
|
SolanaSPLTokenProtocolImpl.prototype.getWalletAddressFromAta = function (ataAddress) {
|
|
287
463
|
return __awaiter(this, void 0, void 0, function () {
|
|
288
|
-
var ataPubkey_1, accountInfo, ownerBytes, ownerPubkey,
|
|
464
|
+
var ataPubkey_1, accountInfo, ownerBytes, ownerPubkey, e_5;
|
|
289
465
|
var _this = this;
|
|
290
466
|
return __generator(this, function (_a) {
|
|
291
467
|
switch (_a.label) {
|
|
@@ -304,8 +480,8 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
304
480
|
ownerPubkey = new solanaWeb3.PublicKey(ownerBytes);
|
|
305
481
|
return [2 /*return*/, ownerPubkey.toBase58()];
|
|
306
482
|
case 2:
|
|
307
|
-
|
|
308
|
-
console.warn('[solana-spl][getWalletAddressFromAta] Failed to get wallet address:',
|
|
483
|
+
e_5 = _a.sent();
|
|
484
|
+
console.warn('[solana-spl][getWalletAddressFromAta] Failed to get wallet address:', e_5);
|
|
309
485
|
return [2 /*return*/, null];
|
|
310
486
|
case 3: return [2 /*return*/];
|
|
311
487
|
}
|
|
@@ -314,7 +490,7 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
314
490
|
};
|
|
315
491
|
SolanaSPLTokenProtocolImpl.prototype.getBalanceOfAddress = function (address) {
|
|
316
492
|
return __awaiter(this, void 0, void 0, function () {
|
|
317
|
-
var walletPubkey_1, mintPubkey_1, tokenAccounts, totalBalance, _i, _a, account, data, amountBytes, amount,
|
|
493
|
+
var walletPubkey_1, mintPubkey_1, tokenAccounts, totalBalance, _i, _a, account, data, amountBytes, amount, e_6;
|
|
318
494
|
var _this = this;
|
|
319
495
|
return __generator(this, function (_b) {
|
|
320
496
|
switch (_b.label) {
|
|
@@ -341,8 +517,8 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
341
517
|
total: (0, module_kit_1.newAmount)(totalBalance.toString(), 'blockchain')
|
|
342
518
|
}];
|
|
343
519
|
case 2:
|
|
344
|
-
|
|
345
|
-
console.error('[solana-spl][balance][error]',
|
|
520
|
+
e_6 = _b.sent();
|
|
521
|
+
console.error('[solana-spl][balance][error]', e_6);
|
|
346
522
|
return [2 /*return*/, { total: (0, module_kit_1.newAmount)(0, 'blockchain') }];
|
|
347
523
|
case 3: return [2 /*return*/];
|
|
348
524
|
}
|
|
@@ -379,106 +555,143 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
379
555
|
});
|
|
380
556
|
};
|
|
381
557
|
SolanaSPLTokenProtocolImpl.prototype.getDetailsFromTransaction = function (transaction, publicKey) {
|
|
382
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
558
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
383
559
|
return __awaiter(this, void 0, void 0, function () {
|
|
384
|
-
var tx, fallbackFeePayer,
|
|
385
|
-
|
|
386
|
-
|
|
560
|
+
var tx, fallbackFeePayer, _p, _q, _r, feePayer, fee, connection, feeInfo, e_7, ataToWalletMap_1, walletHints_1, _i, _s, ix, ataAddress, walletAddress, memoText, walletAddress, resolveAtaToWallet, _t, _u, ix, amountBytes, amount, destAta, ownerWallet, toWallet, amountBytes, amount, destAta, ownerWallet, toWallet, e_8;
|
|
561
|
+
var _this = this;
|
|
562
|
+
return __generator(this, function (_v) {
|
|
563
|
+
switch (_v.label) {
|
|
387
564
|
case 0:
|
|
388
|
-
|
|
565
|
+
_v.trys.push([0, 14, , 15]);
|
|
389
566
|
tx = solanaWeb3.Transaction.from(Buffer.from(transaction.serialized, 'hex'));
|
|
390
567
|
if (!(publicKey !== null && publicKey !== undefined)) return [3 /*break*/, 2];
|
|
391
|
-
|
|
568
|
+
_r = (_q = solanaWeb3.PublicKey).bind;
|
|
392
569
|
return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
|
|
393
570
|
case 1:
|
|
394
|
-
|
|
571
|
+
_p = new (_r.apply(_q, [void 0, _v.sent()]))();
|
|
395
572
|
return [3 /*break*/, 3];
|
|
396
573
|
case 2:
|
|
397
|
-
|
|
398
|
-
|
|
574
|
+
_p = undefined;
|
|
575
|
+
_v.label = 3;
|
|
399
576
|
case 3:
|
|
400
|
-
fallbackFeePayer =
|
|
577
|
+
fallbackFeePayer = _p;
|
|
401
578
|
feePayer = (tx === null || tx === void 0 ? void 0 : tx.feePayer) || (tx.signatures.length > 0 ? tx.signatures[0].publicKey : fallbackFeePayer);
|
|
402
579
|
fee = (0, module_kit_1.newAmount)(5000, 'Lamports');
|
|
403
|
-
|
|
580
|
+
_v.label = 4;
|
|
404
581
|
case 4:
|
|
405
|
-
|
|
582
|
+
_v.trys.push([4, 6, , 7]);
|
|
406
583
|
connection = new solanaWeb3.Connection(this.options.network.rpcUrl);
|
|
407
584
|
return [4 /*yield*/, connection.getFeeForMessage(tx.compileMessage())];
|
|
408
585
|
case 5:
|
|
409
|
-
feeInfo =
|
|
586
|
+
feeInfo = _v.sent();
|
|
410
587
|
fee = (0, module_kit_1.newAmount)((_a = feeInfo === null || feeInfo === void 0 ? void 0 : feeInfo.value) !== null && _a !== void 0 ? _a : 5000, 'Lamports');
|
|
411
588
|
return [3 /*break*/, 7];
|
|
412
589
|
case 6:
|
|
413
|
-
|
|
590
|
+
e_7 = _v.sent();
|
|
414
591
|
console.warn('[solana-spl][getDetailsFromTransaction] Network unavailable, using default fee');
|
|
415
592
|
return [3 /*break*/, 7];
|
|
416
593
|
case 7:
|
|
417
|
-
|
|
418
|
-
|
|
594
|
+
ataToWalletMap_1 = new Map();
|
|
595
|
+
walletHints_1 = [];
|
|
596
|
+
for (_i = 0, _s = tx.instructions; _i < _s.length; _i++) {
|
|
597
|
+
ix = _s[_i];
|
|
598
|
+
if (ix.programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID)) {
|
|
599
|
+
ataAddress = (_c = (_b = ix.keys[1]) === null || _b === void 0 ? void 0 : _b.pubkey) === null || _c === void 0 ? void 0 : _c.toBase58();
|
|
600
|
+
walletAddress = (_e = (_d = ix.keys[2]) === null || _d === void 0 ? void 0 : _d.pubkey) === null || _e === void 0 ? void 0 : _e.toBase58();
|
|
601
|
+
if (ataAddress && walletAddress) {
|
|
602
|
+
ataToWalletMap_1.set(ataAddress, walletAddress);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
// Parse memo instructions for wallet hints
|
|
606
|
+
if (ix.programId.equals(MEMO_PROGRAM_ID)) {
|
|
607
|
+
try {
|
|
608
|
+
memoText = Buffer.from(ix.data).toString('utf-8');
|
|
609
|
+
if (memoText.startsWith(WALLET_HINT_PREFIX)) {
|
|
610
|
+
walletAddress = memoText.slice(WALLET_HINT_PREFIX.length);
|
|
611
|
+
walletHints_1.push(walletAddress);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
catch (_w) {
|
|
615
|
+
// Ignore memo parsing errors
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
resolveAtaToWallet = function (ataAddress, hintIndex) {
|
|
620
|
+
if (hintIndex === void 0) { hintIndex = 0; }
|
|
621
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
622
|
+
var resolvedWallet, _a;
|
|
623
|
+
return __generator(this, function (_b) {
|
|
624
|
+
switch (_b.label) {
|
|
625
|
+
case 0:
|
|
626
|
+
// First check if we found it in ATA creation instructions (works offline)
|
|
627
|
+
if (ataToWalletMap_1.has(ataAddress)) {
|
|
628
|
+
return [2 /*return*/, ataToWalletMap_1.get(ataAddress)];
|
|
629
|
+
}
|
|
630
|
+
// Check if we have a wallet hint from memo (works offline)
|
|
631
|
+
if (walletHints_1.length > hintIndex && walletHints_1[hintIndex]) {
|
|
632
|
+
return [2 /*return*/, walletHints_1[hintIndex]];
|
|
633
|
+
}
|
|
634
|
+
_b.label = 1;
|
|
635
|
+
case 1:
|
|
636
|
+
_b.trys.push([1, 3, , 4]);
|
|
637
|
+
return [4 /*yield*/, this.getWalletAddressFromAta(ataAddress)];
|
|
638
|
+
case 2:
|
|
639
|
+
resolvedWallet = _b.sent();
|
|
640
|
+
if (resolvedWallet) {
|
|
641
|
+
return [2 /*return*/, resolvedWallet];
|
|
642
|
+
}
|
|
643
|
+
return [3 /*break*/, 4];
|
|
644
|
+
case 3:
|
|
645
|
+
_a = _b.sent();
|
|
646
|
+
return [3 /*break*/, 4];
|
|
647
|
+
case 4: return [2 /*return*/, ataAddress]; // Return ATA address if all resolution fails
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
});
|
|
651
|
+
};
|
|
652
|
+
_t = 0, _u = tx.instructions;
|
|
653
|
+
_v.label = 8;
|
|
419
654
|
case 8:
|
|
420
|
-
if (!(
|
|
421
|
-
ix =
|
|
422
|
-
if (!ix.programId.equals(TOKEN_PROGRAM_ID)) return [3 /*break*/,
|
|
423
|
-
if (!(ix.data.length >= 9 && ix.data[0] === 3)) return [3 /*break*/,
|
|
655
|
+
if (!(_t < _u.length)) return [3 /*break*/, 13];
|
|
656
|
+
ix = _u[_t];
|
|
657
|
+
if (!ix.programId.equals(TOKEN_PROGRAM_ID)) return [3 /*break*/, 12];
|
|
658
|
+
if (!(ix.data.length >= 9 && ix.data[0] === 3)) return [3 /*break*/, 10];
|
|
424
659
|
amountBytes = ix.data.slice(1, 9);
|
|
425
660
|
amount = this.readU64LE(amountBytes).toString();
|
|
426
|
-
destAta = ((
|
|
427
|
-
ownerWallet = ((
|
|
428
|
-
|
|
429
|
-
_r.label = 9;
|
|
661
|
+
destAta = ((_g = (_f = ix.keys[1]) === null || _f === void 0 ? void 0 : _f.pubkey) === null || _g === void 0 ? void 0 : _g.toBase58()) || '';
|
|
662
|
+
ownerWallet = ((_j = (_h = ix.keys[2]) === null || _h === void 0 ? void 0 : _h.pubkey) === null || _j === void 0 ? void 0 : _j.toBase58()) || (feePayer === null || feePayer === void 0 ? void 0 : feePayer.toBase58()) || '';
|
|
663
|
+
return [4 /*yield*/, resolveAtaToWallet(destAta)];
|
|
430
664
|
case 9:
|
|
431
|
-
|
|
432
|
-
return [
|
|
665
|
+
toWallet = _v.sent();
|
|
666
|
+
return [2 /*return*/, [{
|
|
667
|
+
from: [ownerWallet],
|
|
668
|
+
to: [toWallet],
|
|
669
|
+
amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
|
|
670
|
+
fee: fee,
|
|
671
|
+
isInbound: false,
|
|
672
|
+
network: this.options.network
|
|
673
|
+
}]];
|
|
433
674
|
case 10:
|
|
434
|
-
|
|
435
|
-
if (resolvedWallet) {
|
|
436
|
-
toWallet = resolvedWallet;
|
|
437
|
-
}
|
|
438
|
-
return [3 /*break*/, 12];
|
|
439
|
-
case 11:
|
|
440
|
-
_p = _r.sent();
|
|
441
|
-
return [3 /*break*/, 12];
|
|
442
|
-
case 12: return [2 /*return*/, [{
|
|
443
|
-
from: [ownerWallet],
|
|
444
|
-
to: [toWallet],
|
|
445
|
-
amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
|
|
446
|
-
fee: fee,
|
|
447
|
-
isInbound: false,
|
|
448
|
-
network: this.options.network
|
|
449
|
-
}]];
|
|
450
|
-
case 13:
|
|
451
|
-
if (!(ix.data.length >= 10 && ix.data[0] === 12)) return [3 /*break*/, 18];
|
|
675
|
+
if (!(ix.data.length >= 10 && ix.data[0] === 12)) return [3 /*break*/, 12];
|
|
452
676
|
amountBytes = ix.data.slice(1, 9);
|
|
453
677
|
amount = this.readU64LE(amountBytes).toString();
|
|
454
|
-
destAta = ((
|
|
455
|
-
ownerWallet = ((
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
case
|
|
468
|
-
|
|
469
|
-
return [3 /*break*/, 17];
|
|
470
|
-
case 17: return [2 /*return*/, [{
|
|
471
|
-
from: [ownerWallet],
|
|
472
|
-
to: [toWallet],
|
|
473
|
-
amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
|
|
474
|
-
fee: fee,
|
|
475
|
-
isInbound: false,
|
|
476
|
-
network: this.options.network
|
|
477
|
-
}]];
|
|
478
|
-
case 18:
|
|
479
|
-
_i++;
|
|
678
|
+
destAta = ((_l = (_k = ix.keys[2]) === null || _k === void 0 ? void 0 : _k.pubkey) === null || _l === void 0 ? void 0 : _l.toBase58()) || '';
|
|
679
|
+
ownerWallet = ((_o = (_m = ix.keys[3]) === null || _m === void 0 ? void 0 : _m.pubkey) === null || _o === void 0 ? void 0 : _o.toBase58()) || (feePayer === null || feePayer === void 0 ? void 0 : feePayer.toBase58()) || '';
|
|
680
|
+
return [4 /*yield*/, resolveAtaToWallet(destAta)];
|
|
681
|
+
case 11:
|
|
682
|
+
toWallet = _v.sent();
|
|
683
|
+
return [2 /*return*/, [{
|
|
684
|
+
from: [ownerWallet],
|
|
685
|
+
to: [toWallet],
|
|
686
|
+
amount: (0, module_kit_1.newAmount)(amount, 'blockchain'),
|
|
687
|
+
fee: fee,
|
|
688
|
+
isInbound: false,
|
|
689
|
+
network: this.options.network
|
|
690
|
+
}]];
|
|
691
|
+
case 12:
|
|
692
|
+
_t++;
|
|
480
693
|
return [3 /*break*/, 8];
|
|
481
|
-
case
|
|
694
|
+
case 13:
|
|
482
695
|
// Fallback
|
|
483
696
|
return [2 /*return*/, [{
|
|
484
697
|
from: [(feePayer === null || feePayer === void 0 ? void 0 : feePayer.toBase58()) || ''],
|
|
@@ -488,9 +701,9 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
488
701
|
isInbound: false,
|
|
489
702
|
network: this.options.network
|
|
490
703
|
}]];
|
|
491
|
-
case
|
|
492
|
-
|
|
493
|
-
console.error('[solana-spl][getDetailsFromTransaction] Failed:',
|
|
704
|
+
case 14:
|
|
705
|
+
e_8 = _v.sent();
|
|
706
|
+
console.error('[solana-spl][getDetailsFromTransaction] Failed:', e_8);
|
|
494
707
|
return [2 /*return*/, [{
|
|
495
708
|
from: [],
|
|
496
709
|
to: [],
|
|
@@ -499,7 +712,7 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
499
712
|
isInbound: false,
|
|
500
713
|
network: this.options.network
|
|
501
714
|
}]];
|
|
502
|
-
case
|
|
715
|
+
case 15: return [2 /*return*/];
|
|
503
716
|
}
|
|
504
717
|
});
|
|
505
718
|
});
|
|
@@ -641,14 +854,14 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
641
854
|
});
|
|
642
855
|
};
|
|
643
856
|
SolanaSPLTokenProtocolImpl.prototype.getTransactionsForAddress = function (address, limit, cursor) {
|
|
644
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
857
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
645
858
|
return __awaiter(this, void 0, void 0, function () {
|
|
646
|
-
var walletPubkey_2, mintPubkey_2, effectiveLimit, tokenAccounts, txs, myAtaAddresses, _i,
|
|
859
|
+
var walletPubkey_2, mintPubkey_2, effectiveLimit, tokenAccounts, txs, myAtaAddresses, _i, _u, pubkey, queryOptions_1, allSignatures, _loop_2, this_1, _v, _w, tokenAccountPubkey, uniqueSignatures, limitedSignatures, _loop_3, this_2, _x, limitedSignatures_1, sigInfo, hasNext, lastSignature, newCursor, e_9;
|
|
647
860
|
var _this = this;
|
|
648
|
-
return __generator(this, function (
|
|
649
|
-
switch (
|
|
861
|
+
return __generator(this, function (_y) {
|
|
862
|
+
switch (_y.label) {
|
|
650
863
|
case 0:
|
|
651
|
-
|
|
864
|
+
_y.trys.push([0, 10, , 11]);
|
|
652
865
|
walletPubkey_2 = new solanaWeb3.PublicKey(address);
|
|
653
866
|
mintPubkey_2 = new solanaWeb3.PublicKey(this.options.contractAddress);
|
|
654
867
|
effectiveLimit = limit || SolanaSPLTokenProtocolImpl.DEFAULT_TX_LIMIT;
|
|
@@ -656,7 +869,7 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
656
869
|
return [2 /*return*/, connection.getTokenAccountsByOwner(walletPubkey_2, { mint: mintPubkey_2 })];
|
|
657
870
|
}); }); })];
|
|
658
871
|
case 1:
|
|
659
|
-
tokenAccounts =
|
|
872
|
+
tokenAccounts = _y.sent();
|
|
660
873
|
if (tokenAccounts.value.length === 0) {
|
|
661
874
|
return [2 /*return*/, {
|
|
662
875
|
transactions: [],
|
|
@@ -665,8 +878,8 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
665
878
|
}
|
|
666
879
|
txs = [];
|
|
667
880
|
myAtaAddresses = new Set();
|
|
668
|
-
for (_i = 0,
|
|
669
|
-
pubkey =
|
|
881
|
+
for (_i = 0, _u = tokenAccounts.value; _i < _u.length; _i++) {
|
|
882
|
+
pubkey = _u[_i].pubkey;
|
|
670
883
|
myAtaAddresses.add(pubkey.toBase58());
|
|
671
884
|
}
|
|
672
885
|
queryOptions_1 = {
|
|
@@ -678,16 +891,16 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
678
891
|
}
|
|
679
892
|
allSignatures = [];
|
|
680
893
|
_loop_2 = function (tokenAccountPubkey) {
|
|
681
|
-
var signatures,
|
|
682
|
-
return __generator(this, function (
|
|
683
|
-
switch (
|
|
894
|
+
var signatures, _z, signatures_1, sig;
|
|
895
|
+
return __generator(this, function (_0) {
|
|
896
|
+
switch (_0.label) {
|
|
684
897
|
case 0: return [4 /*yield*/, this_1.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
685
898
|
return [2 /*return*/, connection.getSignaturesForAddress(tokenAccountPubkey, queryOptions_1)];
|
|
686
899
|
}); }); })];
|
|
687
900
|
case 1:
|
|
688
|
-
signatures =
|
|
689
|
-
for (
|
|
690
|
-
sig = signatures_1[
|
|
901
|
+
signatures = _0.sent();
|
|
902
|
+
for (_z = 0, signatures_1 = signatures; _z < signatures_1.length; _z++) {
|
|
903
|
+
sig = signatures_1[_z];
|
|
691
904
|
if (sig.signature) {
|
|
692
905
|
allSignatures.push({
|
|
693
906
|
signature: sig.signature,
|
|
@@ -701,17 +914,17 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
701
914
|
});
|
|
702
915
|
};
|
|
703
916
|
this_1 = this;
|
|
704
|
-
|
|
705
|
-
|
|
917
|
+
_v = 0, _w = tokenAccounts.value;
|
|
918
|
+
_y.label = 2;
|
|
706
919
|
case 2:
|
|
707
|
-
if (!(
|
|
708
|
-
tokenAccountPubkey =
|
|
920
|
+
if (!(_v < _w.length)) return [3 /*break*/, 5];
|
|
921
|
+
tokenAccountPubkey = _w[_v].pubkey;
|
|
709
922
|
return [5 /*yield**/, _loop_2(tokenAccountPubkey)];
|
|
710
923
|
case 3:
|
|
711
|
-
|
|
712
|
-
|
|
924
|
+
_y.sent();
|
|
925
|
+
_y.label = 4;
|
|
713
926
|
case 4:
|
|
714
|
-
|
|
927
|
+
_v++;
|
|
715
928
|
return [3 /*break*/, 2];
|
|
716
929
|
case 5:
|
|
717
930
|
uniqueSignatures = Array.from(new Map(allSignatures.map(function (s) { return [s.signature, s]; })).values());
|
|
@@ -719,11 +932,11 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
719
932
|
uniqueSignatures.sort(function (a, b) { return (b.blockTime || 0) - (a.blockTime || 0); });
|
|
720
933
|
limitedSignatures = uniqueSignatures.slice(0, effectiveLimit);
|
|
721
934
|
_loop_3 = function (sigInfo) {
|
|
722
|
-
var parsed, amount, fromWallet, toWallet, isInbound, instructions,
|
|
723
|
-
return __generator(this, function (
|
|
724
|
-
switch (
|
|
935
|
+
var parsed, amount, fromWallet, toWallet, isInbound, foundTransfer, ataToWalletMap_2, instructions, _1, instructions_1, ix, parsedIx, info, innerInstructions, _2, innerInstructions_1, innerGroup, _3, _4, innerIx, parsedIx, info, resolveAtaToWallet, _5, instructions_2, ix, parsedIx, info, txMint, sourceAta, destAta, authorityWallet, isSourceMine, isDestMine, resolvedFrom, resolvedTo, resolvedTo, accountKeys, accountAddresses, resolvedTo, blockTime, timestamp, e_10;
|
|
936
|
+
return __generator(this, function (_6) {
|
|
937
|
+
switch (_6.label) {
|
|
725
938
|
case 0:
|
|
726
|
-
|
|
939
|
+
_6.trys.push([0, 17, , 18]);
|
|
727
940
|
return [4 /*yield*/, this_2.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
|
|
728
941
|
return __generator(this, function (_a) {
|
|
729
942
|
return [2 /*return*/, connection.getParsedTransaction(sigInfo.signature, {
|
|
@@ -733,94 +946,181 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
733
946
|
});
|
|
734
947
|
}); })];
|
|
735
948
|
case 1:
|
|
736
|
-
parsed =
|
|
949
|
+
parsed = _6.sent();
|
|
737
950
|
if (!parsed)
|
|
738
951
|
return [2 /*return*/, "continue"];
|
|
739
952
|
amount = (0, module_kit_1.newAmount)(0, 'blockchain');
|
|
740
953
|
fromWallet = address;
|
|
741
954
|
toWallet = address;
|
|
742
955
|
isInbound = false;
|
|
956
|
+
foundTransfer = false;
|
|
957
|
+
ataToWalletMap_2 = new Map();
|
|
743
958
|
instructions = ((_b = (_a = parsed.transaction) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.instructions) || [];
|
|
744
|
-
|
|
745
|
-
|
|
959
|
+
for (_1 = 0, instructions_1 = instructions; _1 < instructions_1.length; _1++) {
|
|
960
|
+
ix = instructions_1[_1];
|
|
961
|
+
if ('parsed' in ix && ix.parsed) {
|
|
962
|
+
parsedIx = ix;
|
|
963
|
+
// Look for ATA creation by Associated Token Program
|
|
964
|
+
if (parsedIx.program === 'spl-associated-token-account' &&
|
|
965
|
+
(((_c = parsedIx.parsed) === null || _c === void 0 ? void 0 : _c.type) === 'create' || ((_d = parsedIx.parsed) === null || _d === void 0 ? void 0 : _d.type) === 'createIdempotent')) {
|
|
966
|
+
info = (_e = parsedIx.parsed) === null || _e === void 0 ? void 0 : _e.info;
|
|
967
|
+
if ((info === null || info === void 0 ? void 0 : info.account) && (info === null || info === void 0 ? void 0 : info.wallet)) {
|
|
968
|
+
// Map ATA address to wallet address
|
|
969
|
+
ataToWalletMap_2.set(info.account, info.wallet);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
innerInstructions = ((_f = parsed.meta) === null || _f === void 0 ? void 0 : _f.innerInstructions) || [];
|
|
975
|
+
for (_2 = 0, innerInstructions_1 = innerInstructions; _2 < innerInstructions_1.length; _2++) {
|
|
976
|
+
innerGroup = innerInstructions_1[_2];
|
|
977
|
+
for (_3 = 0, _4 = innerGroup.instructions || []; _3 < _4.length; _3++) {
|
|
978
|
+
innerIx = _4[_3];
|
|
979
|
+
if ('parsed' in innerIx && innerIx.parsed) {
|
|
980
|
+
parsedIx = innerIx;
|
|
981
|
+
if (parsedIx.program === 'spl-associated-token-account' &&
|
|
982
|
+
(((_g = parsedIx.parsed) === null || _g === void 0 ? void 0 : _g.type) === 'create' || ((_h = parsedIx.parsed) === null || _h === void 0 ? void 0 : _h.type) === 'createIdempotent')) {
|
|
983
|
+
info = (_j = parsedIx.parsed) === null || _j === void 0 ? void 0 : _j.info;
|
|
984
|
+
if ((info === null || info === void 0 ? void 0 : info.account) && (info === null || info === void 0 ? void 0 : info.wallet)) {
|
|
985
|
+
ataToWalletMap_2.set(info.account, info.wallet);
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
resolveAtaToWallet = function (ataAddress) { return __awaiter(_this, void 0, void 0, function () {
|
|
992
|
+
return __generator(this, function (_a) {
|
|
993
|
+
// First check local map from ATA creation instructions
|
|
994
|
+
if (ataToWalletMap_2.has(ataAddress)) {
|
|
995
|
+
return [2 /*return*/, ataToWalletMap_2.get(ataAddress)];
|
|
996
|
+
}
|
|
997
|
+
// Fall back to network query
|
|
998
|
+
return [2 /*return*/, this.getWalletAddressFromAta(ataAddress).catch(function () { return null; })];
|
|
999
|
+
});
|
|
1000
|
+
}); };
|
|
1001
|
+
_5 = 0, instructions_2 = instructions;
|
|
1002
|
+
_6.label = 2;
|
|
746
1003
|
case 2:
|
|
747
|
-
if (!(
|
|
748
|
-
ix =
|
|
749
|
-
if (!('parsed' in ix && ix.parsed)) return [3 /*break*/,
|
|
1004
|
+
if (!(_5 < instructions_2.length)) return [3 /*break*/, 16];
|
|
1005
|
+
ix = instructions_2[_5];
|
|
1006
|
+
if (!('parsed' in ix && ix.parsed)) return [3 /*break*/, 15];
|
|
750
1007
|
parsedIx = ix;
|
|
751
|
-
if (!(parsedIx.program === 'spl-token')) return [3 /*break*/,
|
|
752
|
-
info = (
|
|
753
|
-
if (!(((
|
|
754
|
-
|
|
755
|
-
|
|
1008
|
+
if (!(parsedIx.program === 'spl-token')) return [3 /*break*/, 15];
|
|
1009
|
+
info = (_k = parsedIx.parsed) === null || _k === void 0 ? void 0 : _k.info;
|
|
1010
|
+
if (!(((_l = parsedIx.parsed) === null || _l === void 0 ? void 0 : _l.type) === 'transfer' || ((_m = parsedIx.parsed) === null || _m === void 0 ? void 0 : _m.type) === 'transferChecked')) return [3 /*break*/, 15];
|
|
1011
|
+
txMint = info === null || info === void 0 ? void 0 : info.mint;
|
|
1012
|
+
if (!(txMint === this_2.options.contractAddress || !txMint)) return [3 /*break*/, 15];
|
|
1013
|
+
foundTransfer = true;
|
|
1014
|
+
amount = (0, module_kit_1.newAmount)((info === null || info === void 0 ? void 0 : info.amount) || ((_o = info === null || info === void 0 ? void 0 : info.tokenAmount) === null || _o === void 0 ? void 0 : _o.amount) || '0', 'blockchain');
|
|
756
1015
|
sourceAta = (info === null || info === void 0 ? void 0 : info.source) || '';
|
|
757
1016
|
destAta = (info === null || info === void 0 ? void 0 : info.destination) || '';
|
|
758
1017
|
authorityWallet = (info === null || info === void 0 ? void 0 : info.authority) || '';
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
if (!
|
|
762
|
-
//
|
|
763
|
-
|
|
764
|
-
//
|
|
765
|
-
toWallet = address;
|
|
1018
|
+
isSourceMine = myAtaAddresses.has(sourceAta);
|
|
1019
|
+
isDestMine = myAtaAddresses.has(destAta);
|
|
1020
|
+
if (!(isDestMine && !isSourceMine)) return [3 /*break*/, 6];
|
|
1021
|
+
// Clear inbound: destination is mine, source is not
|
|
1022
|
+
isInbound = true;
|
|
1023
|
+
toWallet = address; // Always use our wallet address for 'to'
|
|
766
1024
|
if (!authorityWallet) return [3 /*break*/, 3];
|
|
767
1025
|
fromWallet = authorityWallet;
|
|
768
1026
|
return [3 /*break*/, 5];
|
|
769
|
-
case 3: return [4 /*yield*/,
|
|
1027
|
+
case 3: return [4 /*yield*/, resolveAtaToWallet(sourceAta)];
|
|
770
1028
|
case 4:
|
|
771
|
-
resolvedFrom =
|
|
1029
|
+
resolvedFrom = _6.sent();
|
|
772
1030
|
fromWallet = resolvedFrom || sourceAta;
|
|
773
|
-
|
|
774
|
-
case 5: return [3 /*break*/,
|
|
1031
|
+
_6.label = 5;
|
|
1032
|
+
case 5: return [3 /*break*/, 14];
|
|
775
1033
|
case 6:
|
|
776
|
-
|
|
777
|
-
//
|
|
778
|
-
|
|
779
|
-
fromWallet =
|
|
780
|
-
return [4 /*yield*/,
|
|
1034
|
+
if (!(isSourceMine && !isDestMine)) return [3 /*break*/, 8];
|
|
1035
|
+
// Clear outbound: source is mine, destination is not
|
|
1036
|
+
isInbound = false;
|
|
1037
|
+
fromWallet = address; // Always use our wallet address for 'from'
|
|
1038
|
+
return [4 /*yield*/, resolveAtaToWallet(destAta)];
|
|
781
1039
|
case 7:
|
|
782
|
-
resolvedTo =
|
|
1040
|
+
resolvedTo = _6.sent();
|
|
783
1041
|
toWallet = resolvedTo || destAta;
|
|
784
|
-
|
|
785
|
-
case 8:
|
|
1042
|
+
return [3 /*break*/, 14];
|
|
1043
|
+
case 8:
|
|
1044
|
+
if (!(isSourceMine && isDestMine)) return [3 /*break*/, 9];
|
|
1045
|
+
// Internal transfer (both are mine) - treat as outbound
|
|
1046
|
+
isInbound = false;
|
|
1047
|
+
fromWallet = address;
|
|
1048
|
+
toWallet = address;
|
|
1049
|
+
return [3 /*break*/, 14];
|
|
786
1050
|
case 9:
|
|
787
|
-
|
|
788
|
-
|
|
1051
|
+
if (!(authorityWallet === address)) return [3 /*break*/, 11];
|
|
1052
|
+
// User is the signer, so this is outbound
|
|
1053
|
+
isInbound = false;
|
|
1054
|
+
fromWallet = address;
|
|
1055
|
+
return [4 /*yield*/, resolveAtaToWallet(destAta)];
|
|
789
1056
|
case 10:
|
|
790
|
-
|
|
1057
|
+
resolvedTo = _6.sent();
|
|
1058
|
+
toWallet = resolvedTo || destAta;
|
|
1059
|
+
return [3 /*break*/, 14];
|
|
1060
|
+
case 11:
|
|
1061
|
+
accountKeys = ((_q = (_p = parsed.transaction) === null || _p === void 0 ? void 0 : _p.message) === null || _q === void 0 ? void 0 : _q.accountKeys) || [];
|
|
1062
|
+
accountAddresses = accountKeys.map(function (k) { var _a; return typeof k === 'string' ? k : (((_a = k.pubkey) === null || _a === void 0 ? void 0 : _a.toString()) || k.toString()); });
|
|
1063
|
+
if (!accountAddresses.includes(address)) return [3 /*break*/, 13];
|
|
1064
|
+
// Our address is involved somewhere
|
|
1065
|
+
// Default to treating as relevant, use available info
|
|
1066
|
+
if (authorityWallet) {
|
|
1067
|
+
fromWallet = authorityWallet;
|
|
1068
|
+
}
|
|
1069
|
+
return [4 /*yield*/, resolveAtaToWallet(destAta)];
|
|
1070
|
+
case 12:
|
|
1071
|
+
resolvedTo = _6.sent();
|
|
1072
|
+
toWallet = resolvedTo || destAta;
|
|
1073
|
+
// Determine direction by checking if we're source or dest
|
|
1074
|
+
isInbound = toWallet === address;
|
|
1075
|
+
return [3 /*break*/, 14];
|
|
1076
|
+
case 13:
|
|
1077
|
+
// Transaction doesn't seem to involve our wallet directly
|
|
1078
|
+
// Skip this transaction
|
|
1079
|
+
foundTransfer = false;
|
|
1080
|
+
_6.label = 14;
|
|
1081
|
+
case 14: return [3 /*break*/, 16];
|
|
1082
|
+
case 15:
|
|
1083
|
+
_5++;
|
|
1084
|
+
return [3 /*break*/, 2];
|
|
1085
|
+
case 16:
|
|
1086
|
+
// Skip transactions that don't have a valid transfer for this token
|
|
1087
|
+
if (!foundTransfer) {
|
|
1088
|
+
return [2 /*return*/, "continue"];
|
|
1089
|
+
}
|
|
1090
|
+
blockTime = (_r = sigInfo.blockTime) !== null && _r !== void 0 ? _r : parsed.blockTime;
|
|
791
1091
|
timestamp = blockTime ? blockTime : Math.floor(Date.now() / 1000);
|
|
792
1092
|
txs.push({
|
|
793
1093
|
hash: sigInfo.signature,
|
|
794
1094
|
timestamp: timestamp,
|
|
795
1095
|
status: sigInfo.confirmationStatus || 'processed',
|
|
796
1096
|
amount: amount,
|
|
797
|
-
fee: (0, module_kit_1.newAmount)((
|
|
1097
|
+
fee: (0, module_kit_1.newAmount)((_t = (_s = parsed.meta) === null || _s === void 0 ? void 0 : _s.fee) !== null && _t !== void 0 ? _t : 0, 'Lamports'),
|
|
798
1098
|
from: [fromWallet],
|
|
799
1099
|
to: [toWallet],
|
|
800
1100
|
isInbound: isInbound,
|
|
801
1101
|
network: this_2.options.network
|
|
802
1102
|
});
|
|
803
|
-
return [3 /*break*/,
|
|
804
|
-
case
|
|
805
|
-
|
|
1103
|
+
return [3 /*break*/, 18];
|
|
1104
|
+
case 17:
|
|
1105
|
+
e_10 = _6.sent();
|
|
806
1106
|
console.warn('[solana-spl][getTransactionsForAddress] Failed to parse tx:', sigInfo.signature);
|
|
807
|
-
return [3 /*break*/,
|
|
808
|
-
case
|
|
1107
|
+
return [3 /*break*/, 18];
|
|
1108
|
+
case 18: return [2 /*return*/];
|
|
809
1109
|
}
|
|
810
1110
|
});
|
|
811
1111
|
};
|
|
812
1112
|
this_2 = this;
|
|
813
|
-
|
|
814
|
-
|
|
1113
|
+
_x = 0, limitedSignatures_1 = limitedSignatures;
|
|
1114
|
+
_y.label = 6;
|
|
815
1115
|
case 6:
|
|
816
|
-
if (!(
|
|
817
|
-
sigInfo = limitedSignatures_1[
|
|
1116
|
+
if (!(_x < limitedSignatures_1.length)) return [3 /*break*/, 9];
|
|
1117
|
+
sigInfo = limitedSignatures_1[_x];
|
|
818
1118
|
return [5 /*yield**/, _loop_3(sigInfo)];
|
|
819
1119
|
case 7:
|
|
820
|
-
|
|
821
|
-
|
|
1120
|
+
_y.sent();
|
|
1121
|
+
_y.label = 8;
|
|
822
1122
|
case 8:
|
|
823
|
-
|
|
1123
|
+
_x++;
|
|
824
1124
|
return [3 /*break*/, 6];
|
|
825
1125
|
case 9:
|
|
826
1126
|
hasNext = limitedSignatures.length === effectiveLimit;
|
|
@@ -834,8 +1134,8 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
834
1134
|
cursor: newCursor
|
|
835
1135
|
}];
|
|
836
1136
|
case 10:
|
|
837
|
-
|
|
838
|
-
console.error('[solana-spl][getTransactionsForAddress] Failed:',
|
|
1137
|
+
e_9 = _y.sent();
|
|
1138
|
+
console.error('[solana-spl][getTransactionsForAddress] Failed:', e_9);
|
|
839
1139
|
return [2 /*return*/, {
|
|
840
1140
|
transactions: [],
|
|
841
1141
|
cursor: { hasNext: false }
|
|
@@ -901,20 +1201,32 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
901
1201
|
};
|
|
902
1202
|
SolanaSPLTokenProtocolImpl.prototype.getTransactionFeeWithPublicKey = function (publicKey, details, configuration) {
|
|
903
1203
|
return __awaiter(this, void 0, void 0, function () {
|
|
904
|
-
var
|
|
1204
|
+
var fromAddress, fromPubkey, mintPubkey, rentExemption, totalAtaCreationCost, ataCreationCount, ataCheckFailed, simulationTx, sourceAta, _loop_4, this_3, _i, details_1, detail, e_11, baseFee, feeResult, e_12, computeUnits, simulation, e_13, priorityFees, baseOnly, baseWithAta, lowFee, mediumFee, highFee, potentialAtaCost;
|
|
905
1205
|
var _this = this;
|
|
906
1206
|
return __generator(this, function (_a) {
|
|
907
1207
|
switch (_a.label) {
|
|
908
|
-
case 0:
|
|
909
|
-
baseFee = 5000 // lamports
|
|
910
|
-
;
|
|
911
|
-
totalAtaCreationCost = 0;
|
|
912
|
-
_a.label = 1;
|
|
1208
|
+
case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
|
|
913
1209
|
case 1:
|
|
914
|
-
_a.
|
|
1210
|
+
fromAddress = _a.sent();
|
|
1211
|
+
fromPubkey = new solanaWeb3.PublicKey(fromAddress);
|
|
915
1212
|
mintPubkey = new solanaWeb3.PublicKey(this.options.contractAddress);
|
|
1213
|
+
return [4 /*yield*/, this.getTokenAccountRentExemption()
|
|
1214
|
+
// Check if any destination requires ATA creation and build transaction for simulation
|
|
1215
|
+
];
|
|
1216
|
+
case 2:
|
|
1217
|
+
rentExemption = _a.sent();
|
|
1218
|
+
totalAtaCreationCost = 0;
|
|
1219
|
+
ataCreationCount = 0;
|
|
1220
|
+
ataCheckFailed = false;
|
|
1221
|
+
simulationTx = new solanaWeb3.Transaction();
|
|
1222
|
+
_a.label = 3;
|
|
1223
|
+
case 3:
|
|
1224
|
+
_a.trys.push([3, 9, , 10]);
|
|
1225
|
+
return [4 /*yield*/, this.getAssociatedTokenAddress(fromAddress)];
|
|
1226
|
+
case 4:
|
|
1227
|
+
sourceAta = _a.sent();
|
|
916
1228
|
_loop_4 = function (detail) {
|
|
917
|
-
var toPubkey, destAta, destAtaInfo;
|
|
1229
|
+
var toPubkey, destAta, destAtaExists, ataQuerySuccess, destAtaInfo, e_14, amount;
|
|
918
1230
|
return __generator(this, function (_b) {
|
|
919
1231
|
switch (_b.label) {
|
|
920
1232
|
case 0:
|
|
@@ -925,48 +1237,136 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
925
1237
|
mintPubkey.toBuffer()
|
|
926
1238
|
], ASSOCIATED_TOKEN_PROGRAM_ID)
|
|
927
1239
|
// Check if destination ATA exists
|
|
1240
|
+
// Important: distinguish between "ATA doesn't exist" (null result) and "query failed" (exception)
|
|
928
1241
|
];
|
|
929
1242
|
case 1:
|
|
930
1243
|
destAta = (_b.sent())[0];
|
|
1244
|
+
destAtaExists = false;
|
|
1245
|
+
ataQuerySuccess = false;
|
|
1246
|
+
_b.label = 2;
|
|
1247
|
+
case 2:
|
|
1248
|
+
_b.trys.push([2, 4, , 5]);
|
|
931
1249
|
return [4 /*yield*/, this_3.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
932
1250
|
return [2 /*return*/, connection.getAccountInfo(destAta)];
|
|
933
|
-
}); }); })
|
|
934
|
-
case
|
|
1251
|
+
}); }); })];
|
|
1252
|
+
case 3:
|
|
935
1253
|
destAtaInfo = _b.sent();
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
1254
|
+
ataQuerySuccess = true;
|
|
1255
|
+
destAtaExists = destAtaInfo !== null;
|
|
1256
|
+
return [3 /*break*/, 5];
|
|
1257
|
+
case 4:
|
|
1258
|
+
e_14 = _b.sent();
|
|
1259
|
+
console.warn('[solana-spl][getTransactionFeeWithPublicKey] ATA query failed for:', detail.to);
|
|
1260
|
+
ataCheckFailed = true;
|
|
1261
|
+
return [3 /*break*/, 5];
|
|
1262
|
+
case 5:
|
|
1263
|
+
if (ataQuerySuccess && !destAtaExists) {
|
|
1264
|
+
// ATA confirmed to not exist, need to create it
|
|
1265
|
+
totalAtaCreationCost += rentExemption;
|
|
1266
|
+
ataCreationCount++;
|
|
1267
|
+
// Add ATA creation instruction for simulation
|
|
1268
|
+
simulationTx.add(this_3.createAssociatedTokenAccountInstruction(fromPubkey, destAta, toPubkey, mintPubkey));
|
|
939
1269
|
}
|
|
1270
|
+
amount = new bignumber_1.BigNumber((0, module_kit_1.newAmount)(detail.amount).blockchain(this_3.units).value);
|
|
1271
|
+
simulationTx.add(this_3.createTransferInstruction(sourceAta, destAta, fromPubkey, BigInt(amount.toFixed(0))));
|
|
940
1272
|
return [2 /*return*/];
|
|
941
1273
|
}
|
|
942
1274
|
});
|
|
943
1275
|
};
|
|
944
1276
|
this_3 = this;
|
|
945
1277
|
_i = 0, details_1 = details;
|
|
946
|
-
_a.label =
|
|
947
|
-
case
|
|
948
|
-
if (!(_i < details_1.length)) return [3 /*break*/,
|
|
1278
|
+
_a.label = 5;
|
|
1279
|
+
case 5:
|
|
1280
|
+
if (!(_i < details_1.length)) return [3 /*break*/, 8];
|
|
949
1281
|
detail = details_1[_i];
|
|
950
1282
|
return [5 /*yield**/, _loop_4(detail)];
|
|
951
|
-
case 3:
|
|
952
|
-
_a.sent();
|
|
953
|
-
_a.label = 4;
|
|
954
|
-
case 4:
|
|
955
|
-
_i++;
|
|
956
|
-
return [3 /*break*/, 2];
|
|
957
|
-
case 5: return [3 /*break*/, 7];
|
|
958
1283
|
case 6:
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
// Assume all destinations need ATA creation (worst case)
|
|
962
|
-
totalAtaCreationCost = details.length * TOKEN_ACCOUNT_RENT_EXEMPTION_LAMPORTS;
|
|
963
|
-
return [3 /*break*/, 7];
|
|
1284
|
+
_a.sent();
|
|
1285
|
+
_a.label = 7;
|
|
964
1286
|
case 7:
|
|
965
|
-
|
|
1287
|
+
_i++;
|
|
1288
|
+
return [3 /*break*/, 5];
|
|
1289
|
+
case 8: return [3 /*break*/, 10];
|
|
1290
|
+
case 9:
|
|
1291
|
+
e_11 = _a.sent();
|
|
1292
|
+
console.warn('[solana-spl][getTransactionFeeWithPublicKey] Failed to build simulation transaction:', e_11);
|
|
1293
|
+
ataCheckFailed = true;
|
|
1294
|
+
return [3 /*break*/, 10];
|
|
1295
|
+
case 10:
|
|
1296
|
+
simulationTx.feePayer = fromPubkey;
|
|
1297
|
+
baseFee = DEFAULT_BASE_FEE_LAMPORTS;
|
|
1298
|
+
_a.label = 11;
|
|
1299
|
+
case 11:
|
|
1300
|
+
_a.trys.push([11, 13, , 14]);
|
|
1301
|
+
return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
|
|
1302
|
+
var blockhash, feeForMessage;
|
|
1303
|
+
return __generator(this, function (_a) {
|
|
1304
|
+
switch (_a.label) {
|
|
1305
|
+
case 0: return [4 /*yield*/, connection.getLatestBlockhash()];
|
|
1306
|
+
case 1:
|
|
1307
|
+
blockhash = (_a.sent()).blockhash;
|
|
1308
|
+
simulationTx.recentBlockhash = blockhash;
|
|
1309
|
+
return [4 /*yield*/, connection.getFeeForMessage(simulationTx.compileMessage())];
|
|
1310
|
+
case 2:
|
|
1311
|
+
feeForMessage = _a.sent();
|
|
1312
|
+
return [2 /*return*/, feeForMessage === null || feeForMessage === void 0 ? void 0 : feeForMessage.value];
|
|
1313
|
+
}
|
|
1314
|
+
});
|
|
1315
|
+
}); })];
|
|
1316
|
+
case 12:
|
|
1317
|
+
feeResult = _a.sent();
|
|
1318
|
+
if (feeResult && feeResult > 0) {
|
|
1319
|
+
baseFee = feeResult;
|
|
1320
|
+
}
|
|
1321
|
+
return [3 /*break*/, 14];
|
|
1322
|
+
case 13:
|
|
1323
|
+
e_12 = _a.sent();
|
|
1324
|
+
console.warn('[solana-spl][getTransactionFeeWithPublicKey] Failed to get base fee:', e_12);
|
|
1325
|
+
return [3 /*break*/, 14];
|
|
1326
|
+
case 14:
|
|
1327
|
+
computeUnits = (details.length * DEFAULT_SPL_TRANSFER_CU) + (ataCreationCount * DEFAULT_ATA_CREATE_CU);
|
|
1328
|
+
_a.label = 15;
|
|
1329
|
+
case 15:
|
|
1330
|
+
_a.trys.push([15, 17, , 18]);
|
|
1331
|
+
return [4 /*yield*/, this.simulateTransaction(simulationTx)];
|
|
1332
|
+
case 16:
|
|
1333
|
+
simulation = _a.sent();
|
|
1334
|
+
if (simulation.success && simulation.unitsConsumed > 0) {
|
|
1335
|
+
computeUnits = simulation.unitsConsumed;
|
|
1336
|
+
// Add 10% buffer to simulated CU for safety
|
|
1337
|
+
computeUnits = Math.ceil(computeUnits * 1.1);
|
|
1338
|
+
}
|
|
1339
|
+
return [3 /*break*/, 18];
|
|
1340
|
+
case 17:
|
|
1341
|
+
e_13 = _a.sent();
|
|
1342
|
+
console.warn('[solana-spl][getTransactionFeeWithPublicKey] Simulation failed, using default CU:', e_13);
|
|
1343
|
+
return [3 /*break*/, 18];
|
|
1344
|
+
case 18: return [4 /*yield*/, this.getRecentPriorityFees()
|
|
1345
|
+
// Calculate total fees for each tier
|
|
1346
|
+
// If ATA check failed, use conservative estimates:
|
|
1347
|
+
// - low: assume ATA exists (optimistic, just base fee)
|
|
1348
|
+
// - medium/high: include potential ATA creation cost
|
|
1349
|
+
];
|
|
1350
|
+
case 19:
|
|
1351
|
+
priorityFees = _a.sent();
|
|
1352
|
+
baseOnly = baseFee;
|
|
1353
|
+
baseWithAta = baseFee + totalAtaCreationCost;
|
|
1354
|
+
if (ataCheckFailed) {
|
|
1355
|
+
potentialAtaCost = details.length * rentExemption;
|
|
1356
|
+
lowFee = baseOnly;
|
|
1357
|
+
mediumFee = this.calculateTotalFee(baseOnly, priorityFees.medium, computeUnits);
|
|
1358
|
+
highFee = this.calculateTotalFee(baseOnly + potentialAtaCost, priorityFees.high, computeUnits);
|
|
1359
|
+
}
|
|
1360
|
+
else {
|
|
1361
|
+
// ATA status is known - calculate exact fees
|
|
1362
|
+
lowFee = baseWithAta;
|
|
1363
|
+
mediumFee = this.calculateTotalFee(baseWithAta, priorityFees.medium, computeUnits);
|
|
1364
|
+
highFee = this.calculateTotalFee(baseWithAta, priorityFees.high, computeUnits);
|
|
1365
|
+
}
|
|
966
1366
|
return [2 /*return*/, {
|
|
967
|
-
low: (0, module_kit_1.newAmount)(
|
|
968
|
-
medium: (0, module_kit_1.newAmount)(
|
|
969
|
-
high: (0, module_kit_1.newAmount)(
|
|
1367
|
+
low: (0, module_kit_1.newAmount)(lowFee, 'Lamports'),
|
|
1368
|
+
medium: (0, module_kit_1.newAmount)(mediumFee, 'Lamports'),
|
|
1369
|
+
high: (0, module_kit_1.newAmount)(highFee, 'Lamports')
|
|
970
1370
|
}];
|
|
971
1371
|
}
|
|
972
1372
|
});
|
|
@@ -985,7 +1385,7 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
985
1385
|
mintPubkey = new solanaWeb3.PublicKey(this.options.contractAddress);
|
|
986
1386
|
transaction = new solanaWeb3.Transaction();
|
|
987
1387
|
_loop_5 = function (detail) {
|
|
988
|
-
var toPubkey, sourceAta, destAta, destAtaInfo, createAtaIx, amount, transferIx;
|
|
1388
|
+
var toPubkey, sourceAta, destAta, destAtaInfo, needsWalletHint, createAtaIx, memoIx, amount, transferIx;
|
|
989
1389
|
return __generator(this, function (_b) {
|
|
990
1390
|
switch (_b.label) {
|
|
991
1391
|
case 0:
|
|
@@ -1009,13 +1409,21 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
1009
1409
|
}); }); })];
|
|
1010
1410
|
case 3:
|
|
1011
1411
|
destAtaInfo = _b.sent();
|
|
1412
|
+
needsWalletHint = true;
|
|
1012
1413
|
if (!destAtaInfo) {
|
|
1013
1414
|
createAtaIx = this_4.createAssociatedTokenAccountInstruction(fromPubkey, // payer
|
|
1014
1415
|
destAta, // ata
|
|
1015
|
-
toPubkey, // owner
|
|
1416
|
+
toPubkey, // owner (wallet address)
|
|
1016
1417
|
mintPubkey // mint
|
|
1017
1418
|
);
|
|
1018
1419
|
transaction.add(createAtaIx);
|
|
1420
|
+
needsWalletHint = false;
|
|
1421
|
+
}
|
|
1422
|
+
// If ATA already exists, add a memo instruction with the wallet address hint
|
|
1423
|
+
// This allows Vault to resolve the destination wallet address offline
|
|
1424
|
+
if (needsWalletHint) {
|
|
1425
|
+
memoIx = this_4.createMemoInstruction("".concat(WALLET_HINT_PREFIX).concat(detail.to));
|
|
1426
|
+
transaction.add(memoIx);
|
|
1019
1427
|
}
|
|
1020
1428
|
amount = new bignumber_1.BigNumber((0, module_kit_1.newAmount)(detail.amount).blockchain(this_4.units).value);
|
|
1021
1429
|
transferIx = this_4.createTransferInstruction(sourceAta, destAta, fromPubkey, BigInt(amount.toFixed(0)));
|
|
@@ -1077,6 +1485,14 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
1077
1485
|
data: Buffer.alloc(0)
|
|
1078
1486
|
});
|
|
1079
1487
|
};
|
|
1488
|
+
// Helper: Create Memo instruction for wallet address hints
|
|
1489
|
+
SolanaSPLTokenProtocolImpl.prototype.createMemoInstruction = function (memo) {
|
|
1490
|
+
return new solanaWeb3.TransactionInstruction({
|
|
1491
|
+
keys: [],
|
|
1492
|
+
programId: MEMO_PROGRAM_ID,
|
|
1493
|
+
data: Buffer.from(memo, 'utf-8')
|
|
1494
|
+
});
|
|
1495
|
+
};
|
|
1080
1496
|
// Helper: Create SPL Token transfer instruction
|
|
1081
1497
|
SolanaSPLTokenProtocolImpl.prototype.createTransferInstruction = function (source, destination, owner, amount) {
|
|
1082
1498
|
var data = Buffer.alloc(9);
|
|
@@ -1116,6 +1532,7 @@ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
|
|
|
1116
1532
|
SolanaSPLTokenProtocolImpl.FALLBACK_RPC_URLS = [
|
|
1117
1533
|
'https://solana.drpc.org'
|
|
1118
1534
|
];
|
|
1535
|
+
SolanaSPLTokenProtocolImpl.PRIORITY_FEE_CACHE_TTL = 30000; // 30 seconds cache
|
|
1119
1536
|
// Default number of transactions to fetch per page
|
|
1120
1537
|
SolanaSPLTokenProtocolImpl.DEFAULT_TX_LIMIT = 10;
|
|
1121
1538
|
return SolanaSPLTokenProtocolImpl;
|