@formo/analytics 1.27.0 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/dist/cjs/src/FormoAnalytics.d.ts +69 -12
  2. package/dist/cjs/src/FormoAnalytics.js +273 -147
  3. package/dist/cjs/src/event/EventFactory.d.ts +10 -2
  4. package/dist/cjs/src/event/EventFactory.js +32 -21
  5. package/dist/cjs/src/index.d.ts +4 -0
  6. package/dist/cjs/src/index.js +6 -0
  7. package/dist/cjs/src/privy/index.d.ts +9 -0
  8. package/dist/cjs/src/privy/index.js +12 -0
  9. package/dist/cjs/src/privy/types.d.ts +175 -0
  10. package/dist/cjs/src/privy/types.js +12 -0
  11. package/dist/cjs/src/privy/utils.d.ts +32 -0
  12. package/dist/cjs/src/privy/utils.js +188 -0
  13. package/dist/cjs/src/session/index.js +2 -1
  14. package/dist/cjs/src/solana/SolanaAdapter.d.ts +211 -0
  15. package/dist/cjs/src/solana/SolanaAdapter.js +975 -0
  16. package/dist/cjs/src/solana/SolanaManager.d.ts +24 -0
  17. package/dist/cjs/src/solana/SolanaManager.js +80 -0
  18. package/dist/cjs/src/solana/address.d.ts +72 -0
  19. package/dist/cjs/src/solana/address.js +176 -0
  20. package/dist/cjs/src/solana/index.d.ts +13 -0
  21. package/dist/cjs/src/solana/index.js +32 -0
  22. package/dist/cjs/src/solana/types.d.ts +206 -0
  23. package/dist/cjs/src/solana/types.js +80 -0
  24. package/dist/cjs/src/types/base.d.ts +17 -0
  25. package/dist/cjs/src/types/events.d.ts +4 -3
  26. package/dist/cjs/src/utils/address.d.ts +21 -0
  27. package/dist/cjs/src/utils/address.js +48 -1
  28. package/dist/cjs/src/utils/builderCode.d.ts +30 -0
  29. package/dist/cjs/src/utils/builderCode.js +143 -0
  30. package/dist/cjs/src/utils/index.d.ts +1 -0
  31. package/dist/cjs/src/utils/index.js +1 -0
  32. package/dist/cjs/src/version.d.ts +1 -1
  33. package/dist/cjs/src/version.js +1 -1
  34. package/dist/cjs/src/wagmi/WagmiEventHandler.js +13 -15
  35. package/dist/cjs/src/wagmi/utils.d.ts +5 -0
  36. package/dist/cjs/src/wagmi/utils.js +20 -0
  37. package/dist/esm/src/FormoAnalytics.d.ts +69 -12
  38. package/dist/esm/src/FormoAnalytics.js +274 -148
  39. package/dist/esm/src/event/EventFactory.d.ts +10 -2
  40. package/dist/esm/src/event/EventFactory.js +34 -23
  41. package/dist/esm/src/index.d.ts +4 -0
  42. package/dist/esm/src/index.js +3 -0
  43. package/dist/esm/src/privy/index.d.ts +9 -0
  44. package/dist/esm/src/privy/index.js +8 -0
  45. package/dist/esm/src/privy/types.d.ts +175 -0
  46. package/dist/esm/src/privy/types.js +11 -0
  47. package/dist/esm/src/privy/utils.d.ts +32 -0
  48. package/dist/esm/src/privy/utils.js +185 -0
  49. package/dist/esm/src/session/index.js +2 -1
  50. package/dist/esm/src/solana/SolanaAdapter.d.ts +211 -0
  51. package/dist/esm/src/solana/SolanaAdapter.js +972 -0
  52. package/dist/esm/src/solana/SolanaManager.d.ts +24 -0
  53. package/dist/esm/src/solana/SolanaManager.js +77 -0
  54. package/dist/esm/src/solana/address.d.ts +72 -0
  55. package/dist/esm/src/solana/address.js +167 -0
  56. package/dist/esm/src/solana/index.d.ts +13 -0
  57. package/dist/esm/src/solana/index.js +13 -0
  58. package/dist/esm/src/solana/types.d.ts +206 -0
  59. package/dist/esm/src/solana/types.js +74 -0
  60. package/dist/esm/src/types/base.d.ts +17 -0
  61. package/dist/esm/src/types/events.d.ts +4 -3
  62. package/dist/esm/src/utils/address.d.ts +21 -0
  63. package/dist/esm/src/utils/address.js +45 -0
  64. package/dist/esm/src/utils/builderCode.d.ts +30 -0
  65. package/dist/esm/src/utils/builderCode.js +140 -0
  66. package/dist/esm/src/utils/index.d.ts +1 -0
  67. package/dist/esm/src/utils/index.js +1 -0
  68. package/dist/esm/src/version.d.ts +1 -1
  69. package/dist/esm/src/version.js +1 -1
  70. package/dist/esm/src/wagmi/WagmiEventHandler.js +14 -16
  71. package/dist/esm/src/wagmi/utils.d.ts +5 -0
  72. package/dist/esm/src/wagmi/utils.js +19 -0
  73. package/dist/index.umd.min.js +1 -1
  74. package/package.json +15 -3
@@ -0,0 +1,975 @@
1
+ "use strict";
2
+ /**
3
+ * SolanaAdapter
4
+ *
5
+ * Handles wallet event tracking by hooking into Solana Wallet Adapter events.
6
+ * This provides integration with the @solana/wallet-adapter ecosystem.
7
+ *
8
+ * @see https://github.com/anza-xyz/wallet-adapter
9
+ */
10
+ var __assign = (this && this.__assign) || function () {
11
+ __assign = Object.assign || function(t) {
12
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
13
+ s = arguments[i];
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
15
+ t[p] = s[p];
16
+ }
17
+ return t;
18
+ };
19
+ return __assign.apply(this, arguments);
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ var __generator = (this && this.__generator) || function (thisArg, body) {
31
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
32
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
33
+ function verb(n) { return function (v) { return step([n, v]); }; }
34
+ function step(op) {
35
+ if (f) throw new TypeError("Generator is already executing.");
36
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
37
+ 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;
38
+ if (y = 0, t) op = [op[0] & 2, t.value];
39
+ switch (op[0]) {
40
+ case 0: case 1: t = op; break;
41
+ case 4: _.label++; return { value: op[1], done: false };
42
+ case 5: _.label++; y = op[1]; op = [0]; continue;
43
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
44
+ default:
45
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
46
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
47
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
48
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
49
+ if (t[2]) _.ops.pop();
50
+ _.trys.pop(); continue;
51
+ }
52
+ op = body.call(thisArg, _);
53
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
54
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
55
+ }
56
+ };
57
+ Object.defineProperty(exports, "__esModule", { value: true });
58
+ exports.SolanaAdapter = void 0;
59
+ var events_1 = require("../types/events");
60
+ var logger_1 = require("../logger");
61
+ var types_1 = require("./types");
62
+ var address_1 = require("./address");
63
+ /**
64
+ * Clean up old entries from a Set to prevent memory leaks.
65
+ */
66
+ function cleanupOldEntries(set, maxSize, removeCount) {
67
+ if (maxSize === void 0) { maxSize = 1000; }
68
+ if (removeCount === void 0) { removeCount = 500; }
69
+ if (set.size > maxSize) {
70
+ var entries = Array.from(set);
71
+ for (var i = 0; i < removeCount && i < entries.length; i++) {
72
+ set.delete(entries[i]);
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Convert a Uint8Array to a hex string (browser-compatible alternative to Buffer.from().toString('hex'))
78
+ */
79
+ function uint8ArrayToHex(bytes) {
80
+ return Array.from(bytes)
81
+ .map(function (b) { return b.toString(16).padStart(2, "0"); })
82
+ .join("");
83
+ }
84
+ /**
85
+ * Safely decode a Uint8Array message to string.
86
+ * Falls back to hex representation if TextDecoder is unavailable (some Node environments).
87
+ */
88
+ function safeDecodeMessage(message) {
89
+ try {
90
+ if (typeof TextDecoder !== "undefined") {
91
+ return new TextDecoder().decode(message);
92
+ }
93
+ // Fallback for Node environments without TextDecoder global
94
+ if (typeof Buffer !== "undefined") {
95
+ return Buffer.from(message).toString("utf-8");
96
+ }
97
+ // Last resort: hex representation
98
+ return "0x".concat(uint8ArrayToHex(message));
99
+ }
100
+ catch (_a) {
101
+ return "0x".concat(uint8ArrayToHex(message));
102
+ }
103
+ }
104
+ var SolanaAdapter = /** @class */ (function () {
105
+ function SolanaAdapter(formoAnalytics, options) {
106
+ this.wallet = null;
107
+ this.connection = null;
108
+ this.unsubscribers = [];
109
+ this.connectionState = {
110
+ isProcessing: false,
111
+ };
112
+ /**
113
+ * Track processed signatures to prevent duplicate event emissions
114
+ */
115
+ this.processedSignatures = new Set();
116
+ /**
117
+ * Store pending transaction details for confirmation tracking
118
+ * Key: transaction signature, Value: transaction details
119
+ */
120
+ this.pendingTransactions = new Map();
121
+ /**
122
+ * Track active polling timeout IDs for cleanup
123
+ */
124
+ this.pollingTimeouts = new Set();
125
+ /**
126
+ * Flag to prevent new polls after cleanup is initiated
127
+ */
128
+ this.isCleanedUp = false;
129
+ this.formo = formoAnalytics;
130
+ this.wallet = options.wallet || null;
131
+ this.connection = options.connection || null;
132
+ this.cluster = options.cluster || "mainnet-beta";
133
+ this.chainId = types_1.SOLANA_CHAIN_IDS[this.cluster];
134
+ logger_1.logger.info("SolanaAdapter: Initializing Solana integration", {
135
+ cluster: this.cluster,
136
+ chainId: this.chainId,
137
+ hasWallet: !!this.wallet,
138
+ hasConnection: !!this.connection,
139
+ });
140
+ if (this.wallet) {
141
+ this.setupWalletListeners();
142
+ }
143
+ }
144
+ /**
145
+ * Restore original methods on the wrapped adapter
146
+ */
147
+ SolanaAdapter.prototype.restoreOriginalMethods = function () {
148
+ // Restore adapter methods
149
+ if (this.wrappedAdapter) {
150
+ if (this.originalAdapterSendTransaction) {
151
+ this.wrappedAdapter.sendTransaction = this.originalAdapterSendTransaction;
152
+ }
153
+ if (this.originalAdapterSignMessage) {
154
+ this.wrappedAdapter.signMessage = this.originalAdapterSignMessage;
155
+ }
156
+ if (this.originalAdapterSignTransaction) {
157
+ this.wrappedAdapter.signTransaction = this.originalAdapterSignTransaction;
158
+ }
159
+ this.wrappedAdapter = undefined;
160
+ }
161
+ // Clear original and bound wrapper references
162
+ this.originalAdapterSendTransaction = undefined;
163
+ this.originalAdapterSignMessage = undefined;
164
+ this.originalAdapterSignTransaction = undefined;
165
+ this.boundWrappedSendTransaction = undefined;
166
+ this.boundWrappedSignMessage = undefined;
167
+ this.boundWrappedSignTransaction = undefined;
168
+ };
169
+ /**
170
+ * Update the wallet instance (useful for React context updates)
171
+ */
172
+ SolanaAdapter.prototype.setWallet = function (wallet) {
173
+ // For context-based wallets, if the inner adapter hasn't changed,
174
+ // just update the context reference without tearing down wrapping.
175
+ // This prevents React re-renders from clearing our method wraps.
176
+ if (wallet &&
177
+ (0, types_1.isSolanaWalletContext)(wallet) &&
178
+ this.wallet &&
179
+ (0, types_1.isSolanaWalletContext)(this.wallet)) {
180
+ var newAdapter = this.getAdapterFromContext(wallet);
181
+ if (newAdapter && newAdapter === this.wrappedAdapter) {
182
+ // Same adapter, just update the context reference
183
+ this.wallet = wallet;
184
+ return;
185
+ }
186
+ }
187
+ // For raw adapters, skip teardown if it's the same object
188
+ if (wallet && wallet === this.wrappedAdapter) {
189
+ return;
190
+ }
191
+ // Restore original methods on previous wallet before cleaning up
192
+ this.restoreOriginalMethods();
193
+ // Clear stale connection state to prevent the old adapter's
194
+ // address/chainId from leaking into disconnect events
195
+ this.connectionState.lastAddress = undefined;
196
+ this.connectionState.lastChainId = undefined;
197
+ // Clean up previous wallet listeners
198
+ this.cleanupWalletListeners();
199
+ this.wallet = wallet;
200
+ if (this.wallet) {
201
+ // Reset cleanup flag when setting a new wallet to enable polling
202
+ this.isCleanedUp = false;
203
+ this.setupWalletListeners();
204
+ }
205
+ };
206
+ /**
207
+ * Check if the wallet adapter has changed (for context-based wallets) and rebind if needed.
208
+ * Call this in React effects when you know the wallet context may have changed but the
209
+ * context object reference stayed the same (e.g., user switched wallets in the wallet selector).
210
+ *
211
+ * This ensures connect/disconnect events from the new wallet are properly tracked without
212
+ * waiting for the next transaction or signature call.
213
+ *
214
+ * @example
215
+ * ```tsx
216
+ * const wallet = useWallet();
217
+ * useEffect(() => {
218
+ * formo.solana.syncWalletState();
219
+ * }, [wallet.wallet]); // Trigger when inner wallet changes
220
+ * ```
221
+ */
222
+ SolanaAdapter.prototype.syncWalletState = function () {
223
+ this.checkAndRebindContextAdapter();
224
+ };
225
+ /**
226
+ * Update the connection instance
227
+ */
228
+ SolanaAdapter.prototype.setConnection = function (connection) {
229
+ this.connection = connection;
230
+ };
231
+ /**
232
+ * Update the cluster/network
233
+ */
234
+ SolanaAdapter.prototype.setCluster = function (cluster) {
235
+ var previousCluster = this.cluster;
236
+ this.cluster = cluster;
237
+ this.chainId = types_1.SOLANA_CHAIN_IDS[cluster];
238
+ // Update connectionState and emit chain event if connected and cluster changed
239
+ if (previousCluster !== cluster && this.connectionState.lastAddress) {
240
+ // Always update connectionState to keep lastChainId in sync for future disconnect events
241
+ this.connectionState.lastChainId = this.chainId;
242
+ if (this.formo.isAutocaptureEnabled("chain")) {
243
+ this.formo.chain({
244
+ chainId: this.chainId,
245
+ address: this.connectionState.lastAddress,
246
+ }).catch(function (error) {
247
+ logger_1.logger.error("SolanaAdapter: Error emitting chain event", error);
248
+ });
249
+ }
250
+ }
251
+ };
252
+ /**
253
+ * Get the current chain ID
254
+ */
255
+ SolanaAdapter.prototype.getChainId = function () {
256
+ return this.chainId;
257
+ };
258
+ /**
259
+ * Set up listeners for wallet events
260
+ */
261
+ SolanaAdapter.prototype.setupWalletListeners = function () {
262
+ if (!this.wallet) {
263
+ return;
264
+ }
265
+ logger_1.logger.info("SolanaAdapter: Setting up wallet listeners");
266
+ // Handle both WalletContext (from useWallet) and direct WalletAdapter
267
+ if ((0, types_1.isSolanaWalletContext)(this.wallet)) {
268
+ this.setupContextListeners(this.wallet);
269
+ }
270
+ else if ((0, types_1.isSolanaAdapter)(this.wallet)) {
271
+ this.setupAdapterListeners(this.wallet);
272
+ }
273
+ // Check if already connected
274
+ this.checkInitialConnection().catch(function (error) {
275
+ logger_1.logger.error("SolanaAdapter: Error checking initial connection", error);
276
+ });
277
+ logger_1.logger.info("SolanaAdapter: Wallet listeners set up successfully");
278
+ };
279
+ /**
280
+ * Set up listeners for a wallet context (useWallet)
281
+ */
282
+ SolanaAdapter.prototype.setupContextListeners = function (context) {
283
+ // The wallet-adapter-react useWallet() returns wallet as { adapter, readyState },
284
+ // so we need to extract the actual adapter which has .on()/.off() methods.
285
+ //
286
+ // IMPORTANT: We wrap methods on the adapter (not the context) because
287
+ // useWallet() returns a new object reference on each render. Components
288
+ // that call useWallet() independently get their own sendTransaction/signMessage
289
+ // callbacks that delegate to adapter.sendTransaction/adapter.signMessage.
290
+ // Wrapping the context object only mutates the FormoProvider's reference,
291
+ // not what other components receive from useWallet().
292
+ var adapter = this.getAdapterFromContext(context);
293
+ if (adapter) {
294
+ this.setupAdapterEventListenersOnly(adapter);
295
+ // Wrap adapter methods so all components using useWallet() are tracked
296
+ this.wrapAdapterMethods(adapter);
297
+ }
298
+ };
299
+ /**
300
+ * Check if the adapter inside a wallet context has changed (e.g., user switched wallets).
301
+ * If so, rebind event listeners and rewrap methods on the new adapter.
302
+ * This handles the case where context.wallet changes but the context object reference stays the same.
303
+ */
304
+ SolanaAdapter.prototype.checkAndRebindContextAdapter = function () {
305
+ if (!this.wallet || !(0, types_1.isSolanaWalletContext)(this.wallet)) {
306
+ return;
307
+ }
308
+ var currentAdapter = this.getAdapterFromContext(this.wallet);
309
+ // If adapter changed, rebind listeners and rewrap methods
310
+ if (currentAdapter !== this.currentBoundAdapter) {
311
+ logger_1.logger.info("SolanaAdapter: Detected wallet adapter change, rebinding");
312
+ // Restore methods on old adapter and clean up listeners
313
+ this.restoreOriginalMethods();
314
+ this.cleanupAdapterListenersOnly();
315
+ // Set up on new adapter
316
+ if (currentAdapter) {
317
+ this.setupAdapterEventListenersOnly(currentAdapter);
318
+ this.wrapAdapterMethods(currentAdapter);
319
+ // Check if new adapter is already connected
320
+ this.checkInitialConnection().catch(function (error) {
321
+ logger_1.logger.error("SolanaAdapter: Error checking initial connection after adapter change", error);
322
+ });
323
+ }
324
+ else {
325
+ // No adapter means disconnected
326
+ this.currentBoundAdapter = undefined;
327
+ if (this.connectionState.lastAddress) {
328
+ this.handleDisconnect();
329
+ }
330
+ }
331
+ }
332
+ };
333
+ /**
334
+ * Clean up only adapter event listeners (not the full cleanup)
335
+ */
336
+ SolanaAdapter.prototype.cleanupAdapterListenersOnly = function () {
337
+ for (var _i = 0, _a = this.unsubscribers; _i < _a.length; _i++) {
338
+ var unsubscribe = _a[_i];
339
+ try {
340
+ unsubscribe();
341
+ }
342
+ catch (error) {
343
+ logger_1.logger.error("SolanaAdapter: Error cleaning up adapter listener", error);
344
+ }
345
+ }
346
+ this.unsubscribers = [];
347
+ this.currentBoundAdapter = undefined;
348
+ };
349
+ /**
350
+ * Register a listener on an adapter and track its unsubscriber
351
+ */
352
+ SolanaAdapter.prototype.registerAdapterListener = function (adapter, event, handler) {
353
+ // Use 'any' cast to handle the overloaded on/off signatures
354
+ adapter.on(event, handler);
355
+ this.unsubscribers.push(function () { return adapter.off(event, handler); });
356
+ };
357
+ /**
358
+ * Set up event listeners on an adapter (connect/disconnect events)
359
+ */
360
+ SolanaAdapter.prototype.setupAdapterEventListenersOnly = function (adapter) {
361
+ var _this = this;
362
+ this.currentBoundAdapter = adapter;
363
+ this.registerAdapterListener(adapter, "connect", function (publicKey) {
364
+ return _this.handleConnect(publicKey);
365
+ });
366
+ this.registerAdapterListener(adapter, "disconnect", function () {
367
+ return _this.handleDisconnect();
368
+ });
369
+ this.registerAdapterListener(adapter, "error", function (error) {
370
+ return logger_1.logger.error("SolanaAdapter: Wallet error", error);
371
+ });
372
+ };
373
+ /**
374
+ * Set up listeners for a direct wallet adapter
375
+ */
376
+ SolanaAdapter.prototype.setupAdapterListeners = function (adapter) {
377
+ this.setupAdapterEventListenersOnly(adapter);
378
+ this.wrapAdapterMethods(adapter);
379
+ };
380
+ /**
381
+ * Wrap wallet adapter methods for transaction/signature tracking
382
+ */
383
+ SolanaAdapter.prototype.wrapAdapterMethods = function (adapter) {
384
+ // If we already wrapped this adapter, check if our wraps are still in place.
385
+ // StandardWalletAdapter._reset() overwrites signMessage/signTransaction
386
+ // on every connect/disconnect/feature-change, so we need to re-wrap those methods.
387
+ if (this.wrappedAdapter === adapter) {
388
+ this.rewrapOverwrittenMethods(adapter);
389
+ return;
390
+ }
391
+ // Store reference to adapter for cleanup
392
+ this.wrappedAdapter = adapter;
393
+ // Wrap sendTransaction
394
+ if (adapter.sendTransaction) {
395
+ this.originalAdapterSendTransaction = adapter.sendTransaction.bind(adapter);
396
+ this.boundWrappedSendTransaction = this.wrappedSendTransaction.bind(this);
397
+ adapter.sendTransaction = this.boundWrappedSendTransaction;
398
+ }
399
+ // Wrap signMessage
400
+ if (adapter.signMessage) {
401
+ this.originalAdapterSignMessage = adapter.signMessage.bind(adapter);
402
+ this.boundWrappedSignMessage = this.wrappedSignMessage.bind(this);
403
+ adapter.signMessage = this.boundWrappedSignMessage;
404
+ }
405
+ // Wrap signTransaction
406
+ if (adapter.signTransaction) {
407
+ this.originalAdapterSignTransaction = adapter.signTransaction.bind(adapter);
408
+ this.boundWrappedSignTransaction = this.wrappedSignTransaction.bind(this);
409
+ adapter.signTransaction = this.boundWrappedSignTransaction;
410
+ }
411
+ };
412
+ /**
413
+ * Re-wrap methods that were overwritten by external code.
414
+ *
415
+ * StandardWalletAdapter._reset() overwrites signMessage and signTransaction
416
+ * as own properties on every connect/disconnect/
417
+ * feature-change event. This method detects which wraps were overwritten
418
+ * and re-applies them, capturing the new original methods.
419
+ */
420
+ SolanaAdapter.prototype.rewrapOverwrittenMethods = function (adapter) {
421
+ var rewrapped = false;
422
+ // signMessage
423
+ if (adapter.signMessage && adapter.signMessage !== this.boundWrappedSignMessage) {
424
+ this.originalAdapterSignMessage = adapter.signMessage.bind(adapter);
425
+ if (!this.boundWrappedSignMessage) {
426
+ this.boundWrappedSignMessage = this.wrappedSignMessage.bind(this);
427
+ }
428
+ adapter.signMessage = this.boundWrappedSignMessage;
429
+ rewrapped = true;
430
+ }
431
+ else if (!adapter.signMessage && this.boundWrappedSignMessage) {
432
+ this.originalAdapterSignMessage = undefined;
433
+ }
434
+ // signTransaction
435
+ if (adapter.signTransaction && adapter.signTransaction !== this.boundWrappedSignTransaction) {
436
+ this.originalAdapterSignTransaction = adapter.signTransaction.bind(adapter);
437
+ if (!this.boundWrappedSignTransaction) {
438
+ this.boundWrappedSignTransaction = this.wrappedSignTransaction.bind(this);
439
+ }
440
+ adapter.signTransaction = this.boundWrappedSignTransaction;
441
+ rewrapped = true;
442
+ }
443
+ else if (!adapter.signTransaction && this.boundWrappedSignTransaction) {
444
+ this.originalAdapterSignTransaction = undefined;
445
+ }
446
+ // sendTransaction — unlikely to be overwritten but check for completeness
447
+ if (adapter.sendTransaction && adapter.sendTransaction !== this.boundWrappedSendTransaction) {
448
+ this.originalAdapterSendTransaction = adapter.sendTransaction.bind(adapter);
449
+ if (!this.boundWrappedSendTransaction) {
450
+ this.boundWrappedSendTransaction = this.wrappedSendTransaction.bind(this);
451
+ }
452
+ adapter.sendTransaction = this.boundWrappedSendTransaction;
453
+ rewrapped = true;
454
+ }
455
+ if (rewrapped) {
456
+ logger_1.logger.debug("SolanaAdapter: Re-wrapped overwritten adapter methods");
457
+ }
458
+ };
459
+ /**
460
+ * Wrapped sendTransaction method for direct adapter
461
+ */
462
+ SolanaAdapter.prototype.wrappedSendTransaction = function (transaction, connection, options) {
463
+ return __awaiter(this, void 0, void 0, function () {
464
+ var chainId, address, signature, error_1;
465
+ return __generator(this, function (_a) {
466
+ switch (_a.label) {
467
+ case 0:
468
+ this.checkAndRebindContextAdapter();
469
+ if (!this.originalAdapterSendTransaction) {
470
+ throw new Error("sendTransaction not available");
471
+ }
472
+ chainId = this.chainId;
473
+ address = this.getCurrentAddress();
474
+ this.emitTransactionEvent(events_1.TransactionStatus.STARTED, address, chainId);
475
+ _a.label = 1;
476
+ case 1:
477
+ _a.trys.push([1, 3, , 4]);
478
+ return [4 /*yield*/, this.originalAdapterSendTransaction(transaction, connection, options)];
479
+ case 2:
480
+ signature = _a.sent();
481
+ this.emitTransactionEvent(events_1.TransactionStatus.BROADCASTED, address, chainId, signature);
482
+ if (address && this.formo.isAutocaptureEnabled("transaction")) {
483
+ this.pendingTransactions.set(signature, {
484
+ address: address,
485
+ startTime: Date.now(),
486
+ });
487
+ this.pollTransactionConfirmation(signature, address, chainId, connection);
488
+ }
489
+ return [2 /*return*/, signature];
490
+ case 3:
491
+ error_1 = _a.sent();
492
+ this.emitTransactionEvent(events_1.TransactionStatus.REJECTED, address, chainId);
493
+ throw error_1;
494
+ case 4: return [2 /*return*/];
495
+ }
496
+ });
497
+ });
498
+ };
499
+ /**
500
+ * Wrapped signMessage method for direct adapter
501
+ */
502
+ SolanaAdapter.prototype.wrappedSignMessage = function (message) {
503
+ return __awaiter(this, void 0, void 0, function () {
504
+ var chainId, address, messageString, signature, signatureHex, error_2;
505
+ return __generator(this, function (_a) {
506
+ switch (_a.label) {
507
+ case 0:
508
+ this.checkAndRebindContextAdapter();
509
+ if (!this.originalAdapterSignMessage) {
510
+ throw new Error("signMessage not available");
511
+ }
512
+ chainId = this.chainId;
513
+ address = this.getCurrentAddress();
514
+ messageString = safeDecodeMessage(message);
515
+ this.emitSignatureEvent(events_1.SignatureStatus.REQUESTED, address, chainId, messageString);
516
+ _a.label = 1;
517
+ case 1:
518
+ _a.trys.push([1, 3, , 4]);
519
+ return [4 /*yield*/, this.originalAdapterSignMessage(message)];
520
+ case 2:
521
+ signature = _a.sent();
522
+ signatureHex = uint8ArrayToHex(signature);
523
+ this.emitSignatureEvent(events_1.SignatureStatus.CONFIRMED, address, chainId, messageString, signatureHex);
524
+ return [2 /*return*/, signature];
525
+ case 3:
526
+ error_2 = _a.sent();
527
+ this.emitSignatureEvent(events_1.SignatureStatus.REJECTED, address, chainId, messageString);
528
+ throw error_2;
529
+ case 4: return [2 /*return*/];
530
+ }
531
+ });
532
+ });
533
+ };
534
+ /**
535
+ * Wrapped signTransaction method for direct adapter
536
+ */
537
+ SolanaAdapter.prototype.wrappedSignTransaction = function (transaction) {
538
+ return __awaiter(this, void 0, void 0, function () {
539
+ var chainId, address, message, signedTx, error_3;
540
+ return __generator(this, function (_a) {
541
+ switch (_a.label) {
542
+ case 0:
543
+ this.checkAndRebindContextAdapter();
544
+ if (!this.originalAdapterSignTransaction) {
545
+ throw new Error("signTransaction not available");
546
+ }
547
+ chainId = this.chainId;
548
+ address = this.getCurrentAddress();
549
+ message = "[Transaction Signature]";
550
+ this.emitSignatureEvent(events_1.SignatureStatus.REQUESTED, address, chainId, message);
551
+ _a.label = 1;
552
+ case 1:
553
+ _a.trys.push([1, 3, , 4]);
554
+ return [4 /*yield*/, this.originalAdapterSignTransaction(transaction)];
555
+ case 2:
556
+ signedTx = _a.sent();
557
+ this.emitSignatureEvent(events_1.SignatureStatus.CONFIRMED, address, chainId, message);
558
+ return [2 /*return*/, signedTx];
559
+ case 3:
560
+ error_3 = _a.sent();
561
+ this.emitSignatureEvent(events_1.SignatureStatus.REJECTED, address, chainId, message);
562
+ throw error_3;
563
+ case 4: return [2 /*return*/];
564
+ }
565
+ });
566
+ });
567
+ };
568
+ /**
569
+ * Check initial connection state
570
+ */
571
+ SolanaAdapter.prototype.checkInitialConnection = function () {
572
+ return __awaiter(this, void 0, void 0, function () {
573
+ var publicKey, address;
574
+ return __generator(this, function (_a) {
575
+ switch (_a.label) {
576
+ case 0:
577
+ publicKey = this.getPublicKey();
578
+ if (!publicKey) return [3 /*break*/, 2];
579
+ address = (0, address_1.publicKeyToAddress)(publicKey);
580
+ if (!(address && !(0, address_1.isBlockedSolanaAddress)(address))) return [3 /*break*/, 2];
581
+ // Skip if we already tracked this address to avoid duplicate connect events
582
+ // (e.g., when setWallet is called repeatedly with the same connected wallet)
583
+ if (this.connectionState.lastAddress === address &&
584
+ this.connectionState.lastChainId === this.chainId) {
585
+ logger_1.logger.debug("SolanaAdapter: Already tracking this address, skipping duplicate connect", { address: address, chainId: this.chainId });
586
+ return [2 /*return*/];
587
+ }
588
+ this.connectionState.lastAddress = address;
589
+ this.connectionState.lastChainId = this.chainId;
590
+ logger_1.logger.info("SolanaAdapter: Already connected on initialization", {
591
+ address: address,
592
+ chainId: this.chainId,
593
+ });
594
+ if (!this.formo.isAutocaptureEnabled("connect")) return [3 /*break*/, 2];
595
+ return [4 /*yield*/, this.formo.connect({
596
+ chainId: this.chainId,
597
+ address: address,
598
+ }, {
599
+ providerName: this.getWalletName(),
600
+ rdns: this.getWalletRdns(),
601
+ })];
602
+ case 1:
603
+ _a.sent();
604
+ _a.label = 2;
605
+ case 2: return [2 /*return*/];
606
+ }
607
+ });
608
+ });
609
+ };
610
+ /**
611
+ * Handle wallet connect event
612
+ */
613
+ SolanaAdapter.prototype.handleConnect = function (publicKey) {
614
+ return __awaiter(this, void 0, void 0, function () {
615
+ var address, error_4;
616
+ return __generator(this, function (_a) {
617
+ switch (_a.label) {
618
+ case 0:
619
+ if (this.connectionState.isProcessing) {
620
+ logger_1.logger.debug("SolanaAdapter: Already processing, skipping connect");
621
+ return [2 /*return*/];
622
+ }
623
+ this.connectionState.isProcessing = true;
624
+ _a.label = 1;
625
+ case 1:
626
+ _a.trys.push([1, 4, 5, 6]);
627
+ // Re-wrap methods that may have been overwritten.
628
+ // StandardWalletAdapter._reset() runs before emitting "connect",
629
+ // so signMessage/signTransaction may have been
630
+ // replaced with new own properties by the time we get here.
631
+ if (this.wrappedAdapter) {
632
+ this.rewrapOverwrittenMethods(this.wrappedAdapter);
633
+ }
634
+ address = (0, address_1.publicKeyToAddress)(publicKey);
635
+ if (!address) {
636
+ logger_1.logger.warn("SolanaAdapter: Invalid public key on connect");
637
+ return [2 /*return*/];
638
+ }
639
+ if ((0, address_1.isBlockedSolanaAddress)(address)) {
640
+ logger_1.logger.debug("SolanaAdapter: Blocked address, skipping connect event");
641
+ return [2 /*return*/];
642
+ }
643
+ logger_1.logger.info("SolanaAdapter: Wallet connected", {
644
+ address: address,
645
+ chainId: this.chainId,
646
+ walletName: this.getWalletName(),
647
+ });
648
+ this.connectionState.lastAddress = address;
649
+ this.connectionState.lastChainId = this.chainId;
650
+ if (!this.formo.isAutocaptureEnabled("connect")) return [3 /*break*/, 3];
651
+ return [4 /*yield*/, this.formo.connect({
652
+ chainId: this.chainId,
653
+ address: address,
654
+ }, {
655
+ providerName: this.getWalletName(),
656
+ rdns: this.getWalletRdns(),
657
+ })];
658
+ case 2:
659
+ _a.sent();
660
+ _a.label = 3;
661
+ case 3: return [3 /*break*/, 6];
662
+ case 4:
663
+ error_4 = _a.sent();
664
+ logger_1.logger.error("SolanaAdapter: Error handling connect", error_4);
665
+ return [3 /*break*/, 6];
666
+ case 5:
667
+ this.connectionState.isProcessing = false;
668
+ return [7 /*endfinally*/];
669
+ case 6: return [2 /*return*/];
670
+ }
671
+ });
672
+ });
673
+ };
674
+ /**
675
+ * Handle wallet disconnect event
676
+ */
677
+ SolanaAdapter.prototype.handleDisconnect = function () {
678
+ return __awaiter(this, void 0, void 0, function () {
679
+ var error_5;
680
+ return __generator(this, function (_a) {
681
+ switch (_a.label) {
682
+ case 0:
683
+ if (this.connectionState.isProcessing) {
684
+ logger_1.logger.debug("SolanaAdapter: Already processing, skipping disconnect");
685
+ return [2 /*return*/];
686
+ }
687
+ // Only emit disconnect if we have a prior tracked connection
688
+ // This prevents emitting events with undefined address/chainId
689
+ if (!this.connectionState.lastAddress) {
690
+ logger_1.logger.debug("SolanaAdapter: No prior connection tracked, skipping disconnect event");
691
+ return [2 /*return*/];
692
+ }
693
+ this.connectionState.isProcessing = true;
694
+ _a.label = 1;
695
+ case 1:
696
+ _a.trys.push([1, 4, 5, 6]);
697
+ logger_1.logger.info("SolanaAdapter: Wallet disconnected", {
698
+ address: this.connectionState.lastAddress,
699
+ chainId: this.connectionState.lastChainId,
700
+ });
701
+ if (!this.formo.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 3];
702
+ return [4 /*yield*/, this.formo.disconnect({
703
+ chainId: this.connectionState.lastChainId,
704
+ address: this.connectionState.lastAddress,
705
+ })];
706
+ case 2:
707
+ _a.sent();
708
+ _a.label = 3;
709
+ case 3:
710
+ this.connectionState.lastAddress = undefined;
711
+ this.connectionState.lastChainId = undefined;
712
+ return [3 /*break*/, 6];
713
+ case 4:
714
+ error_5 = _a.sent();
715
+ logger_1.logger.error("SolanaAdapter: Error handling disconnect", error_5);
716
+ return [3 /*break*/, 6];
717
+ case 5:
718
+ this.connectionState.isProcessing = false;
719
+ return [7 /*endfinally*/];
720
+ case 6: return [2 /*return*/];
721
+ }
722
+ });
723
+ });
724
+ };
725
+ /**
726
+ * Poll for transaction confirmation
727
+ */
728
+ SolanaAdapter.prototype.pollTransactionConfirmation = function (signature_1, address_2, chainId_1, connection_1) {
729
+ return __awaiter(this, arguments, void 0, function (signature, address, chainId, connection, maxAttempts, intervalMs) {
730
+ var conn, attempts, currentTimeoutId, poll;
731
+ var _this = this;
732
+ if (maxAttempts === void 0) { maxAttempts = 30; }
733
+ if (intervalMs === void 0) { intervalMs = 2000; }
734
+ return __generator(this, function (_a) {
735
+ // Don't start polling if already cleaned up
736
+ if (this.isCleanedUp) {
737
+ return [2 /*return*/];
738
+ }
739
+ conn = connection || this.connection;
740
+ // Prefer getSignatureStatuses (standard web3.js API) over getSignatureStatus (custom wrapper)
741
+ if (!conn || (!conn.getSignatureStatuses && !conn.getSignatureStatus)) {
742
+ logger_1.logger.debug("SolanaAdapter: No connection for confirmation polling");
743
+ // Clean up pendingTransactions entry since we can't poll for confirmation
744
+ this.pendingTransactions.delete(signature);
745
+ return [2 /*return*/];
746
+ }
747
+ attempts = 0;
748
+ currentTimeoutId = null;
749
+ poll = function () { return __awaiter(_this, void 0, void 0, function () {
750
+ var status_1, result, result, signatureKey, isTerminalState, error_6;
751
+ return __generator(this, function (_a) {
752
+ switch (_a.label) {
753
+ case 0:
754
+ // Remove the current timeout ID from tracking since it has fired
755
+ if (currentTimeoutId) {
756
+ this.pollingTimeouts.delete(currentTimeoutId);
757
+ currentTimeoutId = null;
758
+ }
759
+ // Stop polling if cleaned up
760
+ if (this.isCleanedUp) {
761
+ this.pendingTransactions.delete(signature);
762
+ return [2 /*return*/];
763
+ }
764
+ _a.label = 1;
765
+ case 1:
766
+ _a.trys.push([1, 6, , 7]);
767
+ status_1 = null;
768
+ if (!conn.getSignatureStatuses) return [3 /*break*/, 3];
769
+ return [4 /*yield*/, conn.getSignatureStatuses([signature])];
770
+ case 2:
771
+ result = _a.sent();
772
+ status_1 = result.value[0];
773
+ return [3 /*break*/, 5];
774
+ case 3:
775
+ if (!conn.getSignatureStatus) return [3 /*break*/, 5];
776
+ return [4 /*yield*/, conn.getSignatureStatus(signature)];
777
+ case 4:
778
+ result = _a.sent();
779
+ status_1 = result.value;
780
+ _a.label = 5;
781
+ case 5:
782
+ if (status_1) {
783
+ signatureKey = "".concat(signature, ":").concat(status_1.confirmationStatus);
784
+ isTerminalState = !!status_1.err ||
785
+ status_1.confirmationStatus === "confirmed" ||
786
+ status_1.confirmationStatus === "finalized";
787
+ // Check for duplicate processing of terminal states only
788
+ if (isTerminalState && this.processedSignatures.has(signatureKey)) {
789
+ return [2 /*return*/];
790
+ }
791
+ if (isTerminalState) {
792
+ this.processedSignatures.add(signatureKey);
793
+ }
794
+ if (status_1.err) {
795
+ // Transaction failed
796
+ logger_1.logger.info("SolanaAdapter: Transaction reverted", {
797
+ signature: signature,
798
+ error: status_1.err,
799
+ });
800
+ this.formo.transaction({
801
+ status: events_1.TransactionStatus.REVERTED,
802
+ chainId: chainId,
803
+ address: address,
804
+ transactionHash: signature,
805
+ });
806
+ this.pendingTransactions.delete(signature);
807
+ return [2 /*return*/];
808
+ }
809
+ if (status_1.confirmationStatus === "confirmed" ||
810
+ status_1.confirmationStatus === "finalized") {
811
+ // Transaction confirmed
812
+ logger_1.logger.info("SolanaAdapter: Transaction confirmed", {
813
+ signature: signature,
814
+ confirmationStatus: status_1.confirmationStatus,
815
+ });
816
+ this.formo.transaction({
817
+ status: events_1.TransactionStatus.CONFIRMED,
818
+ chainId: chainId,
819
+ address: address,
820
+ transactionHash: signature,
821
+ });
822
+ this.pendingTransactions.delete(signature);
823
+ return [2 /*return*/];
824
+ }
825
+ }
826
+ return [3 /*break*/, 7];
827
+ case 6:
828
+ error_6 = _a.sent();
829
+ logger_1.logger.error("SolanaAdapter: Error polling transaction status", error_6);
830
+ return [3 /*break*/, 7];
831
+ case 7:
832
+ attempts++;
833
+ if (attempts < maxAttempts && !this.isCleanedUp) {
834
+ currentTimeoutId = setTimeout(poll, intervalMs);
835
+ this.pollingTimeouts.add(currentTimeoutId);
836
+ }
837
+ else {
838
+ // Cleanup after max attempts
839
+ this.pendingTransactions.delete(signature);
840
+ }
841
+ return [2 /*return*/];
842
+ }
843
+ });
844
+ }); };
845
+ // Start polling
846
+ currentTimeoutId = setTimeout(poll, intervalMs);
847
+ this.pollingTimeouts.add(currentTimeoutId);
848
+ // Clean up old processed signatures
849
+ cleanupOldEntries(this.processedSignatures);
850
+ return [2 /*return*/];
851
+ });
852
+ });
853
+ };
854
+ /**
855
+ * Get current wallet public key
856
+ */
857
+ SolanaAdapter.prototype.getPublicKey = function () {
858
+ var _a, _b;
859
+ return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.publicKey) !== null && _b !== void 0 ? _b : null;
860
+ };
861
+ /**
862
+ * Get current address
863
+ */
864
+ SolanaAdapter.prototype.getCurrentAddress = function () {
865
+ // First check tracking state
866
+ if (this.connectionState.lastAddress) {
867
+ return this.connectionState.lastAddress;
868
+ }
869
+ // Then check wallet, filtering out blocked addresses (system programs, etc.)
870
+ var publicKey = this.getPublicKey();
871
+ var address = publicKey ? (0, address_1.publicKeyToAddress)(publicKey) : null;
872
+ if (address && (0, address_1.isBlockedSolanaAddress)(address)) {
873
+ return null;
874
+ }
875
+ return address;
876
+ };
877
+ // ============================================================
878
+ // Event Emission Helpers
879
+ // ============================================================
880
+ /**
881
+ * Emit a transaction event if address is valid and autocapture is enabled
882
+ */
883
+ SolanaAdapter.prototype.emitTransactionEvent = function (status, address, chainId, transactionHash) {
884
+ if (address && this.formo.isAutocaptureEnabled("transaction")) {
885
+ this.formo.transaction(__assign({ status: status, chainId: chainId, address: address }, (transactionHash && { transactionHash: transactionHash })));
886
+ }
887
+ };
888
+ /**
889
+ * Emit a signature event if address is valid and autocapture is enabled
890
+ */
891
+ SolanaAdapter.prototype.emitSignatureEvent = function (status, address, chainId, message, signatureHash) {
892
+ if (address && this.formo.isAutocaptureEnabled("signature")) {
893
+ this.formo.signature(__assign({ status: status, chainId: chainId, address: address, message: message }, (signatureHash && { signatureHash: signatureHash })));
894
+ }
895
+ };
896
+ /**
897
+ * Extract the actual adapter (with .on/.off) from a wallet context.
898
+ * In @solana/wallet-adapter-react, context.wallet is { adapter, readyState },
899
+ * not a direct adapter.
900
+ */
901
+ SolanaAdapter.prototype.getAdapterFromContext = function (context) {
902
+ var wallet = context.wallet;
903
+ if (!wallet)
904
+ return null;
905
+ // wallet-adapter-react: wallet is { adapter, readyState }
906
+ if (wallet.adapter && typeof wallet.adapter.on === "function") {
907
+ return wallet.adapter;
908
+ }
909
+ return null;
910
+ };
911
+ /**
912
+ * Get wallet name
913
+ */
914
+ SolanaAdapter.prototype.getWalletName = function () {
915
+ if (!this.wallet) {
916
+ return "Unknown Solana Wallet";
917
+ }
918
+ if ((0, types_1.isSolanaWalletContext)(this.wallet)) {
919
+ var adapter = this.getAdapterFromContext(this.wallet);
920
+ return (adapter === null || adapter === void 0 ? void 0 : adapter.name) || "Unknown Solana Wallet";
921
+ }
922
+ return this.wallet.name;
923
+ };
924
+ /**
925
+ * Get wallet RDNS (reverse domain name)
926
+ * For Solana wallets, we construct an RDNS-like identifier
927
+ */
928
+ SolanaAdapter.prototype.getWalletRdns = function () {
929
+ var name = this.getWalletName().toLowerCase().replace(/\s+/g, "");
930
+ return "sol.wallet.".concat(name);
931
+ };
932
+ /**
933
+ * Clean up wallet listeners
934
+ */
935
+ SolanaAdapter.prototype.cleanupWalletListeners = function () {
936
+ for (var _i = 0, _a = this.unsubscribers; _i < _a.length; _i++) {
937
+ var unsubscribe = _a[_i];
938
+ try {
939
+ unsubscribe();
940
+ }
941
+ catch (error) {
942
+ logger_1.logger.error("SolanaAdapter: Error during listener cleanup", error);
943
+ }
944
+ }
945
+ this.unsubscribers = [];
946
+ this.currentBoundAdapter = undefined;
947
+ };
948
+ /**
949
+ * Clean up all resources
950
+ */
951
+ SolanaAdapter.prototype.cleanup = function () {
952
+ logger_1.logger.debug("SolanaAdapter: Cleaning up");
953
+ // Set cleanup flag to stop any ongoing polls
954
+ this.isCleanedUp = true;
955
+ // Cancel all active polling timeouts
956
+ Array.from(this.pollingTimeouts).forEach(function (timeoutId) {
957
+ clearTimeout(timeoutId);
958
+ });
959
+ this.pollingTimeouts.clear();
960
+ this.cleanupWalletListeners();
961
+ this.processedSignatures.clear();
962
+ this.pendingTransactions.clear();
963
+ // Clear connection state to prevent stale data
964
+ this.connectionState.lastAddress = undefined;
965
+ this.connectionState.lastChainId = undefined;
966
+ // Restore original methods on wrapped adapter
967
+ this.restoreOriginalMethods();
968
+ this.wallet = null;
969
+ this.connection = null;
970
+ logger_1.logger.debug("SolanaAdapter: Cleanup complete");
971
+ };
972
+ return SolanaAdapter;
973
+ }());
974
+ exports.SolanaAdapter = SolanaAdapter;
975
+ //# sourceMappingURL=SolanaAdapter.js.map