@formo/analytics 1.28.2 → 1.28.4
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/dist/cjs/src/FormoAnalytics.d.ts +2 -0
- package/dist/cjs/src/FormoAnalytics.js +10 -5
- package/dist/cjs/src/FormoAnalyticsProvider.js +1 -0
- package/dist/cjs/src/consent/index.js +12 -10
- package/dist/cjs/src/event/EventFactory.js +7 -7
- package/dist/cjs/src/event/utils.d.ts +2 -3
- package/dist/cjs/src/event/utils.js +24 -24
- package/dist/cjs/src/queue/EventQueue.d.ts +1 -1
- package/dist/cjs/src/queue/EventQueue.js +21 -20
- package/dist/cjs/src/session/index.d.ts +0 -9
- package/dist/cjs/src/session/index.js +7 -0
- package/dist/cjs/src/solana/SolanaAdapter.d.ts +3 -4
- package/dist/cjs/src/solana/SolanaAdapter.js +42 -29
- package/dist/cjs/src/storage/StorageManager.js +11 -3
- package/dist/cjs/src/storage/built-in/cookie.js +29 -3
- package/dist/cjs/src/storage/cookiePolicy.d.ts +10 -0
- package/dist/cjs/src/storage/cookiePolicy.js +27 -0
- package/dist/cjs/src/types/base.d.ts +12 -0
- package/dist/cjs/src/utils/address.js +4 -6
- package/dist/cjs/src/utils/domain.d.ts +27 -0
- package/dist/cjs/src/utils/domain.js +74 -0
- package/dist/cjs/src/utils/generate.js +23 -11
- package/dist/cjs/src/validators/network.js +7 -2
- package/dist/cjs/src/version.d.ts +1 -1
- package/dist/cjs/src/version.js +1 -1
- package/dist/cjs/src/wagmi/utils.js +0 -1
- package/dist/esm/src/FormoAnalytics.d.ts +2 -0
- package/dist/esm/src/FormoAnalytics.js +10 -5
- package/dist/esm/src/FormoAnalyticsProvider.js +1 -0
- package/dist/esm/src/consent/index.js +12 -10
- package/dist/esm/src/event/EventFactory.js +7 -7
- package/dist/esm/src/event/utils.d.ts +2 -3
- package/dist/esm/src/event/utils.js +25 -24
- package/dist/esm/src/queue/EventQueue.d.ts +1 -1
- package/dist/esm/src/queue/EventQueue.js +21 -20
- package/dist/esm/src/session/index.d.ts +0 -9
- package/dist/esm/src/session/index.js +7 -0
- package/dist/esm/src/solana/SolanaAdapter.d.ts +3 -4
- package/dist/esm/src/solana/SolanaAdapter.js +42 -29
- package/dist/esm/src/storage/StorageManager.js +11 -3
- package/dist/esm/src/storage/built-in/cookie.js +29 -3
- package/dist/esm/src/storage/cookiePolicy.d.ts +10 -0
- package/dist/esm/src/storage/cookiePolicy.js +24 -0
- package/dist/esm/src/types/base.d.ts +12 -0
- package/dist/esm/src/utils/address.js +4 -6
- package/dist/esm/src/utils/domain.d.ts +27 -0
- package/dist/esm/src/utils/domain.js +70 -0
- package/dist/esm/src/utils/generate.js +23 -11
- package/dist/esm/src/validators/network.js +7 -2
- package/dist/esm/src/version.d.ts +1 -1
- package/dist/esm/src/version.js +1 -1
- package/dist/esm/src/wagmi/utils.js +0 -1
- package/dist/index.umd.min.js +1 -1
- package/dist/index.umd.min.js.LICENSE.txt +4 -4
- package/package.json +46 -36
|
@@ -118,12 +118,12 @@ var EventQueue = /** @class */ (function () {
|
|
|
118
118
|
});
|
|
119
119
|
// Catches the page being hidden, including scenarios like closing the tab.
|
|
120
120
|
document.addEventListener("pagehide", function () {
|
|
121
|
-
isAccessible = document.visibilityState
|
|
121
|
+
isAccessible = document.visibilityState !== "hidden";
|
|
122
122
|
handleOnLeave();
|
|
123
123
|
});
|
|
124
124
|
// Catches visibility changes, such as switching tabs or minimizing the browser.
|
|
125
125
|
document.addEventListener("visibilitychange", function () {
|
|
126
|
-
isAccessible =
|
|
126
|
+
isAccessible = document.visibilityState !== "hidden";
|
|
127
127
|
if (document.visibilityState === "hidden") {
|
|
128
128
|
handleOnLeave();
|
|
129
129
|
}
|
|
@@ -149,7 +149,7 @@ var EventQueue = /** @class */ (function () {
|
|
|
149
149
|
switch (_a.label) {
|
|
150
150
|
case 0:
|
|
151
151
|
if (!(isAccessible === false)) return [3 /*break*/, 2];
|
|
152
|
-
return [4 /*yield*/, this.flush()];
|
|
152
|
+
return [4 /*yield*/, this.flush(undefined, true)];
|
|
153
153
|
case 1:
|
|
154
154
|
_a.sent();
|
|
155
155
|
_a.label = 2;
|
|
@@ -179,10 +179,8 @@ var EventQueue = /** @class */ (function () {
|
|
|
179
179
|
return [4 /*yield*/, this.generateMessageId(event)];
|
|
180
180
|
case 1:
|
|
181
181
|
message_id = _a.sent();
|
|
182
|
-
return [4 /*yield*/, this.isDuplicate(message_id)];
|
|
183
|
-
case 2:
|
|
184
182
|
// check if the message already exists
|
|
185
|
-
if (
|
|
183
|
+
if (this.isDuplicate(message_id)) {
|
|
186
184
|
logger.warn("Event already enqueued, try again after ".concat(millisecondsToSecond(this.flushIntervalMs), " seconds."));
|
|
187
185
|
return [2 /*return*/];
|
|
188
186
|
}
|
|
@@ -211,10 +209,11 @@ var EventQueue = /** @class */ (function () {
|
|
|
211
209
|
});
|
|
212
210
|
});
|
|
213
211
|
};
|
|
214
|
-
EventQueue.prototype.flush = function (
|
|
215
|
-
return __awaiter(this,
|
|
216
|
-
var items, sentAt, data, batches;
|
|
212
|
+
EventQueue.prototype.flush = function (callback_1) {
|
|
213
|
+
return __awaiter(this, arguments, void 0, function (callback, drainAll) {
|
|
214
|
+
var items, _i, items_1, item, sentAt, data, batches;
|
|
217
215
|
var _this = this;
|
|
216
|
+
if (drainAll === void 0) { drainAll = false; }
|
|
218
217
|
return __generator(this, function (_a) {
|
|
219
218
|
switch (_a.label) {
|
|
220
219
|
case 0:
|
|
@@ -228,13 +227,19 @@ var EventQueue = /** @class */ (function () {
|
|
|
228
227
|
return [2 /*return*/, Promise.resolve()];
|
|
229
228
|
}
|
|
230
229
|
if (!this.pendingFlush) return [3 /*break*/, 2];
|
|
230
|
+
if (!!drainAll) return [3 /*break*/, 2];
|
|
231
231
|
return [4 /*yield*/, this.pendingFlush];
|
|
232
232
|
case 1:
|
|
233
233
|
_a.sent();
|
|
234
234
|
_a.label = 2;
|
|
235
235
|
case 2:
|
|
236
|
-
items = this.queue.splice(0, this.flushAt);
|
|
237
|
-
|
|
236
|
+
items = this.queue.splice(0, drainAll ? this.queue.length : this.flushAt);
|
|
237
|
+
// Only remove hashes for flushed items so duplicate detection remains
|
|
238
|
+
// active for events still in the queue.
|
|
239
|
+
for (_i = 0, items_1 = items; _i < items_1.length; _i++) {
|
|
240
|
+
item = items_1[_i];
|
|
241
|
+
this.payloadHashes.delete(item.message.message_id);
|
|
242
|
+
}
|
|
238
243
|
sentAt = new Date().toISOString();
|
|
239
244
|
data = items.map(function (item) { return (__assign(__assign({}, item.message), { sent_at: sentAt })); });
|
|
240
245
|
batches = this.splitIntoBatches(items, data);
|
|
@@ -396,15 +401,11 @@ var EventQueue = /** @class */ (function () {
|
|
|
396
401
|
return false;
|
|
397
402
|
};
|
|
398
403
|
EventQueue.prototype.isDuplicate = function (eventId) {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
this.payloadHashes.add(eventId);
|
|
405
|
-
return [2 /*return*/, false];
|
|
406
|
-
});
|
|
407
|
-
});
|
|
404
|
+
// check if exists a message with identical payload within 1 minute
|
|
405
|
+
if (this.payloadHashes.has(eventId))
|
|
406
|
+
return true;
|
|
407
|
+
this.payloadHashes.add(eventId);
|
|
408
|
+
return false;
|
|
408
409
|
};
|
|
409
410
|
return EventQueue;
|
|
410
411
|
}());
|
|
@@ -38,15 +38,6 @@ export interface IFormoAnalyticsSession {
|
|
|
38
38
|
*/
|
|
39
39
|
markWalletIdentified(address: string, rdns: string): void;
|
|
40
40
|
}
|
|
41
|
-
/**
|
|
42
|
-
* Implementation of session management using cookies
|
|
43
|
-
*
|
|
44
|
-
* Tracks:
|
|
45
|
-
* - Detected wallets (by RDNS) - to prevent duplicate detection events
|
|
46
|
-
* - Identified wallet-address pairs - to prevent duplicate identification events
|
|
47
|
-
*
|
|
48
|
-
* Session data expires at end of day (86400 seconds).
|
|
49
|
-
*/
|
|
50
41
|
export declare class FormoAnalyticsSession implements IFormoAnalyticsSession {
|
|
51
42
|
/**
|
|
52
43
|
* Generate a unique key for wallet identification tracking
|
|
@@ -22,6 +22,7 @@ export var SESSION_WALLET_IDENTIFIED_KEY = "wallet-identified";
|
|
|
22
22
|
*
|
|
23
23
|
* Session data expires at end of day (86400 seconds).
|
|
24
24
|
*/
|
|
25
|
+
var MAX_SESSION_ENTRIES = 20;
|
|
25
26
|
var FormoAnalyticsSession = /** @class */ (function () {
|
|
26
27
|
function FormoAnalyticsSession() {
|
|
27
28
|
}
|
|
@@ -59,6 +60,9 @@ var FormoAnalyticsSession = /** @class */ (function () {
|
|
|
59
60
|
var rdnses = ((_a = cookie().get(SESSION_WALLET_DETECTED_KEY)) === null || _a === void 0 ? void 0 : _a.split(",")) || [];
|
|
60
61
|
if (!rdnses.includes(rdns)) {
|
|
61
62
|
rdnses.push(rdns);
|
|
63
|
+
if (rdnses.length > MAX_SESSION_ENTRIES) {
|
|
64
|
+
rdnses.splice(0, rdnses.length - MAX_SESSION_ENTRIES);
|
|
65
|
+
}
|
|
62
66
|
cookie().set(SESSION_WALLET_DETECTED_KEY, rdnses.join(","), {
|
|
63
67
|
// Expires by the end of the day
|
|
64
68
|
expires: new Date(Date.now() + 86400 * 1000).toUTCString(),
|
|
@@ -99,6 +103,9 @@ var FormoAnalyticsSession = /** @class */ (function () {
|
|
|
99
103
|
var alreadyExists = identifiedWallets.includes(identifiedKey);
|
|
100
104
|
if (!alreadyExists) {
|
|
101
105
|
identifiedWallets.push(identifiedKey);
|
|
106
|
+
if (identifiedWallets.length > MAX_SESSION_ENTRIES) {
|
|
107
|
+
identifiedWallets.splice(0, identifiedWallets.length - MAX_SESSION_ENTRIES);
|
|
108
|
+
}
|
|
102
109
|
var newValue = identifiedWallets.join(",");
|
|
103
110
|
cookie().set(SESSION_WALLET_IDENTIFIED_KEY, newValue, {
|
|
104
111
|
// Expires by the end of the day
|
|
@@ -26,11 +26,10 @@ export declare class SolanaAdapter {
|
|
|
26
26
|
*/
|
|
27
27
|
private pendingTransactions;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Per-adapter original methods stored in a WeakMap to prevent routing
|
|
30
|
+
* to the wrong wallet after switching adapters.
|
|
30
31
|
*/
|
|
31
|
-
private
|
|
32
|
-
private originalAdapterSignMessage?;
|
|
33
|
-
private originalAdapterSignTransaction?;
|
|
32
|
+
private adapterOriginals;
|
|
34
33
|
/**
|
|
35
34
|
* Bound wrapper references — used to detect when external code (e.g. StandardWalletAdapter._reset())
|
|
36
35
|
* overwrites our wraps so we can re-apply them.
|
|
@@ -115,6 +115,11 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
115
115
|
* Key: transaction signature, Value: transaction details
|
|
116
116
|
*/
|
|
117
117
|
this.pendingTransactions = new Map();
|
|
118
|
+
/**
|
|
119
|
+
* Per-adapter original methods stored in a WeakMap to prevent routing
|
|
120
|
+
* to the wrong wallet after switching adapters.
|
|
121
|
+
*/
|
|
122
|
+
this.adapterOriginals = new WeakMap();
|
|
118
123
|
/**
|
|
119
124
|
* Track active polling timeout IDs for cleanup
|
|
120
125
|
*/
|
|
@@ -144,21 +149,22 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
144
149
|
SolanaAdapter.prototype.restoreOriginalMethods = function () {
|
|
145
150
|
// Restore adapter methods
|
|
146
151
|
if (this.wrappedAdapter) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
152
|
+
var originals = this.adapterOriginals.get(this.wrappedAdapter);
|
|
153
|
+
if (originals) {
|
|
154
|
+
if (originals.sendTransaction) {
|
|
155
|
+
this.wrappedAdapter.sendTransaction = originals.sendTransaction;
|
|
156
|
+
}
|
|
157
|
+
if (originals.signMessage) {
|
|
158
|
+
this.wrappedAdapter.signMessage = originals.signMessage;
|
|
159
|
+
}
|
|
160
|
+
if (originals.signTransaction) {
|
|
161
|
+
this.wrappedAdapter.signTransaction = originals.signTransaction;
|
|
162
|
+
}
|
|
163
|
+
this.adapterOriginals.delete(this.wrappedAdapter);
|
|
155
164
|
}
|
|
156
165
|
this.wrappedAdapter = undefined;
|
|
157
166
|
}
|
|
158
|
-
// Clear
|
|
159
|
-
this.originalAdapterSendTransaction = undefined;
|
|
160
|
-
this.originalAdapterSignMessage = undefined;
|
|
161
|
-
this.originalAdapterSignTransaction = undefined;
|
|
167
|
+
// Clear bound wrapper references
|
|
162
168
|
this.boundWrappedSendTransaction = undefined;
|
|
163
169
|
this.boundWrappedSignMessage = undefined;
|
|
164
170
|
this.boundWrappedSignTransaction = undefined;
|
|
@@ -387,24 +393,26 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
387
393
|
}
|
|
388
394
|
// Store reference to adapter for cleanup
|
|
389
395
|
this.wrappedAdapter = adapter;
|
|
396
|
+
var originals = {};
|
|
390
397
|
// Wrap sendTransaction
|
|
391
398
|
if (adapter.sendTransaction) {
|
|
392
|
-
|
|
399
|
+
originals.sendTransaction = adapter.sendTransaction.bind(adapter);
|
|
393
400
|
this.boundWrappedSendTransaction = this.wrappedSendTransaction.bind(this);
|
|
394
401
|
adapter.sendTransaction = this.boundWrappedSendTransaction;
|
|
395
402
|
}
|
|
396
403
|
// Wrap signMessage
|
|
397
404
|
if (adapter.signMessage) {
|
|
398
|
-
|
|
405
|
+
originals.signMessage = adapter.signMessage.bind(adapter);
|
|
399
406
|
this.boundWrappedSignMessage = this.wrappedSignMessage.bind(this);
|
|
400
407
|
adapter.signMessage = this.boundWrappedSignMessage;
|
|
401
408
|
}
|
|
402
409
|
// Wrap signTransaction
|
|
403
410
|
if (adapter.signTransaction) {
|
|
404
|
-
|
|
411
|
+
originals.signTransaction = adapter.signTransaction.bind(adapter);
|
|
405
412
|
this.boundWrappedSignTransaction = this.wrappedSignTransaction.bind(this);
|
|
406
413
|
adapter.signTransaction = this.boundWrappedSignTransaction;
|
|
407
414
|
}
|
|
415
|
+
this.adapterOriginals.set(adapter, originals);
|
|
408
416
|
};
|
|
409
417
|
/**
|
|
410
418
|
* Re-wrap methods that were overwritten by external code.
|
|
@@ -416,9 +424,10 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
416
424
|
*/
|
|
417
425
|
SolanaAdapter.prototype.rewrapOverwrittenMethods = function (adapter) {
|
|
418
426
|
var rewrapped = false;
|
|
427
|
+
var originals = this.adapterOriginals.get(adapter) || {};
|
|
419
428
|
// signMessage
|
|
420
429
|
if (adapter.signMessage && adapter.signMessage !== this.boundWrappedSignMessage) {
|
|
421
|
-
|
|
430
|
+
originals.signMessage = adapter.signMessage.bind(adapter);
|
|
422
431
|
if (!this.boundWrappedSignMessage) {
|
|
423
432
|
this.boundWrappedSignMessage = this.wrappedSignMessage.bind(this);
|
|
424
433
|
}
|
|
@@ -426,11 +435,11 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
426
435
|
rewrapped = true;
|
|
427
436
|
}
|
|
428
437
|
else if (!adapter.signMessage && this.boundWrappedSignMessage) {
|
|
429
|
-
|
|
438
|
+
originals.signMessage = undefined;
|
|
430
439
|
}
|
|
431
440
|
// signTransaction
|
|
432
441
|
if (adapter.signTransaction && adapter.signTransaction !== this.boundWrappedSignTransaction) {
|
|
433
|
-
|
|
442
|
+
originals.signTransaction = adapter.signTransaction.bind(adapter);
|
|
434
443
|
if (!this.boundWrappedSignTransaction) {
|
|
435
444
|
this.boundWrappedSignTransaction = this.wrappedSignTransaction.bind(this);
|
|
436
445
|
}
|
|
@@ -438,17 +447,18 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
438
447
|
rewrapped = true;
|
|
439
448
|
}
|
|
440
449
|
else if (!adapter.signTransaction && this.boundWrappedSignTransaction) {
|
|
441
|
-
|
|
450
|
+
originals.signTransaction = undefined;
|
|
442
451
|
}
|
|
443
452
|
// sendTransaction — unlikely to be overwritten but check for completeness
|
|
444
453
|
if (adapter.sendTransaction && adapter.sendTransaction !== this.boundWrappedSendTransaction) {
|
|
445
|
-
|
|
454
|
+
originals.sendTransaction = adapter.sendTransaction.bind(adapter);
|
|
446
455
|
if (!this.boundWrappedSendTransaction) {
|
|
447
456
|
this.boundWrappedSendTransaction = this.wrappedSendTransaction.bind(this);
|
|
448
457
|
}
|
|
449
458
|
adapter.sendTransaction = this.boundWrappedSendTransaction;
|
|
450
459
|
rewrapped = true;
|
|
451
460
|
}
|
|
461
|
+
this.adapterOriginals.set(adapter, originals);
|
|
452
462
|
if (rewrapped) {
|
|
453
463
|
logger.debug("SolanaAdapter: Re-wrapped overwritten adapter methods");
|
|
454
464
|
}
|
|
@@ -458,12 +468,13 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
458
468
|
*/
|
|
459
469
|
SolanaAdapter.prototype.wrappedSendTransaction = function (transaction, connection, options) {
|
|
460
470
|
return __awaiter(this, void 0, void 0, function () {
|
|
461
|
-
var chainId, address, signature, error_1;
|
|
471
|
+
var originals, chainId, address, signature, error_1;
|
|
462
472
|
return __generator(this, function (_a) {
|
|
463
473
|
switch (_a.label) {
|
|
464
474
|
case 0:
|
|
465
475
|
this.checkAndRebindContextAdapter();
|
|
466
|
-
|
|
476
|
+
originals = this.wrappedAdapter ? this.adapterOriginals.get(this.wrappedAdapter) : undefined;
|
|
477
|
+
if (!(originals === null || originals === void 0 ? void 0 : originals.sendTransaction)) {
|
|
467
478
|
throw new Error("sendTransaction not available");
|
|
468
479
|
}
|
|
469
480
|
chainId = this.chainId;
|
|
@@ -472,7 +483,7 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
472
483
|
_a.label = 1;
|
|
473
484
|
case 1:
|
|
474
485
|
_a.trys.push([1, 3, , 4]);
|
|
475
|
-
return [4 /*yield*/,
|
|
486
|
+
return [4 /*yield*/, originals.sendTransaction(transaction, connection, options)];
|
|
476
487
|
case 2:
|
|
477
488
|
signature = _a.sent();
|
|
478
489
|
this.emitTransactionEvent(TransactionStatus.BROADCASTED, address, chainId, signature);
|
|
@@ -498,12 +509,13 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
498
509
|
*/
|
|
499
510
|
SolanaAdapter.prototype.wrappedSignMessage = function (message) {
|
|
500
511
|
return __awaiter(this, void 0, void 0, function () {
|
|
501
|
-
var chainId, address, messageString, signature, signatureHex, error_2;
|
|
512
|
+
var originals, chainId, address, messageString, signature, signatureHex, error_2;
|
|
502
513
|
return __generator(this, function (_a) {
|
|
503
514
|
switch (_a.label) {
|
|
504
515
|
case 0:
|
|
505
516
|
this.checkAndRebindContextAdapter();
|
|
506
|
-
|
|
517
|
+
originals = this.wrappedAdapter ? this.adapterOriginals.get(this.wrappedAdapter) : undefined;
|
|
518
|
+
if (!(originals === null || originals === void 0 ? void 0 : originals.signMessage)) {
|
|
507
519
|
throw new Error("signMessage not available");
|
|
508
520
|
}
|
|
509
521
|
chainId = this.chainId;
|
|
@@ -513,7 +525,7 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
513
525
|
_a.label = 1;
|
|
514
526
|
case 1:
|
|
515
527
|
_a.trys.push([1, 3, , 4]);
|
|
516
|
-
return [4 /*yield*/,
|
|
528
|
+
return [4 /*yield*/, originals.signMessage(message)];
|
|
517
529
|
case 2:
|
|
518
530
|
signature = _a.sent();
|
|
519
531
|
signatureHex = uint8ArrayToHex(signature);
|
|
@@ -533,12 +545,13 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
533
545
|
*/
|
|
534
546
|
SolanaAdapter.prototype.wrappedSignTransaction = function (transaction) {
|
|
535
547
|
return __awaiter(this, void 0, void 0, function () {
|
|
536
|
-
var chainId, address, message, signedTx, error_3;
|
|
548
|
+
var originals, chainId, address, message, signedTx, error_3;
|
|
537
549
|
return __generator(this, function (_a) {
|
|
538
550
|
switch (_a.label) {
|
|
539
551
|
case 0:
|
|
540
552
|
this.checkAndRebindContextAdapter();
|
|
541
|
-
|
|
553
|
+
originals = this.wrappedAdapter ? this.adapterOriginals.get(this.wrappedAdapter) : undefined;
|
|
554
|
+
if (!(originals === null || originals === void 0 ? void 0 : originals.signTransaction)) {
|
|
542
555
|
throw new Error("signTransaction not available");
|
|
543
556
|
}
|
|
544
557
|
chainId = this.chainId;
|
|
@@ -548,7 +561,7 @@ var SolanaAdapter = /** @class */ (function () {
|
|
|
548
561
|
_a.label = 1;
|
|
549
562
|
case 1:
|
|
550
563
|
_a.trys.push([1, 3, , 4]);
|
|
551
|
-
return [4 /*yield*/,
|
|
564
|
+
return [4 /*yield*/, originals.signTransaction(transaction)];
|
|
552
565
|
case 2:
|
|
553
566
|
signedTx = _a.sent();
|
|
554
567
|
this.emitSignatureEvent(SignatureStatus.CONFIRMED, address, chainId, message);
|
|
@@ -17,11 +17,19 @@ var StorageManager = /** @class */ (function () {
|
|
|
17
17
|
StorageManager.prototype.getStorage = function (type) {
|
|
18
18
|
if (!this.storages.has(type)) {
|
|
19
19
|
var storage = this.createStorage(type);
|
|
20
|
+
var currentType = type;
|
|
20
21
|
// If storage is not available, try next
|
|
21
22
|
while (!storage.isAvailable()) {
|
|
22
|
-
var index = TYPES.indexOf(
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
var index = TYPES.indexOf(currentType);
|
|
24
|
+
if (index === -1 || index + 1 >= TYPES.length) {
|
|
25
|
+
// No more fallbacks, use memory storage as last resort
|
|
26
|
+
storage = this.createStorage("memoryStorage");
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
var prevType = currentType;
|
|
30
|
+
currentType = TYPES[index + 1];
|
|
31
|
+
logger.warn("Storage ".concat(prevType, " is not available, trying ").concat(currentType));
|
|
32
|
+
storage = this.createStorage(currentType);
|
|
25
33
|
}
|
|
26
34
|
// Add to cache
|
|
27
35
|
this.storages.set(type, storage);
|
|
@@ -14,6 +14,7 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
14
14
|
};
|
|
15
15
|
})();
|
|
16
16
|
import StorageBlueprint from "./blueprint";
|
|
17
|
+
import { getApexDomain } from "../../utils/domain";
|
|
17
18
|
var CookieStorage = /** @class */ (function (_super) {
|
|
18
19
|
__extends(CookieStorage, _super);
|
|
19
20
|
function CookieStorage() {
|
|
@@ -26,10 +27,27 @@ var CookieStorage = /** @class */ (function (_super) {
|
|
|
26
27
|
var expires = options === null || options === void 0 ? void 0 : options.expires;
|
|
27
28
|
var maxAge = options === null || options === void 0 ? void 0 : options.maxAge;
|
|
28
29
|
var path = (options === null || options === void 0 ? void 0 : options.path) || "/";
|
|
29
|
-
var domain = options === null || options === void 0 ? void 0 : options.domain;
|
|
30
|
+
var domain = (options === null || options === void 0 ? void 0 : options.domain) || "";
|
|
30
31
|
var sameSite = options === null || options === void 0 ? void 0 : options.sameSite;
|
|
31
32
|
var secure = (options === null || options === void 0 ? void 0 : options.secure) || false;
|
|
32
|
-
var
|
|
33
|
+
var encodedKey = encodeURIComponent(this.getKey(key));
|
|
34
|
+
// When writing a domain-wide cookie, expire any legacy host-only cookie
|
|
35
|
+
// on the current host so it doesn't shadow the domain-wide cookie in
|
|
36
|
+
// document.cookie reads. This only clears the cookie on the current host;
|
|
37
|
+
// host-only cookies on sibling hosts are not visible and cannot be cleared.
|
|
38
|
+
if (domain) {
|
|
39
|
+
document.cookie = "".concat(encodedKey, "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=").concat(path, ";");
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// When writing a host-only cookie (no domain), expire any previously
|
|
43
|
+
// written apex-domain cookie so it doesn't shadow the new host cookie.
|
|
44
|
+
// This handles the transition from crossSubdomainCookies: true to false.
|
|
45
|
+
var apexDomain = getApexDomain();
|
|
46
|
+
if (apexDomain) {
|
|
47
|
+
document.cookie = "".concat(encodedKey, "=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=").concat(path, "; domain=.").concat(apexDomain);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
var cookie = "".concat(encodedKey, "=").concat(encodeURIComponent(value));
|
|
33
51
|
if (maxAge) {
|
|
34
52
|
cookie += "; max-age=" + maxAge;
|
|
35
53
|
}
|
|
@@ -55,7 +73,15 @@ var CookieStorage = /** @class */ (function (_super) {
|
|
|
55
73
|
return match ? decodeURIComponent(match[1]) : null;
|
|
56
74
|
};
|
|
57
75
|
CookieStorage.prototype.remove = function (key) {
|
|
58
|
-
|
|
76
|
+
var encodedKey = encodeURIComponent(this.getKey(key));
|
|
77
|
+
// Always expire host-only cookie
|
|
78
|
+
document.cookie = "".concat(encodedKey, "=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT");
|
|
79
|
+
// Also expire apex-domain cookie if a valid apex domain exists,
|
|
80
|
+
// so that remove() works regardless of crossSubdomainCookies.
|
|
81
|
+
var domain = getApexDomain();
|
|
82
|
+
if (domain) {
|
|
83
|
+
document.cookie = "".concat(encodedKey, "=; path=/; domain=.").concat(domain, "; expires=Thu, 01 Jan 1970 00:00:00 GMT");
|
|
84
|
+
}
|
|
59
85
|
};
|
|
60
86
|
return CookieStorage;
|
|
61
87
|
}(StorageBlueprint));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the domain attribute string for identity cookies.
|
|
3
|
+
* - false → "" (no domain attribute, host-only)
|
|
4
|
+
* - true → ".example.com" when a valid apex domain is detected,
|
|
5
|
+
* or "" on localhost / IP / single-label hosts
|
|
6
|
+
*
|
|
7
|
+
* @param crossSubdomain Whether cookies should be shared across subdomains.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getIdentityCookieDomain(crossSubdomain?: boolean): string;
|
|
10
|
+
//# sourceMappingURL=cookiePolicy.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cookie domain policy — centralizes the decision of whether identity
|
|
3
|
+
* cookies should be host-scoped or apex-scoped.
|
|
4
|
+
*
|
|
5
|
+
* - true (default): domain set to .apexDomain → shared across subdomains
|
|
6
|
+
* - false: no domain attribute → cookie scoped to current host
|
|
7
|
+
*/
|
|
8
|
+
import { getApexDomain } from "../utils/domain";
|
|
9
|
+
/**
|
|
10
|
+
* Returns the domain attribute string for identity cookies.
|
|
11
|
+
* - false → "" (no domain attribute, host-only)
|
|
12
|
+
* - true → ".example.com" when a valid apex domain is detected,
|
|
13
|
+
* or "" on localhost / IP / single-label hosts
|
|
14
|
+
*
|
|
15
|
+
* @param crossSubdomain Whether cookies should be shared across subdomains.
|
|
16
|
+
*/
|
|
17
|
+
export function getIdentityCookieDomain(crossSubdomain) {
|
|
18
|
+
if (crossSubdomain === void 0) { crossSubdomain = true; }
|
|
19
|
+
if (!crossSubdomain)
|
|
20
|
+
return "";
|
|
21
|
+
var domain = getApexDomain();
|
|
22
|
+
return domain ? ".".concat(domain) : "";
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=cookiePolicy.js.map
|
|
@@ -144,6 +144,18 @@ export interface WagmiOptions {
|
|
|
144
144
|
export interface Options {
|
|
145
145
|
provider?: EIP1193Provider;
|
|
146
146
|
tracking?: boolean | TrackingOptions;
|
|
147
|
+
/**
|
|
148
|
+
* When `true`, identity cookies (anonymous ID, user ID) are set on the
|
|
149
|
+
* apex/root domain (e.g. `.example.com`), enabling cross-subdomain identity
|
|
150
|
+
* sharing between app.example.com and www.example.com.
|
|
151
|
+
*
|
|
152
|
+
* When `false`, cookies are scoped to the current host only.
|
|
153
|
+
*
|
|
154
|
+
* Session cookies (wallet detection, current URL) always remain host-scoped.
|
|
155
|
+
* Consent cookies are always apex-scoped independently for compliance.
|
|
156
|
+
* @default true
|
|
157
|
+
*/
|
|
158
|
+
crossSubdomainCookies?: boolean;
|
|
147
159
|
/**
|
|
148
160
|
* Control wallet event autocapture
|
|
149
161
|
* - `false`: Disable all wallet autocapture
|
|
@@ -46,15 +46,13 @@ export var getValidAddress = function (address) {
|
|
|
46
46
|
* @returns true if the address is blocked, false otherwise
|
|
47
47
|
*/
|
|
48
48
|
export var isBlockedAddress = function (address) {
|
|
49
|
-
if (!address)
|
|
49
|
+
if (!address || typeof address !== 'string')
|
|
50
50
|
return false;
|
|
51
|
-
var
|
|
52
|
-
if (!
|
|
51
|
+
var normalized = address.trim().toLowerCase();
|
|
52
|
+
if (!normalized || !normalized.startsWith('0x') || normalized.length !== 42)
|
|
53
53
|
return false;
|
|
54
|
-
// Normalize to checksum format for comparison
|
|
55
|
-
var checksumAddress = toChecksumAddress(validAddress);
|
|
56
54
|
return BLOCKED_ADDRESSES.some(function (blockedAddr) {
|
|
57
|
-
return
|
|
55
|
+
return blockedAddr.toLowerCase() === normalized;
|
|
58
56
|
});
|
|
59
57
|
};
|
|
60
58
|
export var toChecksumAddress = function (address) {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain utilities for cross-subdomain cookie sharing.
|
|
3
|
+
*
|
|
4
|
+
* Uses a cookie-probe approach: tries setting a test cookie on progressively
|
|
5
|
+
* shorter domain candidates until the browser accepts one. This is
|
|
6
|
+
* self-maintaining — no hardcoded public suffix lists to keep up to date.
|
|
7
|
+
* The browser itself is the authority on which domains accept cookies.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Extract the apex (registrable) domain for cookie sharing across subdomains.
|
|
11
|
+
*
|
|
12
|
+
* Walks up the hostname labels from shortest candidate to longest, probing
|
|
13
|
+
* with a test cookie. The shortest domain the browser accepts is the apex.
|
|
14
|
+
*
|
|
15
|
+
* Returns null for localhost, IP addresses, single-label hosts, SSR, or
|
|
16
|
+
* when no candidate domain accepts cookies (e.g. public suffix hosts like
|
|
17
|
+
* vercel.app or github.io).
|
|
18
|
+
*
|
|
19
|
+
* Results are cached for the lifetime of the page.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getApexDomain(): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Reset the cached apex domain. Exposed for testing only.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export declare function _resetApexDomainCache(): void;
|
|
27
|
+
//# sourceMappingURL=domain.d.ts.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain utilities for cross-subdomain cookie sharing.
|
|
3
|
+
*
|
|
4
|
+
* Uses a cookie-probe approach: tries setting a test cookie on progressively
|
|
5
|
+
* shorter domain candidates until the browser accepts one. This is
|
|
6
|
+
* self-maintaining — no hardcoded public suffix lists to keep up to date.
|
|
7
|
+
* The browser itself is the authority on which domains accept cookies.
|
|
8
|
+
*/
|
|
9
|
+
var TEST_COOKIE_NAME = '__formo_domain_probe';
|
|
10
|
+
/** Cached result so we only probe once per page load. */
|
|
11
|
+
var cachedApexDomain;
|
|
12
|
+
/**
|
|
13
|
+
* Try to set a test cookie on the given domain. Returns true if the browser
|
|
14
|
+
* accepted it (i.e. the cookie is readable back).
|
|
15
|
+
*/
|
|
16
|
+
function canSetCookieOnDomain(domain) {
|
|
17
|
+
var cookieVal = 'probe';
|
|
18
|
+
document.cookie = "".concat(TEST_COOKIE_NAME, "=").concat(cookieVal, "; domain=.").concat(domain, "; path=/; max-age=10");
|
|
19
|
+
var accepted = document.cookie.indexOf("".concat(TEST_COOKIE_NAME, "=").concat(cookieVal)) !== -1;
|
|
20
|
+
// Clean up regardless of result
|
|
21
|
+
document.cookie = "".concat(TEST_COOKIE_NAME, "=; domain=.").concat(domain, "; path=/; max-age=0");
|
|
22
|
+
return accepted;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Extract the apex (registrable) domain for cookie sharing across subdomains.
|
|
26
|
+
*
|
|
27
|
+
* Walks up the hostname labels from shortest candidate to longest, probing
|
|
28
|
+
* with a test cookie. The shortest domain the browser accepts is the apex.
|
|
29
|
+
*
|
|
30
|
+
* Returns null for localhost, IP addresses, single-label hosts, SSR, or
|
|
31
|
+
* when no candidate domain accepts cookies (e.g. public suffix hosts like
|
|
32
|
+
* vercel.app or github.io).
|
|
33
|
+
*
|
|
34
|
+
* Results are cached for the lifetime of the page.
|
|
35
|
+
*/
|
|
36
|
+
export function getApexDomain() {
|
|
37
|
+
if (typeof window === 'undefined')
|
|
38
|
+
return null;
|
|
39
|
+
if (cachedApexDomain !== undefined)
|
|
40
|
+
return cachedApexDomain;
|
|
41
|
+
var hostname = window.location.hostname;
|
|
42
|
+
if (hostname === 'localhost' || /^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
|
|
43
|
+
cachedApexDomain = null;
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
var parts = hostname.split('.');
|
|
47
|
+
if (parts.length < 2) {
|
|
48
|
+
cachedApexDomain = null;
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
// Walk from the shortest candidate (last 2 labels) to the full hostname.
|
|
52
|
+
// The shortest domain the browser accepts is the apex domain.
|
|
53
|
+
for (var i = 2; i <= parts.length; i++) {
|
|
54
|
+
var candidate = parts.slice(-i).join('.');
|
|
55
|
+
if (canSetCookieOnDomain(candidate)) {
|
|
56
|
+
cachedApexDomain = candidate;
|
|
57
|
+
return candidate;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
cachedApexDomain = null;
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Reset the cached apex domain. Exposed for testing only.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
67
|
+
export function _resetApexDomainCache() {
|
|
68
|
+
cachedApexDomain = undefined;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=domain.js.map
|