@wallfree-dev/solana 0.13.43-beta.2 → 0.13.43-beta.6

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.
@@ -0,0 +1,1129 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __generator = (this && this.__generator) || function (thisArg, body) {
35
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
36
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
37
+ function verb(n) { return function (v) { return step([n, v]); }; }
38
+ function step(op) {
39
+ if (f) throw new TypeError("Generator is already executing.");
40
+ while (_) try {
41
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
42
+ if (y = 0, t) op = [op[0] & 2, t.value];
43
+ switch (op[0]) {
44
+ case 0: case 1: t = op; break;
45
+ case 4: _.label++; return { value: op[1], done: false };
46
+ case 5: _.label++; y = op[1]; op = [0]; continue;
47
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
48
+ default:
49
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
50
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
51
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
52
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
53
+ if (t[2]) _.ops.pop();
54
+ _.trys.pop(); continue;
55
+ }
56
+ op = body.call(thisArg, _);
57
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
58
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
59
+ }
60
+ };
61
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
62
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
63
+ if (ar || !(i in from)) {
64
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
65
+ ar[i] = from[i];
66
+ }
67
+ }
68
+ return to.concat(ar || Array.prototype.slice.call(from));
69
+ };
70
+ Object.defineProperty(exports, "__esModule", { value: true });
71
+ exports.createSolanaSPLTokenProtocol = exports.SolanaSPLTokenProtocolImpl = void 0;
72
+ var module_kit_1 = require("@wallfree-dev/module-kit");
73
+ var solanaWeb3 = __importStar(require("@solana/web3.js"));
74
+ // @ts-ignore
75
+ var bs58 = __importStar(require("bs58"));
76
+ var nacl = __importStar(require("tweetnacl"));
77
+ var bignumber_1 = require("@wallfree-dev/coinlib-core/dependencies/src/bignumber.js-9.0.0/bignumber");
78
+ var SolanaProtocol_1 = require("./SolanaProtocol");
79
+ // SPL Token Program ID
80
+ var TOKEN_PROGRAM_ID = new solanaWeb3.PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
81
+ var ASSOCIATED_TOKEN_PROGRAM_ID = new solanaWeb3.PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
82
+ // Rent exemption for a token account (165 bytes) - approximately 0.00203928 SOL
83
+ // This is the minimum balance required to keep a token account alive
84
+ var TOKEN_ACCOUNT_RENT_EXEMPTION_LAMPORTS = 2039280;
85
+ // Implementation
86
+ var SolanaSPLTokenProtocolImpl = /** @class */ (function () {
87
+ function SolanaSPLTokenProtocolImpl(options) {
88
+ this.options = options;
89
+ this.units = options.units;
90
+ this.mainUnit = options.mainUnit;
91
+ }
92
+ // Helper for RPC calls with fallback to backup endpoints
93
+ SolanaSPLTokenProtocolImpl.prototype.withFallback = function (fn, maxRetries) {
94
+ var _a, _b, _c, _d, _e;
95
+ if (maxRetries === void 0) { maxRetries = 2; }
96
+ return __awaiter(this, void 0, void 0, function () {
97
+ var allUrls, lastError, _i, allUrls_1, rpcUrl, _loop_1, retry, state_1;
98
+ return __generator(this, function (_f) {
99
+ switch (_f.label) {
100
+ case 0:
101
+ allUrls = __spreadArray([this.options.network.rpcUrl], SolanaSPLTokenProtocolImpl.FALLBACK_RPC_URLS, true);
102
+ _i = 0, allUrls_1 = allUrls;
103
+ _f.label = 1;
104
+ case 1:
105
+ if (!(_i < allUrls_1.length)) return [3 /*break*/, 6];
106
+ rpcUrl = allUrls_1[_i];
107
+ _loop_1 = function (retry) {
108
+ var connection, _g, e_1, isTemporaryError;
109
+ return __generator(this, function (_h) {
110
+ switch (_h.label) {
111
+ case 0:
112
+ _h.trys.push([0, 2, , 5]);
113
+ connection = new solanaWeb3.Connection(rpcUrl);
114
+ _g = {};
115
+ return [4 /*yield*/, fn(connection)];
116
+ case 1: return [2 /*return*/, (_g.value = _h.sent(), _g)];
117
+ case 2:
118
+ e_1 = _h.sent();
119
+ lastError = e_1;
120
+ isTemporaryError = ((_a = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _a === void 0 ? void 0 : _a.includes('500')) ||
121
+ ((_b = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _b === void 0 ? void 0 : _b.includes('502')) ||
122
+ ((_c = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _c === void 0 ? void 0 : _c.includes('503')) ||
123
+ ((_d = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _d === void 0 ? void 0 : _d.includes('code":19')) ||
124
+ ((_e = e_1 === null || e_1 === void 0 ? void 0 : e_1.message) === null || _e === void 0 ? void 0 : _e.includes('Temporary'));
125
+ if (!isTemporaryError) {
126
+ return [2 /*return*/, "break"];
127
+ }
128
+ if (!(retry < maxRetries - 1)) return [3 /*break*/, 4];
129
+ return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 1000 * (retry + 1)); })];
130
+ case 3:
131
+ _h.sent();
132
+ _h.label = 4;
133
+ case 4: return [3 /*break*/, 5];
134
+ case 5: return [2 /*return*/];
135
+ }
136
+ });
137
+ };
138
+ retry = 0;
139
+ _f.label = 2;
140
+ case 2:
141
+ if (!(retry < maxRetries)) return [3 /*break*/, 5];
142
+ return [5 /*yield**/, _loop_1(retry)];
143
+ case 3:
144
+ state_1 = _f.sent();
145
+ if (typeof state_1 === "object")
146
+ return [2 /*return*/, state_1.value];
147
+ if (state_1 === "break")
148
+ return [3 /*break*/, 5];
149
+ _f.label = 4;
150
+ case 4:
151
+ retry++;
152
+ return [3 /*break*/, 2];
153
+ case 5:
154
+ _i++;
155
+ return [3 /*break*/, 1];
156
+ case 6: throw lastError;
157
+ }
158
+ });
159
+ });
160
+ };
161
+ // SubProtocol methods
162
+ SolanaSPLTokenProtocolImpl.prototype.getType = function () {
163
+ return __awaiter(this, void 0, void 0, function () {
164
+ return __generator(this, function (_a) {
165
+ return [2 /*return*/, 'token'];
166
+ });
167
+ });
168
+ };
169
+ SolanaSPLTokenProtocolImpl.prototype.mainProtocol = function () {
170
+ return __awaiter(this, void 0, void 0, function () {
171
+ return __generator(this, function (_a) {
172
+ return [2 /*return*/, this.options.mainIdentifier];
173
+ });
174
+ });
175
+ };
176
+ SolanaSPLTokenProtocolImpl.prototype.getContractAddress = function () {
177
+ return __awaiter(this, void 0, void 0, function () {
178
+ return __generator(this, function (_a) {
179
+ return [2 /*return*/, this.options.contractAddress];
180
+ });
181
+ });
182
+ };
183
+ SolanaSPLTokenProtocolImpl.prototype.getMetadata = function () {
184
+ return __awaiter(this, void 0, void 0, function () {
185
+ return __generator(this, function (_a) {
186
+ return [2 /*return*/, {
187
+ identifier: this.options.identifier,
188
+ name: this.options.name,
189
+ units: this.units,
190
+ mainUnit: this.mainUnit,
191
+ fee: {
192
+ defaults: {
193
+ low: (0, module_kit_1.newAmount)(0.000005, 'SOL'),
194
+ medium: (0, module_kit_1.newAmount)(0.000005, 'SOL'),
195
+ high: (0, module_kit_1.newAmount)(0.000005, 'SOL')
196
+ },
197
+ units: SolanaProtocol_1.SOLANA_UNITS_METADATA,
198
+ mainUnit: 'SOL'
199
+ },
200
+ account: {
201
+ standardDerivationPath: "m/44'/501'/0'/0'",
202
+ address: {
203
+ isCaseSensitive: true,
204
+ placeholder: '...',
205
+ regex: '^[1-9A-HJ-NP-Za-km-z]{32,44}$'
206
+ }
207
+ }
208
+ }];
209
+ });
210
+ });
211
+ };
212
+ SolanaSPLTokenProtocolImpl.prototype.getPublicKeyBuffer = function (publicKey) {
213
+ if (publicKey.format === 'hex') {
214
+ return Buffer.from(publicKey.value, 'hex');
215
+ }
216
+ else if (publicKey.format === 'encoded') {
217
+ return bs58.decode(publicKey.value);
218
+ }
219
+ return Buffer.from(publicKey.value, 'hex');
220
+ };
221
+ SolanaSPLTokenProtocolImpl.prototype.getAddressFromPublicKey = function (publicKey) {
222
+ return __awaiter(this, void 0, void 0, function () {
223
+ var pubKeyBytes;
224
+ return __generator(this, function (_a) {
225
+ pubKeyBytes = this.getPublicKeyBuffer(publicKey);
226
+ return [2 /*return*/, bs58.encode(pubKeyBytes)];
227
+ });
228
+ });
229
+ };
230
+ SolanaSPLTokenProtocolImpl.prototype.getAddressesFromPublicKey = function (publicKey) {
231
+ return __awaiter(this, void 0, void 0, function () {
232
+ var address;
233
+ return __generator(this, function (_a) {
234
+ switch (_a.label) {
235
+ case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
236
+ case 1:
237
+ address = _a.sent();
238
+ return [2 /*return*/, [{
239
+ address: address,
240
+ cursor: { hasNext: false }
241
+ }]];
242
+ }
243
+ });
244
+ });
245
+ };
246
+ SolanaSPLTokenProtocolImpl.prototype.validateAddress = function (address) {
247
+ return __awaiter(this, void 0, void 0, function () {
248
+ var pubkey;
249
+ return __generator(this, function (_a) {
250
+ try {
251
+ pubkey = new solanaWeb3.PublicKey(address);
252
+ // Additional check: ensure it's on the ed25519 curve (valid public key)
253
+ // Note: Some special addresses like program IDs may not be on curve, so we accept both
254
+ return [2 /*return*/, pubkey.toBytes().length === 32];
255
+ }
256
+ catch (_b) {
257
+ return [2 /*return*/, false];
258
+ }
259
+ return [2 /*return*/];
260
+ });
261
+ });
262
+ };
263
+ // Get Associated Token Address for a wallet
264
+ SolanaSPLTokenProtocolImpl.prototype.getAssociatedTokenAddress = function (walletAddress) {
265
+ return __awaiter(this, void 0, void 0, function () {
266
+ var walletPubkey, mintPubkey, ata;
267
+ return __generator(this, function (_a) {
268
+ switch (_a.label) {
269
+ case 0:
270
+ walletPubkey = new solanaWeb3.PublicKey(walletAddress);
271
+ mintPubkey = new solanaWeb3.PublicKey(this.options.contractAddress);
272
+ return [4 /*yield*/, solanaWeb3.PublicKey.findProgramAddress([
273
+ walletPubkey.toBuffer(),
274
+ TOKEN_PROGRAM_ID.toBuffer(),
275
+ mintPubkey.toBuffer()
276
+ ], ASSOCIATED_TOKEN_PROGRAM_ID)];
277
+ case 1:
278
+ ata = (_a.sent())[0];
279
+ return [2 /*return*/, ata];
280
+ }
281
+ });
282
+ });
283
+ };
284
+ // Get wallet address from ATA by fetching account info
285
+ // Returns the owner (wallet) address of a token account
286
+ SolanaSPLTokenProtocolImpl.prototype.getWalletAddressFromAta = function (ataAddress) {
287
+ return __awaiter(this, void 0, void 0, function () {
288
+ var ataPubkey_1, accountInfo, ownerBytes, ownerPubkey, e_2;
289
+ var _this = this;
290
+ return __generator(this, function (_a) {
291
+ switch (_a.label) {
292
+ case 0:
293
+ _a.trys.push([0, 2, , 3]);
294
+ ataPubkey_1 = new solanaWeb3.PublicKey(ataAddress);
295
+ return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
296
+ return [2 /*return*/, connection.getAccountInfo(ataPubkey_1)];
297
+ }); }); })];
298
+ case 1:
299
+ accountInfo = _a.sent();
300
+ if (!accountInfo || !accountInfo.data) {
301
+ return [2 /*return*/, null];
302
+ }
303
+ ownerBytes = accountInfo.data.slice(32, 64);
304
+ ownerPubkey = new solanaWeb3.PublicKey(ownerBytes);
305
+ return [2 /*return*/, ownerPubkey.toBase58()];
306
+ case 2:
307
+ e_2 = _a.sent();
308
+ console.warn('[solana-spl][getWalletAddressFromAta] Failed to get wallet address:', e_2);
309
+ return [2 /*return*/, null];
310
+ case 3: return [2 /*return*/];
311
+ }
312
+ });
313
+ });
314
+ };
315
+ SolanaSPLTokenProtocolImpl.prototype.getBalanceOfAddress = function (address) {
316
+ return __awaiter(this, void 0, void 0, function () {
317
+ var walletPubkey_1, mintPubkey_1, tokenAccounts, totalBalance, _i, _a, account, data, amountBytes, amount, e_3;
318
+ var _this = this;
319
+ return __generator(this, function (_b) {
320
+ switch (_b.label) {
321
+ case 0:
322
+ _b.trys.push([0, 2, , 3]);
323
+ walletPubkey_1 = new solanaWeb3.PublicKey(address);
324
+ mintPubkey_1 = new solanaWeb3.PublicKey(this.options.contractAddress);
325
+ return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
326
+ return __generator(this, function (_a) {
327
+ return [2 /*return*/, connection.getTokenAccountsByOwner(walletPubkey_1, { mint: mintPubkey_1 })];
328
+ });
329
+ }); })];
330
+ case 1:
331
+ tokenAccounts = _b.sent();
332
+ totalBalance = new bignumber_1.BigNumber(0);
333
+ for (_i = 0, _a = tokenAccounts.value; _i < _a.length; _i++) {
334
+ account = _a[_i].account;
335
+ data = account.data;
336
+ amountBytes = data.slice(64, 72);
337
+ amount = this.readU64LE(amountBytes);
338
+ totalBalance = totalBalance.plus(amount);
339
+ }
340
+ return [2 /*return*/, {
341
+ total: (0, module_kit_1.newAmount)(totalBalance.toString(), 'blockchain')
342
+ }];
343
+ case 2:
344
+ e_3 = _b.sent();
345
+ console.error('[solana-spl][balance][error]', e_3);
346
+ return [2 /*return*/, { total: (0, module_kit_1.newAmount)(0, 'blockchain') }];
347
+ case 3: return [2 /*return*/];
348
+ }
349
+ });
350
+ });
351
+ };
352
+ // Helper to read u64 little-endian (browser compatible)
353
+ SolanaSPLTokenProtocolImpl.prototype.readU64LE = function (bytes) {
354
+ var result = new bignumber_1.BigNumber(0);
355
+ for (var i = 7; i >= 0; i--) {
356
+ result = result.times(256).plus(bytes[i] || 0);
357
+ }
358
+ return result;
359
+ };
360
+ // Helper to write u64 little-endian (browser compatible)
361
+ SolanaSPLTokenProtocolImpl.prototype.writeU64LE = function (buffer, value, offset) {
362
+ var remaining = value;
363
+ for (var i = 0; i < 8; i++) {
364
+ buffer[offset + i] = Number(remaining & BigInt(0xff));
365
+ remaining = remaining >> BigInt(8);
366
+ }
367
+ };
368
+ SolanaSPLTokenProtocolImpl.prototype.getBalanceOfPublicKey = function (publicKey) {
369
+ return __awaiter(this, void 0, void 0, function () {
370
+ var address;
371
+ return __generator(this, function (_a) {
372
+ switch (_a.label) {
373
+ case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
374
+ case 1:
375
+ address = _a.sent();
376
+ return [2 /*return*/, this.getBalanceOfAddress(address)];
377
+ }
378
+ });
379
+ });
380
+ };
381
+ SolanaSPLTokenProtocolImpl.prototype.getDetailsFromTransaction = function (transaction, publicKey) {
382
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
383
+ return __awaiter(this, void 0, void 0, function () {
384
+ var tx, fallbackFeePayer, _k, _l, _m, feePayer, fee, connection, feeInfo, e_4, _i, _o, ix, amountBytes, amount, destAta, ownerWallet, toWallet, resolvedWallet, _p, amountBytes, amount, destAta, ownerWallet, toWallet, resolvedWallet, _q, e_5;
385
+ return __generator(this, function (_r) {
386
+ switch (_r.label) {
387
+ case 0:
388
+ _r.trys.push([0, 20, , 21]);
389
+ tx = solanaWeb3.Transaction.from(Buffer.from(transaction.serialized, 'hex'));
390
+ if (!(publicKey !== null && publicKey !== undefined)) return [3 /*break*/, 2];
391
+ _m = (_l = solanaWeb3.PublicKey).bind;
392
+ return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
393
+ case 1:
394
+ _k = new (_m.apply(_l, [void 0, _r.sent()]))();
395
+ return [3 /*break*/, 3];
396
+ case 2:
397
+ _k = undefined;
398
+ _r.label = 3;
399
+ case 3:
400
+ fallbackFeePayer = _k;
401
+ feePayer = (tx === null || tx === void 0 ? void 0 : tx.feePayer) || (tx.signatures.length > 0 ? tx.signatures[0].publicKey : fallbackFeePayer);
402
+ fee = (0, module_kit_1.newAmount)(5000, 'Lamports');
403
+ _r.label = 4;
404
+ case 4:
405
+ _r.trys.push([4, 6, , 7]);
406
+ connection = new solanaWeb3.Connection(this.options.network.rpcUrl);
407
+ return [4 /*yield*/, connection.getFeeForMessage(tx.compileMessage())];
408
+ case 5:
409
+ feeInfo = _r.sent();
410
+ fee = (0, module_kit_1.newAmount)((_a = feeInfo === null || feeInfo === void 0 ? void 0 : feeInfo.value) !== null && _a !== void 0 ? _a : 5000, 'Lamports');
411
+ return [3 /*break*/, 7];
412
+ case 6:
413
+ e_4 = _r.sent();
414
+ console.warn('[solana-spl][getDetailsFromTransaction] Network unavailable, using default fee');
415
+ return [3 /*break*/, 7];
416
+ case 7:
417
+ _i = 0, _o = tx.instructions;
418
+ _r.label = 8;
419
+ case 8:
420
+ if (!(_i < _o.length)) return [3 /*break*/, 19];
421
+ ix = _o[_i];
422
+ if (!ix.programId.equals(TOKEN_PROGRAM_ID)) return [3 /*break*/, 18];
423
+ if (!(ix.data.length >= 9 && ix.data[0] === 3)) return [3 /*break*/, 13];
424
+ amountBytes = ix.data.slice(1, 9);
425
+ amount = this.readU64LE(amountBytes).toString();
426
+ destAta = ((_c = (_b = ix.keys[1]) === null || _b === void 0 ? void 0 : _b.pubkey) === null || _c === void 0 ? void 0 : _c.toBase58()) || '';
427
+ ownerWallet = ((_e = (_d = ix.keys[2]) === null || _d === void 0 ? void 0 : _d.pubkey) === null || _e === void 0 ? void 0 : _e.toBase58()) || (feePayer === null || feePayer === void 0 ? void 0 : feePayer.toBase58()) || '';
428
+ toWallet = destAta;
429
+ _r.label = 9;
430
+ case 9:
431
+ _r.trys.push([9, 11, , 12]);
432
+ return [4 /*yield*/, this.getWalletAddressFromAta(destAta)];
433
+ case 10:
434
+ resolvedWallet = _r.sent();
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];
452
+ amountBytes = ix.data.slice(1, 9);
453
+ amount = this.readU64LE(amountBytes).toString();
454
+ destAta = ((_g = (_f = ix.keys[2]) === null || _f === void 0 ? void 0 : _f.pubkey) === null || _g === void 0 ? void 0 : _g.toBase58()) || '';
455
+ ownerWallet = ((_j = (_h = ix.keys[3]) === 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()) || '';
456
+ toWallet = destAta;
457
+ _r.label = 14;
458
+ case 14:
459
+ _r.trys.push([14, 16, , 17]);
460
+ return [4 /*yield*/, this.getWalletAddressFromAta(destAta)];
461
+ case 15:
462
+ resolvedWallet = _r.sent();
463
+ if (resolvedWallet) {
464
+ toWallet = resolvedWallet;
465
+ }
466
+ return [3 /*break*/, 17];
467
+ case 16:
468
+ _q = _r.sent();
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++;
480
+ return [3 /*break*/, 8];
481
+ case 19:
482
+ // Fallback
483
+ return [2 /*return*/, [{
484
+ from: [(feePayer === null || feePayer === void 0 ? void 0 : feePayer.toBase58()) || ''],
485
+ to: [],
486
+ amount: (0, module_kit_1.newAmount)(0, 'blockchain'),
487
+ fee: fee,
488
+ isInbound: false,
489
+ network: this.options.network
490
+ }]];
491
+ case 20:
492
+ e_5 = _r.sent();
493
+ console.error('[solana-spl][getDetailsFromTransaction] Failed:', e_5);
494
+ return [2 /*return*/, [{
495
+ from: [],
496
+ to: [],
497
+ amount: (0, module_kit_1.newAmount)(0, 'blockchain'),
498
+ fee: (0, module_kit_1.newAmount)(0, 'Lamports'),
499
+ isInbound: false,
500
+ network: this.options.network
501
+ }]];
502
+ case 21: return [2 /*return*/];
503
+ }
504
+ });
505
+ });
506
+ };
507
+ SolanaSPLTokenProtocolImpl.prototype.getTransactionDetailsFromSigned = function (signedTx) {
508
+ return __awaiter(this, void 0, void 0, function () {
509
+ return __generator(this, function (_a) {
510
+ return [2 /*return*/, this.getDetailsFromTransaction(signedTx.transaction, null)];
511
+ });
512
+ });
513
+ };
514
+ SolanaSPLTokenProtocolImpl.prototype.verifyMessageWithPublicKey = function (message, signature, publicKey) {
515
+ return __awaiter(this, void 0, void 0, function () {
516
+ var messageBytes, signatureBytes, pubKeyBytes;
517
+ return __generator(this, function (_a) {
518
+ try {
519
+ messageBytes = Buffer.from(message);
520
+ signatureBytes = Buffer.from(signature.value, signature.format === 'hex' ? 'hex' : undefined);
521
+ pubKeyBytes = this.getPublicKeyBuffer(publicKey);
522
+ return [2 /*return*/, nacl.sign.detached.verify(messageBytes, signatureBytes, pubKeyBytes)];
523
+ }
524
+ catch (e) {
525
+ return [2 /*return*/, false];
526
+ }
527
+ return [2 /*return*/];
528
+ });
529
+ });
530
+ };
531
+ SolanaSPLTokenProtocolImpl.prototype.encryptAsymmetricWithPublicKey = function (payload, publicKey) {
532
+ return __awaiter(this, void 0, void 0, function () {
533
+ return __generator(this, function (_a) {
534
+ throw new Error('Not implemented');
535
+ });
536
+ });
537
+ };
538
+ SolanaSPLTokenProtocolImpl.prototype.getCryptoConfiguration = function () {
539
+ return __awaiter(this, void 0, void 0, function () {
540
+ return __generator(this, function (_a) {
541
+ return [2 /*return*/, { algorithm: 'ed25519' }];
542
+ });
543
+ });
544
+ };
545
+ SolanaSPLTokenProtocolImpl.prototype.getKeyPairFromDerivative = function (derivative) {
546
+ return __awaiter(this, void 0, void 0, function () {
547
+ var secretKeyBuffer, publicKeyBuffer;
548
+ return __generator(this, function (_a) {
549
+ secretKeyBuffer = Buffer.from(derivative.secretKey, 'hex');
550
+ publicKeyBuffer = Buffer.from(derivative.publicKey, 'hex');
551
+ return [2 /*return*/, {
552
+ publicKey: {
553
+ value: publicKeyBuffer.toString('hex'),
554
+ format: 'hex',
555
+ type: 'pub'
556
+ },
557
+ secretKey: {
558
+ value: secretKeyBuffer.toString('hex'),
559
+ format: 'hex',
560
+ type: 'priv'
561
+ }
562
+ }];
563
+ });
564
+ });
565
+ };
566
+ SolanaSPLTokenProtocolImpl.prototype.signTransactionWithSecretKey = function (transaction, secretKey) {
567
+ return __awaiter(this, void 0, void 0, function () {
568
+ var tx, keyHex, secretKeyBytes, keyPair;
569
+ return __generator(this, function (_a) {
570
+ tx = solanaWeb3.Transaction.from(Buffer.from(transaction.serialized, 'hex'));
571
+ keyHex = secretKey.value;
572
+ secretKeyBytes = Buffer.from(keyHex, secretKey.format === 'hex' ? 'hex' : undefined);
573
+ try {
574
+ if (secretKeyBytes.length === 64) {
575
+ keyPair = solanaWeb3.Keypair.fromSecretKey(secretKeyBytes);
576
+ }
577
+ else if (secretKeyBytes.length === 32) {
578
+ keyPair = solanaWeb3.Keypair.fromSeed(secretKeyBytes);
579
+ }
580
+ else {
581
+ throw new Error("Invalid secret key length: ".concat(secretKeyBytes.length));
582
+ }
583
+ }
584
+ catch (e) {
585
+ throw new Error("Could not create keypair from secret key: ".concat(e));
586
+ }
587
+ tx.sign(keyPair);
588
+ return [2 /*return*/, {
589
+ serialized: tx.serialize().toString('hex'),
590
+ type: 'signed'
591
+ }];
592
+ });
593
+ });
594
+ };
595
+ SolanaSPLTokenProtocolImpl.prototype.signMessageWithKeyPair = function (message, keyPair) {
596
+ return __awaiter(this, void 0, void 0, function () {
597
+ var messageBytes, secretKeyBytes, signingKey, signature;
598
+ return __generator(this, function (_a) {
599
+ messageBytes = Buffer.from(message);
600
+ secretKeyBytes = Buffer.from(keyPair.secretKey.value, keyPair.secretKey.format === 'hex' ? 'hex' : undefined);
601
+ if (secretKeyBytes.length === 64) {
602
+ signingKey = secretKeyBytes;
603
+ }
604
+ else if (secretKeyBytes.length === 32) {
605
+ signingKey = nacl.sign.keyPair.fromSeed(secretKeyBytes).secretKey;
606
+ }
607
+ else {
608
+ throw new Error('Invalid secret key length');
609
+ }
610
+ signature = nacl.sign.detached(messageBytes, signingKey);
611
+ return [2 /*return*/, (0, module_kit_1.newSignature)(Buffer.from(signature).toString('hex'), 'hex')];
612
+ });
613
+ });
614
+ };
615
+ SolanaSPLTokenProtocolImpl.prototype.decryptAsymmetricWithKeyPair = function (payload, keyPair) {
616
+ return __awaiter(this, void 0, void 0, function () {
617
+ return __generator(this, function (_a) {
618
+ throw new Error('Not implemented');
619
+ });
620
+ });
621
+ };
622
+ SolanaSPLTokenProtocolImpl.prototype.encryptAESWithSecretKey = function (payload, secretKey) {
623
+ return __awaiter(this, void 0, void 0, function () {
624
+ return __generator(this, function (_a) {
625
+ throw new Error('Not implemented');
626
+ });
627
+ });
628
+ };
629
+ SolanaSPLTokenProtocolImpl.prototype.decryptAESWithSecretKey = function (payload, secretKey) {
630
+ return __awaiter(this, void 0, void 0, function () {
631
+ return __generator(this, function (_a) {
632
+ throw new Error('Not implemented');
633
+ });
634
+ });
635
+ };
636
+ SolanaSPLTokenProtocolImpl.prototype.getNetwork = function () {
637
+ return __awaiter(this, void 0, void 0, function () {
638
+ return __generator(this, function (_a) {
639
+ return [2 /*return*/, this.options.network];
640
+ });
641
+ });
642
+ };
643
+ SolanaSPLTokenProtocolImpl.prototype.getTransactionsForAddress = function (address, limit, cursor) {
644
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
645
+ return __awaiter(this, void 0, void 0, function () {
646
+ var walletPubkey_2, mintPubkey_2, effectiveLimit, tokenAccounts, txs, myAtaAddresses, _i, _k, pubkey, queryOptions_1, allSignatures, _loop_2, this_1, _l, _m, tokenAccountPubkey, uniqueSignatures, limitedSignatures, _loop_3, this_2, _o, limitedSignatures_1, sigInfo, hasNext, lastSignature, newCursor, e_6;
647
+ var _this = this;
648
+ return __generator(this, function (_p) {
649
+ switch (_p.label) {
650
+ case 0:
651
+ _p.trys.push([0, 10, , 11]);
652
+ walletPubkey_2 = new solanaWeb3.PublicKey(address);
653
+ mintPubkey_2 = new solanaWeb3.PublicKey(this.options.contractAddress);
654
+ effectiveLimit = limit || SolanaSPLTokenProtocolImpl.DEFAULT_TX_LIMIT;
655
+ return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
656
+ return [2 /*return*/, connection.getTokenAccountsByOwner(walletPubkey_2, { mint: mintPubkey_2 })];
657
+ }); }); })];
658
+ case 1:
659
+ tokenAccounts = _p.sent();
660
+ if (tokenAccounts.value.length === 0) {
661
+ return [2 /*return*/, {
662
+ transactions: [],
663
+ cursor: { hasNext: false }
664
+ }];
665
+ }
666
+ txs = [];
667
+ myAtaAddresses = new Set();
668
+ for (_i = 0, _k = tokenAccounts.value; _i < _k.length; _i++) {
669
+ pubkey = _k[_i].pubkey;
670
+ myAtaAddresses.add(pubkey.toBase58());
671
+ }
672
+ queryOptions_1 = {
673
+ limit: effectiveLimit
674
+ };
675
+ // If cursor has lastSignature, use it for pagination
676
+ if (cursor === null || cursor === void 0 ? void 0 : cursor.lastSignature) {
677
+ queryOptions_1.before = cursor.lastSignature;
678
+ }
679
+ allSignatures = [];
680
+ _loop_2 = function (tokenAccountPubkey) {
681
+ var signatures, _q, signatures_1, sig;
682
+ return __generator(this, function (_r) {
683
+ switch (_r.label) {
684
+ case 0: return [4 /*yield*/, this_1.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
685
+ return [2 /*return*/, connection.getSignaturesForAddress(tokenAccountPubkey, queryOptions_1)];
686
+ }); }); })];
687
+ case 1:
688
+ signatures = _r.sent();
689
+ for (_q = 0, signatures_1 = signatures; _q < signatures_1.length; _q++) {
690
+ sig = signatures_1[_q];
691
+ if (sig.signature) {
692
+ allSignatures.push({
693
+ signature: sig.signature,
694
+ blockTime: sig.blockTime,
695
+ confirmationStatus: sig.confirmationStatus
696
+ });
697
+ }
698
+ }
699
+ return [2 /*return*/];
700
+ }
701
+ });
702
+ };
703
+ this_1 = this;
704
+ _l = 0, _m = tokenAccounts.value;
705
+ _p.label = 2;
706
+ case 2:
707
+ if (!(_l < _m.length)) return [3 /*break*/, 5];
708
+ tokenAccountPubkey = _m[_l].pubkey;
709
+ return [5 /*yield**/, _loop_2(tokenAccountPubkey)];
710
+ case 3:
711
+ _p.sent();
712
+ _p.label = 4;
713
+ case 4:
714
+ _l++;
715
+ return [3 /*break*/, 2];
716
+ case 5:
717
+ uniqueSignatures = Array.from(new Map(allSignatures.map(function (s) { return [s.signature, s]; })).values());
718
+ // Sort by blockTime descending (most recent first)
719
+ uniqueSignatures.sort(function (a, b) { return (b.blockTime || 0) - (a.blockTime || 0); });
720
+ limitedSignatures = uniqueSignatures.slice(0, effectiveLimit);
721
+ _loop_3 = function (sigInfo) {
722
+ var parsed, amount, fromWallet, toWallet, isInbound, instructions, _s, instructions_1, ix, parsedIx, info, sourceAta, destAta, authorityWallet, resolvedFrom, resolvedTo, blockTime, timestamp, e_7;
723
+ return __generator(this, function (_t) {
724
+ switch (_t.label) {
725
+ case 0:
726
+ _t.trys.push([0, 11, , 12]);
727
+ return [4 /*yield*/, this_2.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
728
+ return __generator(this, function (_a) {
729
+ return [2 /*return*/, connection.getParsedTransaction(sigInfo.signature, {
730
+ commitment: 'confirmed',
731
+ maxSupportedTransactionVersion: 0
732
+ })];
733
+ });
734
+ }); })];
735
+ case 1:
736
+ parsed = _t.sent();
737
+ if (!parsed)
738
+ return [2 /*return*/, "continue"];
739
+ amount = (0, module_kit_1.newAmount)(0, 'blockchain');
740
+ fromWallet = address;
741
+ toWallet = address;
742
+ isInbound = false;
743
+ instructions = ((_b = (_a = parsed.transaction) === null || _a === void 0 ? void 0 : _a.message) === null || _b === void 0 ? void 0 : _b.instructions) || [];
744
+ _s = 0, instructions_1 = instructions;
745
+ _t.label = 2;
746
+ case 2:
747
+ if (!(_s < instructions_1.length)) return [3 /*break*/, 10];
748
+ ix = instructions_1[_s];
749
+ if (!('parsed' in ix && ix.parsed)) return [3 /*break*/, 9];
750
+ parsedIx = ix;
751
+ if (!(parsedIx.program === 'spl-token')) return [3 /*break*/, 9];
752
+ info = (_c = parsedIx.parsed) === null || _c === void 0 ? void 0 : _c.info;
753
+ if (!(((_d = parsedIx.parsed) === null || _d === void 0 ? void 0 : _d.type) === 'transfer' || ((_e = parsedIx.parsed) === null || _e === void 0 ? void 0 : _e.type) === 'transferChecked')) return [3 /*break*/, 9];
754
+ if (!((info === null || info === void 0 ? void 0 : info.mint) === this_2.options.contractAddress || !(info === null || info === void 0 ? void 0 : info.mint))) return [3 /*break*/, 9];
755
+ amount = (0, module_kit_1.newAmount)((info === null || info === void 0 ? void 0 : info.amount) || ((_f = info === null || info === void 0 ? void 0 : info.tokenAmount) === null || _f === void 0 ? void 0 : _f.amount) || '0', 'blockchain');
756
+ sourceAta = (info === null || info === void 0 ? void 0 : info.source) || '';
757
+ destAta = (info === null || info === void 0 ? void 0 : info.destination) || '';
758
+ authorityWallet = (info === null || info === void 0 ? void 0 : info.authority) || '';
759
+ // Determine if this is inbound or outbound based on ATA ownership
760
+ isInbound = myAtaAddresses.has(destAta) && !myAtaAddresses.has(sourceAta);
761
+ if (!isInbound) return [3 /*break*/, 6];
762
+ // Inbound: we received tokens
763
+ // from = sender's wallet (need to resolve from source ATA)
764
+ // to = our wallet address
765
+ toWallet = address;
766
+ if (!authorityWallet) return [3 /*break*/, 3];
767
+ fromWallet = authorityWallet;
768
+ return [3 /*break*/, 5];
769
+ case 3: return [4 /*yield*/, this_2.getWalletAddressFromAta(sourceAta).catch(function () { return null; })];
770
+ case 4:
771
+ resolvedFrom = _t.sent();
772
+ fromWallet = resolvedFrom || sourceAta;
773
+ _t.label = 5;
774
+ case 5: return [3 /*break*/, 8];
775
+ case 6:
776
+ // Outbound: we sent tokens
777
+ // from = our wallet address
778
+ // to = recipient's wallet (need to resolve from dest ATA)
779
+ fromWallet = authorityWallet || address;
780
+ return [4 /*yield*/, this_2.getWalletAddressFromAta(destAta).catch(function () { return null; })];
781
+ case 7:
782
+ resolvedTo = _t.sent();
783
+ toWallet = resolvedTo || destAta;
784
+ _t.label = 8;
785
+ case 8: return [3 /*break*/, 10];
786
+ case 9:
787
+ _s++;
788
+ return [3 /*break*/, 2];
789
+ case 10:
790
+ blockTime = (_g = sigInfo.blockTime) !== null && _g !== void 0 ? _g : parsed.blockTime;
791
+ timestamp = blockTime ? blockTime : Math.floor(Date.now() / 1000);
792
+ txs.push({
793
+ hash: sigInfo.signature,
794
+ timestamp: timestamp,
795
+ status: sigInfo.confirmationStatus || 'processed',
796
+ amount: amount,
797
+ fee: (0, module_kit_1.newAmount)((_j = (_h = parsed.meta) === null || _h === void 0 ? void 0 : _h.fee) !== null && _j !== void 0 ? _j : 0, 'Lamports'),
798
+ from: [fromWallet],
799
+ to: [toWallet],
800
+ isInbound: isInbound,
801
+ network: this_2.options.network
802
+ });
803
+ return [3 /*break*/, 12];
804
+ case 11:
805
+ e_7 = _t.sent();
806
+ console.warn('[solana-spl][getTransactionsForAddress] Failed to parse tx:', sigInfo.signature);
807
+ return [3 /*break*/, 12];
808
+ case 12: return [2 /*return*/];
809
+ }
810
+ });
811
+ };
812
+ this_2 = this;
813
+ _o = 0, limitedSignatures_1 = limitedSignatures;
814
+ _p.label = 6;
815
+ case 6:
816
+ if (!(_o < limitedSignatures_1.length)) return [3 /*break*/, 9];
817
+ sigInfo = limitedSignatures_1[_o];
818
+ return [5 /*yield**/, _loop_3(sigInfo)];
819
+ case 7:
820
+ _p.sent();
821
+ _p.label = 8;
822
+ case 8:
823
+ _o++;
824
+ return [3 /*break*/, 6];
825
+ case 9:
826
+ hasNext = limitedSignatures.length === effectiveLimit;
827
+ lastSignature = limitedSignatures.length > 0 ? limitedSignatures[limitedSignatures.length - 1].signature : undefined;
828
+ newCursor = {
829
+ hasNext: hasNext,
830
+ lastSignature: lastSignature
831
+ };
832
+ return [2 /*return*/, {
833
+ transactions: txs,
834
+ cursor: newCursor
835
+ }];
836
+ case 10:
837
+ e_6 = _p.sent();
838
+ console.error('[solana-spl][getTransactionsForAddress] Failed:', e_6);
839
+ return [2 /*return*/, {
840
+ transactions: [],
841
+ cursor: { hasNext: false }
842
+ }];
843
+ case 11: return [2 /*return*/];
844
+ }
845
+ });
846
+ });
847
+ };
848
+ SolanaSPLTokenProtocolImpl.prototype.getTransactionsForPublicKey = function (publicKey, limit, cursor) {
849
+ return __awaiter(this, void 0, void 0, function () {
850
+ var address;
851
+ return __generator(this, function (_a) {
852
+ switch (_a.label) {
853
+ case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
854
+ case 1:
855
+ address = _a.sent();
856
+ return [2 /*return*/, this.getTransactionsForAddress(address, limit, cursor)];
857
+ }
858
+ });
859
+ });
860
+ };
861
+ SolanaSPLTokenProtocolImpl.prototype.getTransactionStatus = function (transactionIds) {
862
+ var _a;
863
+ return __awaiter(this, void 0, void 0, function () {
864
+ var statuses, result, i, id, status_1;
865
+ var _this = this;
866
+ return __generator(this, function (_b) {
867
+ switch (_b.label) {
868
+ case 0: return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
869
+ return __generator(this, function (_a) {
870
+ switch (_a.label) {
871
+ case 0: return [4 /*yield*/, connection.getSignatureStatuses(transactionIds)];
872
+ case 1: return [2 /*return*/, (_a.sent()).value];
873
+ }
874
+ });
875
+ }); })];
876
+ case 1:
877
+ statuses = _b.sent();
878
+ result = {};
879
+ for (i = 0; i < transactionIds.length; i++) {
880
+ id = transactionIds[i];
881
+ status_1 = statuses[i];
882
+ result[id] = { status: (_a = status_1 === null || status_1 === void 0 ? void 0 : status_1.confirmationStatus) !== null && _a !== void 0 ? _a : 'unknown' };
883
+ }
884
+ return [2 /*return*/, result];
885
+ }
886
+ });
887
+ });
888
+ };
889
+ SolanaSPLTokenProtocolImpl.prototype.getTransactionMaxAmountWithPublicKey = function (publicKey, to, configuration) {
890
+ return __awaiter(this, void 0, void 0, function () {
891
+ var balance;
892
+ return __generator(this, function (_a) {
893
+ switch (_a.label) {
894
+ case 0: return [4 /*yield*/, this.getBalanceOfPublicKey(publicKey)];
895
+ case 1:
896
+ balance = _a.sent();
897
+ return [2 /*return*/, balance.total];
898
+ }
899
+ });
900
+ });
901
+ };
902
+ SolanaSPLTokenProtocolImpl.prototype.getTransactionFeeWithPublicKey = function (publicKey, details, configuration) {
903
+ return __awaiter(this, void 0, void 0, function () {
904
+ var baseFee, totalAtaCreationCost, mintPubkey, _loop_4, this_3, _i, details_1, detail, e_8, totalFee;
905
+ var _this = this;
906
+ return __generator(this, function (_a) {
907
+ switch (_a.label) {
908
+ case 0:
909
+ baseFee = 5000 // lamports
910
+ ;
911
+ totalAtaCreationCost = 0;
912
+ _a.label = 1;
913
+ case 1:
914
+ _a.trys.push([1, 6, , 7]);
915
+ mintPubkey = new solanaWeb3.PublicKey(this.options.contractAddress);
916
+ _loop_4 = function (detail) {
917
+ var toPubkey, destAta, destAtaInfo;
918
+ return __generator(this, function (_b) {
919
+ switch (_b.label) {
920
+ case 0:
921
+ toPubkey = new solanaWeb3.PublicKey(detail.to);
922
+ return [4 /*yield*/, solanaWeb3.PublicKey.findProgramAddress([
923
+ toPubkey.toBuffer(),
924
+ TOKEN_PROGRAM_ID.toBuffer(),
925
+ mintPubkey.toBuffer()
926
+ ], ASSOCIATED_TOKEN_PROGRAM_ID)
927
+ // Check if destination ATA exists
928
+ ];
929
+ case 1:
930
+ destAta = (_b.sent())[0];
931
+ return [4 /*yield*/, this_3.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
932
+ return [2 /*return*/, connection.getAccountInfo(destAta)];
933
+ }); }); }).catch(function () { return null; })];
934
+ case 2:
935
+ destAtaInfo = _b.sent();
936
+ if (!destAtaInfo) {
937
+ // ATA doesn't exist, need to pay rent exemption to create it
938
+ totalAtaCreationCost += TOKEN_ACCOUNT_RENT_EXEMPTION_LAMPORTS;
939
+ }
940
+ return [2 /*return*/];
941
+ }
942
+ });
943
+ };
944
+ this_3 = this;
945
+ _i = 0, details_1 = details;
946
+ _a.label = 2;
947
+ case 2:
948
+ if (!(_i < details_1.length)) return [3 /*break*/, 5];
949
+ detail = details_1[_i];
950
+ 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
+ case 6:
959
+ e_8 = _a.sent();
960
+ console.warn('[solana-spl][getTransactionFeeWithPublicKey] Failed to check ATA existence, assuming worst case');
961
+ // Assume all destinations need ATA creation (worst case)
962
+ totalAtaCreationCost = details.length * TOKEN_ACCOUNT_RENT_EXEMPTION_LAMPORTS;
963
+ return [3 /*break*/, 7];
964
+ case 7:
965
+ totalFee = baseFee + totalAtaCreationCost;
966
+ return [2 /*return*/, {
967
+ low: (0, module_kit_1.newAmount)(totalFee, 'Lamports'),
968
+ medium: (0, module_kit_1.newAmount)(totalFee, 'Lamports'),
969
+ high: (0, module_kit_1.newAmount)(totalFee, 'Lamports')
970
+ }];
971
+ }
972
+ });
973
+ });
974
+ };
975
+ SolanaSPLTokenProtocolImpl.prototype.prepareTransactionWithPublicKey = function (publicKey, details, configuration) {
976
+ return __awaiter(this, void 0, void 0, function () {
977
+ var fromAddress, fromPubkey, mintPubkey, transaction, _loop_5, this_4, _i, details_2, detail, blockhash, serialized;
978
+ var _this = this;
979
+ return __generator(this, function (_a) {
980
+ switch (_a.label) {
981
+ case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)];
982
+ case 1:
983
+ fromAddress = _a.sent();
984
+ fromPubkey = new solanaWeb3.PublicKey(fromAddress);
985
+ mintPubkey = new solanaWeb3.PublicKey(this.options.contractAddress);
986
+ transaction = new solanaWeb3.Transaction();
987
+ _loop_5 = function (detail) {
988
+ var toPubkey, sourceAta, destAta, destAtaInfo, createAtaIx, amount, transferIx;
989
+ return __generator(this, function (_b) {
990
+ switch (_b.label) {
991
+ case 0:
992
+ toPubkey = new solanaWeb3.PublicKey(detail.to);
993
+ return [4 /*yield*/, this_4.getAssociatedTokenAddress(fromAddress)
994
+ // Get destination token account (ATA)
995
+ ];
996
+ case 1:
997
+ sourceAta = _b.sent();
998
+ return [4 /*yield*/, solanaWeb3.PublicKey.findProgramAddress([
999
+ toPubkey.toBuffer(),
1000
+ TOKEN_PROGRAM_ID.toBuffer(),
1001
+ mintPubkey.toBuffer()
1002
+ ], ASSOCIATED_TOKEN_PROGRAM_ID)
1003
+ // Check if destination ATA exists, if not create it
1004
+ ];
1005
+ case 2:
1006
+ destAta = (_b.sent())[0];
1007
+ return [4 /*yield*/, this_4.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
1008
+ return [2 /*return*/, connection.getAccountInfo(destAta)];
1009
+ }); }); })];
1010
+ case 3:
1011
+ destAtaInfo = _b.sent();
1012
+ if (!destAtaInfo) {
1013
+ createAtaIx = this_4.createAssociatedTokenAccountInstruction(fromPubkey, // payer
1014
+ destAta, // ata
1015
+ toPubkey, // owner
1016
+ mintPubkey // mint
1017
+ );
1018
+ transaction.add(createAtaIx);
1019
+ }
1020
+ amount = new bignumber_1.BigNumber((0, module_kit_1.newAmount)(detail.amount).blockchain(this_4.units).value);
1021
+ transferIx = this_4.createTransferInstruction(sourceAta, destAta, fromPubkey, BigInt(amount.toFixed(0)));
1022
+ transaction.add(transferIx);
1023
+ return [2 /*return*/];
1024
+ }
1025
+ });
1026
+ };
1027
+ this_4 = this;
1028
+ _i = 0, details_2 = details;
1029
+ _a.label = 2;
1030
+ case 2:
1031
+ if (!(_i < details_2.length)) return [3 /*break*/, 5];
1032
+ detail = details_2[_i];
1033
+ return [5 /*yield**/, _loop_5(detail)];
1034
+ case 3:
1035
+ _a.sent();
1036
+ _a.label = 4;
1037
+ case 4:
1038
+ _i++;
1039
+ return [3 /*break*/, 2];
1040
+ case 5:
1041
+ transaction.feePayer = fromPubkey;
1042
+ return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
1043
+ var result;
1044
+ return __generator(this, function (_a) {
1045
+ switch (_a.label) {
1046
+ case 0: return [4 /*yield*/, connection.getLatestBlockhash()];
1047
+ case 1:
1048
+ result = _a.sent();
1049
+ return [2 /*return*/, result.blockhash];
1050
+ }
1051
+ });
1052
+ }); })];
1053
+ case 6:
1054
+ blockhash = _a.sent();
1055
+ transaction.recentBlockhash = blockhash;
1056
+ serialized = transaction.serialize({ requireAllSignatures: false }).toString('hex');
1057
+ return [2 /*return*/, {
1058
+ serialized: serialized,
1059
+ type: 'unsigned'
1060
+ }];
1061
+ }
1062
+ });
1063
+ });
1064
+ };
1065
+ // Helper: Create Associated Token Account instruction
1066
+ SolanaSPLTokenProtocolImpl.prototype.createAssociatedTokenAccountInstruction = function (payer, associatedToken, owner, mint) {
1067
+ return new solanaWeb3.TransactionInstruction({
1068
+ keys: [
1069
+ { pubkey: payer, isSigner: true, isWritable: true },
1070
+ { pubkey: associatedToken, isSigner: false, isWritable: true },
1071
+ { pubkey: owner, isSigner: false, isWritable: false },
1072
+ { pubkey: mint, isSigner: false, isWritable: false },
1073
+ { pubkey: solanaWeb3.SystemProgram.programId, isSigner: false, isWritable: false },
1074
+ { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
1075
+ ],
1076
+ programId: ASSOCIATED_TOKEN_PROGRAM_ID,
1077
+ data: Buffer.alloc(0)
1078
+ });
1079
+ };
1080
+ // Helper: Create SPL Token transfer instruction
1081
+ SolanaSPLTokenProtocolImpl.prototype.createTransferInstruction = function (source, destination, owner, amount) {
1082
+ var data = Buffer.alloc(9);
1083
+ data.writeUInt8(3, 0); // Transfer instruction
1084
+ this.writeU64LE(data, amount, 1); // Browser-compatible u64 write
1085
+ return new solanaWeb3.TransactionInstruction({
1086
+ keys: [
1087
+ { pubkey: source, isSigner: false, isWritable: true },
1088
+ { pubkey: destination, isSigner: false, isWritable: true },
1089
+ { pubkey: owner, isSigner: true, isWritable: false }
1090
+ ],
1091
+ programId: TOKEN_PROGRAM_ID,
1092
+ data: data
1093
+ });
1094
+ };
1095
+ SolanaSPLTokenProtocolImpl.prototype.broadcastTransaction = function (transaction) {
1096
+ return __awaiter(this, void 0, void 0, function () {
1097
+ var txBuffer, signature;
1098
+ var _this = this;
1099
+ return __generator(this, function (_a) {
1100
+ switch (_a.label) {
1101
+ case 0:
1102
+ txBuffer = Buffer.from(transaction.serialized, 'hex');
1103
+ return [4 /*yield*/, this.withFallback(function (connection) { return __awaiter(_this, void 0, void 0, function () {
1104
+ return __generator(this, function (_a) {
1105
+ return [2 /*return*/, connection.sendRawTransaction(txBuffer)];
1106
+ });
1107
+ }); })];
1108
+ case 1:
1109
+ signature = _a.sent();
1110
+ return [2 /*return*/, signature];
1111
+ }
1112
+ });
1113
+ });
1114
+ };
1115
+ // Fallback RPC endpoints for reliability
1116
+ SolanaSPLTokenProtocolImpl.FALLBACK_RPC_URLS = [
1117
+ 'https://solana.drpc.org'
1118
+ ];
1119
+ // Default number of transactions to fetch per page
1120
+ SolanaSPLTokenProtocolImpl.DEFAULT_TX_LIMIT = 10;
1121
+ return SolanaSPLTokenProtocolImpl;
1122
+ }());
1123
+ exports.SolanaSPLTokenProtocolImpl = SolanaSPLTokenProtocolImpl;
1124
+ // Factory function
1125
+ function createSolanaSPLTokenProtocol(options) {
1126
+ return new SolanaSPLTokenProtocolImpl(options);
1127
+ }
1128
+ exports.createSolanaSPLTokenProtocol = createSolanaSPLTokenProtocol;
1129
+ //# sourceMappingURL=SolanaSPLTokenProtocol.js.map