@formo/analytics 1.38.1 → 1.38.2
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 +10 -1
- package/dist/cjs/src/FormoAnalytics.js +11 -1
- package/dist/cjs/src/evm/EvmEventTracker.d.ts +100 -9
- package/dist/cjs/src/evm/EvmEventTracker.js +357 -19
- package/dist/cjs/src/evm/EvmProviderRegistry.d.ts +34 -2
- package/dist/cjs/src/evm/EvmProviderRegistry.js +61 -4
- package/dist/cjs/src/evm/EvmRequestTracker.d.ts +9 -4
- package/dist/cjs/src/evm/EvmRequestTracker.js +26 -16
- package/dist/cjs/src/version.d.ts +1 -1
- package/dist/cjs/src/version.js +1 -1
- package/dist/cjs/src/wagmi/WagmiEventHandler.d.ts +30 -1
- package/dist/cjs/src/wagmi/WagmiEventHandler.js +80 -1
- package/dist/cjs/src/wagmi/types.d.ts +6 -0
- package/dist/cjs/src/wagmi/utils.js +9 -1
- package/dist/esm/src/FormoAnalytics.d.ts +10 -1
- package/dist/esm/src/FormoAnalytics.js +11 -1
- package/dist/esm/src/evm/EvmEventTracker.d.ts +100 -9
- package/dist/esm/src/evm/EvmEventTracker.js +357 -19
- package/dist/esm/src/evm/EvmProviderRegistry.d.ts +34 -2
- package/dist/esm/src/evm/EvmProviderRegistry.js +61 -4
- package/dist/esm/src/evm/EvmRequestTracker.d.ts +9 -4
- package/dist/esm/src/evm/EvmRequestTracker.js +26 -16
- package/dist/esm/src/version.d.ts +1 -1
- package/dist/esm/src/version.js +1 -1
- package/dist/esm/src/wagmi/WagmiEventHandler.d.ts +30 -1
- package/dist/esm/src/wagmi/WagmiEventHandler.js +80 -1
- package/dist/esm/src/wagmi/types.d.ts +6 -0
- package/dist/esm/src/wagmi/utils.js +9 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +2 -2
|
@@ -136,10 +136,54 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
136
136
|
* Announcement-driven cleanup must not touch them: they are never in an
|
|
137
137
|
* announcement list, so "missing from the announcement" is their normal
|
|
138
138
|
* state, not evidence of removal. A Set rather than a WeakSet because
|
|
139
|
-
*
|
|
140
|
-
* strongly
|
|
139
|
+
* the corrected-detect pass iterates it; the registry's detail list
|
|
140
|
+
* holds these providers strongly for the instance's life anyway.
|
|
141
141
|
*/
|
|
142
142
|
this.externallyRegistered = new Set();
|
|
143
|
+
/**
|
|
144
|
+
* Registered providers whose session this SDK has NOT yet learned.
|
|
145
|
+
*
|
|
146
|
+
* Only these are retried on page hits and opt-in. Re-running adoption for
|
|
147
|
+
* every registered provider looked idempotent but was not: adoption is
|
|
148
|
+
* the same path a live `accountsChanged` takes, and that path treats a
|
|
149
|
+
* provider with a different address from the active one as a wallet
|
|
150
|
+
* switch. With two registered providers, or one registered next to a
|
|
151
|
+
* discovered wallet, every page hit emitted a disconnect and a connect
|
|
152
|
+
* that no user action caused.
|
|
153
|
+
*
|
|
154
|
+
* A provider enters at registration (it may have no session yet, or be
|
|
155
|
+
* refused because tracking is suppressed), again whenever a handler
|
|
156
|
+
* refuses its signal while suppressed (noted on entry AND at the
|
|
157
|
+
* suppressed commit, since the handlers gate on the active provider and
|
|
158
|
+
* re-check suppression after an await), and again for all of them when
|
|
159
|
+
* an opt-out purges identity. It leaves the first time a handler commits
|
|
160
|
+
* its session unsuppressed, or when it is untracked. Retrying reads the
|
|
161
|
+
* provider's SYNCHRONOUS accounts only - no RPC - so a registered
|
|
162
|
+
* provider whose session never fires `accountsChanged` (a wallet that
|
|
163
|
+
* signals `connect` alone while `autocapture.connect` is off, which
|
|
164
|
+
* installs a chain-only observer) is still adopted on the next hit. "No
|
|
165
|
+
* RPC" holds for the pending provider itself; the handler's switch
|
|
166
|
+
* arbitration may still ask the ACTIVE provider for its accounts, as it
|
|
167
|
+
* does for any live signal.
|
|
168
|
+
*
|
|
169
|
+
* Replay goes through the accounts handler, which has live wallet-switch
|
|
170
|
+
* semantics: a different provider with a different address is a switch.
|
|
171
|
+
* So a pending provider is replayed only while no OTHER wallet is active
|
|
172
|
+
* and known - it waits, at no cost, until that wallet is gone - unless
|
|
173
|
+
* its own signal was refused (`latestRefused`): then the replay does
|
|
174
|
+
* exactly what the live signal would have done, switch included.
|
|
175
|
+
*/
|
|
176
|
+
this.pendingAdoptions = new Set();
|
|
177
|
+
/**
|
|
178
|
+
* Registered providers whose session ended and have not signalled a
|
|
179
|
+
* new one. Some providers keep stale synchronous `accounts` after a
|
|
180
|
+
* disconnect; replaying those would re-install a session that is over.
|
|
181
|
+
* Any later session signal (connect, accountsChanged) lifts this.
|
|
182
|
+
*/
|
|
183
|
+
this.awaitingNewSession = new Set();
|
|
184
|
+
/** One retry scan at a time; a call during a scan queues one more. */
|
|
185
|
+
this.retryInFlight = false;
|
|
186
|
+
this.retryRequested = false;
|
|
143
187
|
/**
|
|
144
188
|
* The connect this SDK has already reported for a provider.
|
|
145
189
|
*
|
|
@@ -148,10 +192,89 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
148
192
|
* which is when a record must lapse.
|
|
149
193
|
*/
|
|
150
194
|
this._announcedConnect = new WeakMap();
|
|
195
|
+
/** Set by `cleanup()`; every awaited continuation checks it. */
|
|
196
|
+
this.disposed = false;
|
|
197
|
+
/** Bumped when a registered provider's session ends. See reopenAdoption. */
|
|
198
|
+
this.sessionGenerations = new WeakMap();
|
|
151
199
|
}
|
|
200
|
+
EvmEventTracker.prototype.dropRefusal = function (provider) {
|
|
201
|
+
if (this.latestRefused === provider)
|
|
202
|
+
this.latestRefused = undefined;
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* An opt-out purges wallet identity. Every registered session is then
|
|
206
|
+
* unknown again (pending; no refusal is ADDED, so the opt-in replay of a
|
|
207
|
+
* merely connected wallet does not switch, while a refusal already
|
|
208
|
+
* standing from an excluded route keeps its meaning), and the
|
|
209
|
+
* opt-in retry must re-learn all of them: with the active wallet's
|
|
210
|
+
* address gone, the accounts handler cannot even tell a second wallet's
|
|
211
|
+
* accounts apart from the active one's, and would ignore them.
|
|
212
|
+
*/
|
|
213
|
+
EvmEventTracker.prototype.markRegisteredAdoptionsPending = function () {
|
|
214
|
+
var _this = this;
|
|
215
|
+
this.externallyRegistered.forEach(function (provider) {
|
|
216
|
+
return _this.pendingAdoptions.add(provider);
|
|
217
|
+
});
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Remember a registered provider's signal that suppression refuses.
|
|
221
|
+
*
|
|
222
|
+
* Replay privilege (`latestRefused`) goes only to a provider whose
|
|
223
|
+
* session the replay can actually read - synchronous accounts - so an
|
|
224
|
+
* accountless `connect` (a chain-only observation, or a session still
|
|
225
|
+
* pairing) cannot displace an earlier refusal that is adoptable.
|
|
226
|
+
*/
|
|
227
|
+
EvmEventTracker.prototype.noteRefusalIfSuppressed = function (provider) {
|
|
228
|
+
if (this.deps.isTrackingSuppressed() &&
|
|
229
|
+
this.externallyRegistered.has(provider)) {
|
|
230
|
+
this.pendingAdoptions.add(provider);
|
|
231
|
+
var adoptable = false;
|
|
232
|
+
try {
|
|
233
|
+
adoptable = readProviderAccounts(provider).length > 0;
|
|
234
|
+
}
|
|
235
|
+
catch (_a) {
|
|
236
|
+
/* unreadable state: pending, not privileged */
|
|
237
|
+
}
|
|
238
|
+
if (adoptable)
|
|
239
|
+
this.latestRefused = provider;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
/** A handler has learned this provider's session; nothing is pending. */
|
|
243
|
+
EvmEventTracker.prototype.settleAdoption = function (provider) {
|
|
244
|
+
this.pendingAdoptions.delete(provider);
|
|
245
|
+
this.awaitingNewSession.delete(provider);
|
|
246
|
+
this.dropRefusal(provider);
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* A registered provider's session has ended. Its NEXT session is not
|
|
250
|
+
* yet learned, and may announce itself in a way no handler adopts (a
|
|
251
|
+
* `connect` alone while `autocapture.connect` is off installs a
|
|
252
|
+
* chain-only observer), so it is pending again for the page-hit retry.
|
|
253
|
+
*/
|
|
254
|
+
EvmEventTracker.prototype.reopenAdoption = function (provider) {
|
|
255
|
+
var _a;
|
|
256
|
+
if (this.externallyRegistered.has(provider)) {
|
|
257
|
+
this.pendingAdoptions.add(provider);
|
|
258
|
+
this.awaitingNewSession.add(provider);
|
|
259
|
+
// A lookup still in flight for the session that just ended must not
|
|
260
|
+
// record a refusal for it when it resolves.
|
|
261
|
+
this.sessionGenerations.set(provider, ((_a = this.sessionGenerations.get(provider)) !== null && _a !== void 0 ? _a : 0) + 1);
|
|
262
|
+
// The refusal marker described the session that just ended. Left
|
|
263
|
+
// standing, a later connect-only session would inherit it and be
|
|
264
|
+
// replayed as a switch away from another active wallet.
|
|
265
|
+
this.dropRefusal(provider);
|
|
266
|
+
}
|
|
267
|
+
};
|
|
152
268
|
/** Stop listening for wallet announcements. Called from SDK teardown. */
|
|
153
269
|
EvmEventTracker.prototype.cleanup = function () {
|
|
154
270
|
var _a;
|
|
271
|
+
// A replay in flight (awaiting the active wallet's accounts) must not
|
|
272
|
+
// resume into a torn-down instance and commit a session there.
|
|
273
|
+
this.disposed = true;
|
|
274
|
+
this.pendingAdoptions.clear();
|
|
275
|
+
this.awaitingNewSession.clear();
|
|
276
|
+
this.latestRefused = undefined;
|
|
277
|
+
this.retryRequested = false;
|
|
155
278
|
try {
|
|
156
279
|
(_a = this.unsubscribeDiscovery) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
157
280
|
}
|
|
@@ -160,6 +283,10 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
160
283
|
}
|
|
161
284
|
this.unsubscribeDiscovery = undefined;
|
|
162
285
|
};
|
|
286
|
+
EvmEventTracker.prototype.sessionGeneration = function (provider) {
|
|
287
|
+
var _a;
|
|
288
|
+
return (_a = this.sessionGenerations.get(provider)) !== null && _a !== void 0 ? _a : 0;
|
|
289
|
+
};
|
|
163
290
|
/** Drop a provider's reported connect. Called when it stops being active. */
|
|
164
291
|
EvmEventTracker.prototype.forgetAnnouncedConnect = function (provider) {
|
|
165
292
|
this._announcedConnect.delete(provider);
|
|
@@ -321,6 +448,9 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
321
448
|
void this.detectWallets([
|
|
322
449
|
__assign(__assign({}, detail), { info: __assign(__assign({}, detail.info), this.registry.infoFor(provider)) }),
|
|
323
450
|
]);
|
|
451
|
+
// Pending until a handler commits its session unsuppressed: the
|
|
452
|
+
// session may not exist yet, or adoption may be refused right below.
|
|
453
|
+
this.pendingAdoptions.add(provider);
|
|
324
454
|
var accounts = readProviderAccounts(provider);
|
|
325
455
|
if (accounts.length > 0) {
|
|
326
456
|
void this.onAccountsChanged(provider, accounts);
|
|
@@ -328,14 +458,19 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
328
458
|
return true;
|
|
329
459
|
};
|
|
330
460
|
/**
|
|
331
|
-
*
|
|
461
|
+
* Finish what registration could not.
|
|
462
|
+
*
|
|
463
|
+
* A registered provider's session may not have existed at registration,
|
|
464
|
+
* or its adoption was refused because tracking was suppressed (opt-out,
|
|
465
|
+
* excluded route) - and an existing session may never emit another
|
|
466
|
+
* accountsChanged, so nothing else would ever retry. Called when
|
|
467
|
+
* suppression can have ended (opt-in, page navigation).
|
|
332
468
|
*
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
*
|
|
338
|
-
* deduplicated by the same state and markers as any repeated signal.
|
|
469
|
+
* Adoption is retried ONLY for providers not yet adopted
|
|
470
|
+
* (`pendingAdoptions`), only from their synchronous accounts, and only
|
|
471
|
+
* once suppression has actually ended. The corrected-detect pass below
|
|
472
|
+
* runs for every registered provider: it is deduplicated per session by
|
|
473
|
+
* rdns, so repeating it is free.
|
|
339
474
|
*/
|
|
340
475
|
EvmEventTracker.prototype.retryExternalAdoptions = function () {
|
|
341
476
|
var _this = this;
|
|
@@ -358,11 +493,97 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
358
493
|
},
|
|
359
494
|
]);
|
|
360
495
|
}
|
|
361
|
-
var accounts = readProviderAccounts(provider);
|
|
362
|
-
if (accounts.length > 0) {
|
|
363
|
-
void _this.onAccountsChanged(provider, accounts);
|
|
364
|
-
}
|
|
365
496
|
});
|
|
497
|
+
if (this.disposed ||
|
|
498
|
+
this.pendingAdoptions.size === 0 ||
|
|
499
|
+
this.deps.isTrackingSuppressed()) {
|
|
500
|
+
// Nothing to finish, or still suppressed: adopting now would be
|
|
501
|
+
// refused again, and the entry must survive for the next chance.
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
// ONE scan at a time, providers awaited in turn, and the entry is NOT
|
|
505
|
+
// removed here: only a handler that commits the session removes it.
|
|
506
|
+
// Fired concurrently - two overlapping scans from repeated page hits,
|
|
507
|
+
// or two providers within one - the later call made the earlier
|
|
508
|
+
// one's observation stale; a stale return dropped a provider whose
|
|
509
|
+
// session was never learned, and a second scan replayed a provider
|
|
510
|
+
// the first was still switching to, emitting the old wallet's
|
|
511
|
+
// disconnect twice. A call that lands during a scan queues exactly
|
|
512
|
+
// one more scan, so nothing that changed meanwhile is missed.
|
|
513
|
+
if (this.retryInFlight) {
|
|
514
|
+
this.retryRequested = true;
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
this.retryInFlight = true;
|
|
518
|
+
void (function () { return __awaiter(_this, void 0, void 0, function () {
|
|
519
|
+
var first, ordered, _i, ordered_1, provider, accounts, otherWalletActive, _a;
|
|
520
|
+
var _this = this;
|
|
521
|
+
return __generator(this, function (_b) {
|
|
522
|
+
switch (_b.label) {
|
|
523
|
+
case 0:
|
|
524
|
+
_b.trys.push([0, , 9, 10]);
|
|
525
|
+
_b.label = 1;
|
|
526
|
+
case 1:
|
|
527
|
+
this.retryRequested = false;
|
|
528
|
+
first = [this.wallet.provider, this.latestRefused].filter(function (p) { return !!p && _this.pendingAdoptions.has(p); });
|
|
529
|
+
ordered = Array.from(new Set(__spreadArray(__spreadArray([], first, true), Array.from(this.pendingAdoptions), true)));
|
|
530
|
+
_i = 0, ordered_1 = ordered;
|
|
531
|
+
_b.label = 2;
|
|
532
|
+
case 2:
|
|
533
|
+
if (!(_i < ordered_1.length)) return [3 /*break*/, 7];
|
|
534
|
+
provider = ordered_1[_i];
|
|
535
|
+
if (this.disposed || this.deps.isTrackingSuppressed())
|
|
536
|
+
return [3 /*break*/, 7];
|
|
537
|
+
accounts = void 0;
|
|
538
|
+
try {
|
|
539
|
+
accounts = readProviderAccounts(provider);
|
|
540
|
+
}
|
|
541
|
+
catch (_c) {
|
|
542
|
+
// A wallet whose state getters throw (transport disposed)
|
|
543
|
+
// stays pending; it must not abort the scan for the others,
|
|
544
|
+
// nor surface as an unhandled rejection from this task.
|
|
545
|
+
return [3 /*break*/, 6];
|
|
546
|
+
}
|
|
547
|
+
if (accounts.length === 0 || this.awaitingNewSession.has(provider)) {
|
|
548
|
+
// No session yet, or none since the last one ended: stays
|
|
549
|
+
// pending, at no cost.
|
|
550
|
+
return [3 /*break*/, 6];
|
|
551
|
+
}
|
|
552
|
+
otherWalletActive = this.wallet.provider !== undefined &&
|
|
553
|
+
this.wallet.provider !== provider;
|
|
554
|
+
if (otherWalletActive && this.latestRefused !== provider) {
|
|
555
|
+
// Never signalled, merely connected: replaying it now would
|
|
556
|
+
// be reported as a wallet switch nobody made. Waits for
|
|
557
|
+
// that wallet to go.
|
|
558
|
+
return [3 /*break*/, 6];
|
|
559
|
+
}
|
|
560
|
+
_b.label = 3;
|
|
561
|
+
case 3:
|
|
562
|
+
_b.trys.push([3, 5, , 6]);
|
|
563
|
+
return [4 /*yield*/, this.onAccountsChanged(provider, accounts)];
|
|
564
|
+
case 4:
|
|
565
|
+
_b.sent();
|
|
566
|
+
return [3 /*break*/, 6];
|
|
567
|
+
case 5:
|
|
568
|
+
_a = _b.sent();
|
|
569
|
+
return [3 /*break*/, 6];
|
|
570
|
+
case 6:
|
|
571
|
+
_i++;
|
|
572
|
+
return [3 /*break*/, 2];
|
|
573
|
+
case 7:
|
|
574
|
+
if (this.retryRequested &&
|
|
575
|
+
!this.disposed &&
|
|
576
|
+
!this.deps.isTrackingSuppressed()) return [3 /*break*/, 1];
|
|
577
|
+
_b.label = 8;
|
|
578
|
+
case 8: return [3 /*break*/, 10];
|
|
579
|
+
case 9:
|
|
580
|
+
this.retryInFlight = false;
|
|
581
|
+
this.retryRequested = false;
|
|
582
|
+
return [7 /*endfinally*/];
|
|
583
|
+
case 10: return [2 /*return*/];
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}); })();
|
|
366
587
|
};
|
|
367
588
|
EvmEventTracker.prototype.registerAccountsChangedListener = function (provider) {
|
|
368
589
|
var _this = this;
|
|
@@ -383,6 +604,11 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
383
604
|
return __generator(this, function (_a) {
|
|
384
605
|
switch (_a.label) {
|
|
385
606
|
case 0:
|
|
607
|
+
// A listener that could not be removed at cleanup (its provider's
|
|
608
|
+
// removeListener threw) still fires; it must not touch a torn-down
|
|
609
|
+
// instance.
|
|
610
|
+
if (this.disposed)
|
|
611
|
+
return [2 /*return*/];
|
|
386
612
|
logger.info("onAccountsChanged", accounts);
|
|
387
613
|
claims = accounts.length > 0 || this.wallet.provider === provider;
|
|
388
614
|
observation = claims
|
|
@@ -418,11 +644,12 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
418
644
|
*/
|
|
419
645
|
EvmEventTracker.prototype._handleAccountsChanged = function (provider, accounts, observation) {
|
|
420
646
|
return __awaiter(this, void 0, void 0, function () {
|
|
421
|
-
var error_1, address, currentStoredAddress, newProviderAddress, activeProviderAccounts, error_2, nextChainId, wasDisconnected, providerInfo, effectiveChainId;
|
|
647
|
+
var error_1, address, session, currentStoredAddress, newProviderAddress, activeProviderAccounts, error_2, nextChainId, wasDisconnected, providerInfo, effectiveChainId;
|
|
422
648
|
return __generator(this, function (_a) {
|
|
423
649
|
switch (_a.label) {
|
|
424
650
|
case 0:
|
|
425
651
|
if (!(accounts.length === 0)) return [3 /*break*/, 9];
|
|
652
|
+
this.reopenAdoption(provider);
|
|
426
653
|
if (!(this.wallet.provider === provider)) return [3 /*break*/, 7];
|
|
427
654
|
logger.info("OnAccountsChanged: Detecting disconnect, current state:", {
|
|
428
655
|
evmAddress: this.wallet.evmAddress,
|
|
@@ -445,6 +672,9 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
445
672
|
case 2:
|
|
446
673
|
// Pass EVM state explicitly to ensure we have the data for the disconnect event
|
|
447
674
|
_a.sent();
|
|
675
|
+
// Torn down during the emission: nothing below may run.
|
|
676
|
+
if (this.disposed)
|
|
677
|
+
return [2 /*return*/];
|
|
448
678
|
return [3 /*break*/, 4];
|
|
449
679
|
case 3:
|
|
450
680
|
error_1 = _a.sent();
|
|
@@ -469,6 +699,12 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
469
699
|
logger.warn("onAccountsChanged: Invalid address received", accounts[0]);
|
|
470
700
|
return [2 /*return*/];
|
|
471
701
|
}
|
|
702
|
+
// Before the active-provider gates below: a registered provider that
|
|
703
|
+
// is not the active one can return early without ever reaching the
|
|
704
|
+
// suppressed commit, and its session may never signal again.
|
|
705
|
+
this.awaitingNewSession.delete(provider);
|
|
706
|
+
this.noteRefusalIfSuppressed(provider);
|
|
707
|
+
session = this.sessionGeneration(provider);
|
|
472
708
|
if (!(this.wallet.provider && this.wallet.provider !== provider)) return [3 /*break*/, 26];
|
|
473
709
|
currentStoredAddress = this.wallet.evmAddress;
|
|
474
710
|
newProviderAddress = validateAndChecksumAddress(address);
|
|
@@ -484,12 +720,24 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
484
720
|
return [4 /*yield*/, this.registry.accountsOf(this.wallet.provider)];
|
|
485
721
|
case 11:
|
|
486
722
|
activeProviderAccounts = _a.sent();
|
|
723
|
+
if (this.disposed)
|
|
724
|
+
return [2 /*return*/];
|
|
725
|
+
if (this.sessionGeneration(provider) !== session) {
|
|
726
|
+
// This provider's session ended during the probe: the signal
|
|
727
|
+
// describes nothing that still exists, refusal included.
|
|
728
|
+
this.dropRefusal(provider);
|
|
729
|
+
return [2 /*return*/];
|
|
730
|
+
}
|
|
487
731
|
// The probe is asynchronous too, so check before issuing anything.
|
|
488
732
|
// Every branch below reads the CURRENT evm state, so a switch that
|
|
489
733
|
// went stale during the probe would emit a false disconnect for
|
|
490
734
|
// whoever claimed the namespace, and clear them.
|
|
491
|
-
if (!this.wallet.isCurrent(observation))
|
|
735
|
+
if (!this.wallet.isCurrent(observation)) {
|
|
736
|
+
// Superseded: this signal's refusal, if noted, no longer describes
|
|
737
|
+
// a session the replay may switch to.
|
|
738
|
+
this.dropRefusal(provider);
|
|
492
739
|
return [2 /*return*/];
|
|
740
|
+
}
|
|
493
741
|
logger.info("OnAccountsChanged: Checking current provider accounts", {
|
|
494
742
|
activeProvider: this.registry.infoFor(this.wallet.provider).name,
|
|
495
743
|
accountsLength: activeProviderAccounts
|
|
@@ -515,6 +763,9 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
515
763
|
})];
|
|
516
764
|
case 12:
|
|
517
765
|
_a.sent();
|
|
766
|
+
// Torn down during the emission: nothing below may run.
|
|
767
|
+
if (this.disposed)
|
|
768
|
+
return [2 /*return*/];
|
|
518
769
|
return [3 /*break*/, 14];
|
|
519
770
|
case 13:
|
|
520
771
|
logger.debug("OnAccountsChanged: Disconnect event skipped during provider switch (autocapture.disconnect: false)");
|
|
@@ -522,12 +773,31 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
522
773
|
this.wallet.clear('evm');
|
|
523
774
|
_a.label = 14;
|
|
524
775
|
case 14:
|
|
525
|
-
if (!this.wallet.isCurrent(observation))
|
|
776
|
+
if (!this.wallet.isCurrent(observation)) {
|
|
777
|
+
// Superseded: this signal's refusal, if noted, no longer describes
|
|
778
|
+
// a session the replay may switch to.
|
|
779
|
+
this.dropRefusal(provider);
|
|
526
780
|
return [2 /*return*/];
|
|
781
|
+
}
|
|
527
782
|
// Clear state and let the new provider become active
|
|
528
783
|
this.wallet.clearProvider();
|
|
529
784
|
return [3 /*break*/, 16];
|
|
530
785
|
case 15:
|
|
786
|
+
// Ignored: the active wallet has accounts and this signal's
|
|
787
|
+
// address is the same, or the active address is unknown (a
|
|
788
|
+
// discovered wallet whose identity an opt-out purged; a
|
|
789
|
+
// registered one is re-learned before this point). THIS
|
|
790
|
+
// provider's session is not adopted; it stays pending without
|
|
791
|
+
// its refusal marker, so it is not probed again on every page
|
|
792
|
+
// hit while the active wallet stands, and is adopted once that
|
|
793
|
+
// wallet is gone. A live signal is ignored here in exactly the
|
|
794
|
+
// same way, so the replay changes nothing about who is active.
|
|
795
|
+
// While SUPPRESSED this is the refusal itself, not a verdict:
|
|
796
|
+
// the marker stands for the replay that runs once suppression
|
|
797
|
+
// ends.
|
|
798
|
+
if (!this.deps.isTrackingSuppressed()) {
|
|
799
|
+
this.dropRefusal(provider);
|
|
800
|
+
}
|
|
531
801
|
logger.info("OnAccountsChanged: Current provider still has accounts and same address, ignoring new provider", {
|
|
532
802
|
activeProvider: this.registry.infoFor(this.wallet.provider).name,
|
|
533
803
|
eventProvider: this.registry.infoFor(provider).name,
|
|
@@ -550,6 +820,9 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
550
820
|
})];
|
|
551
821
|
case 18:
|
|
552
822
|
_a.sent();
|
|
823
|
+
// Torn down during the emission: nothing below may run.
|
|
824
|
+
if (this.disposed)
|
|
825
|
+
return [2 /*return*/];
|
|
553
826
|
return [3 /*break*/, 20];
|
|
554
827
|
case 19:
|
|
555
828
|
logger.debug("OnAccountsChanged: Disconnect event skipped for old provider (autocapture.disconnect: false)");
|
|
@@ -557,8 +830,12 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
557
830
|
this.wallet.clear('evm');
|
|
558
831
|
_a.label = 20;
|
|
559
832
|
case 20:
|
|
560
|
-
if (!this.wallet.isCurrent(observation))
|
|
833
|
+
if (!this.wallet.isCurrent(observation)) {
|
|
834
|
+
// Superseded: this signal's refusal, if noted, no longer describes
|
|
835
|
+
// a session the replay may switch to.
|
|
836
|
+
this.dropRefusal(provider);
|
|
561
837
|
return [2 /*return*/];
|
|
838
|
+
}
|
|
562
839
|
_a.label = 21;
|
|
563
840
|
case 21: return [3 /*break*/, 26];
|
|
564
841
|
case 22:
|
|
@@ -579,6 +856,9 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
579
856
|
})];
|
|
580
857
|
case 23:
|
|
581
858
|
_a.sent();
|
|
859
|
+
// Torn down during the emission: nothing below may run.
|
|
860
|
+
if (this.disposed)
|
|
861
|
+
return [2 /*return*/];
|
|
582
862
|
return [3 /*break*/, 25];
|
|
583
863
|
case 24:
|
|
584
864
|
logger.debug("OnAccountsChanged: Disconnect event skipped for failed provider check (autocapture.disconnect: false)");
|
|
@@ -586,8 +866,12 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
586
866
|
this.wallet.clear('evm');
|
|
587
867
|
_a.label = 25;
|
|
588
868
|
case 25:
|
|
589
|
-
if (!this.wallet.isCurrent(observation))
|
|
869
|
+
if (!this.wallet.isCurrent(observation)) {
|
|
870
|
+
// Superseded: this signal's refusal, if noted, no longer describes
|
|
871
|
+
// a session the replay may switch to.
|
|
872
|
+
this.dropRefusal(provider);
|
|
590
873
|
return [2 /*return*/];
|
|
874
|
+
}
|
|
591
875
|
return [3 /*break*/, 26];
|
|
592
876
|
case 26:
|
|
593
877
|
// Set provider if none exists (first connection)
|
|
@@ -596,6 +880,8 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
596
880
|
}
|
|
597
881
|
// If both the provider and address are the same, no-op
|
|
598
882
|
if (this.wallet.provider === provider && address === this.wallet.evmAddress) {
|
|
883
|
+
// This session is the one already known; nothing is pending for it.
|
|
884
|
+
this.settleAdoption(provider);
|
|
599
885
|
return [2 /*return*/];
|
|
600
886
|
}
|
|
601
887
|
nextChainId = this.registry.resolveChainId(provider);
|
|
@@ -606,9 +892,14 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
606
892
|
// events.)
|
|
607
893
|
if (this.deps.isTrackingSuppressed()) {
|
|
608
894
|
this.wallet.clearStaleEvmWalletOnSwitchWhileSuppressed(address);
|
|
895
|
+
// Again after the await: suppression may have begun mid-flight.
|
|
896
|
+
this.noteRefusalIfSuppressed(provider);
|
|
609
897
|
}
|
|
610
898
|
else {
|
|
611
899
|
this.wallet.set('evm', { address: address, chainId: nextChainId });
|
|
900
|
+
// Adopted unsuppressed, whichever path got here first: a retry for
|
|
901
|
+
// this provider would now be a repeat, not a completion.
|
|
902
|
+
this.settleAdoption(provider);
|
|
612
903
|
}
|
|
613
904
|
providerInfo = this.registry.infoFor(provider);
|
|
614
905
|
effectiveChainId = nextChainId || 0;
|
|
@@ -667,6 +958,11 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
667
958
|
return __generator(this, function (_a) {
|
|
668
959
|
switch (_a.label) {
|
|
669
960
|
case 0:
|
|
961
|
+
// A listener that could not be removed at cleanup (its provider's
|
|
962
|
+
// removeListener threw) still fires; it must not touch a torn-down
|
|
963
|
+
// instance.
|
|
964
|
+
if (this.disposed)
|
|
965
|
+
return [2 /*return*/];
|
|
670
966
|
logger.info("onChainChanged", chainIdHex);
|
|
671
967
|
nextChainId = parseChainId(chainIdHex);
|
|
672
968
|
// Record it for THIS provider regardless of which one is active. This is
|
|
@@ -767,9 +1063,16 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
767
1063
|
args[_i] = arguments[_i];
|
|
768
1064
|
}
|
|
769
1065
|
var connection = args[0];
|
|
1066
|
+
if (_this.disposed)
|
|
1067
|
+
return;
|
|
770
1068
|
if (typeof (connection === null || connection === void 0 ? void 0 : connection.chainId) !== "string")
|
|
771
1069
|
return;
|
|
772
1070
|
_this.registry.rememberChain(provider, parseChainId(connection.chainId));
|
|
1071
|
+
_this.awaitingNewSession.delete(provider);
|
|
1072
|
+
// This observer adopts nothing, but a registered provider's connect
|
|
1073
|
+
// refused by suppression is still a refused signal: once suppression
|
|
1074
|
+
// ends, its replay may switch, as the full handler's would.
|
|
1075
|
+
_this.noteRefusalIfSuppressed(provider);
|
|
773
1076
|
};
|
|
774
1077
|
provider.on("connect", listener);
|
|
775
1078
|
this.registry.addListener(provider, "connect", listener);
|
|
@@ -828,6 +1131,9 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
828
1131
|
return __generator(this, function (_a) {
|
|
829
1132
|
switch (_a.label) {
|
|
830
1133
|
case 0:
|
|
1134
|
+
if (this.disposed)
|
|
1135
|
+
return [2 /*return*/];
|
|
1136
|
+
this.reopenAdoption(provider);
|
|
831
1137
|
if (this.wallet.provider !== provider)
|
|
832
1138
|
return [2 /*return*/];
|
|
833
1139
|
// As in the accountsChanged disconnect path: the reported connect ends
|
|
@@ -849,6 +1155,9 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
849
1155
|
case 2:
|
|
850
1156
|
// Pass current state explicitly to ensure we have the data for the disconnect event
|
|
851
1157
|
_a.sent();
|
|
1158
|
+
// Torn down during the emission: nothing below may run.
|
|
1159
|
+
if (this.disposed)
|
|
1160
|
+
return [2 /*return*/];
|
|
852
1161
|
return [3 /*break*/, 4];
|
|
853
1162
|
case 3:
|
|
854
1163
|
e_1 = _a.sent();
|
|
@@ -870,11 +1179,20 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
870
1179
|
};
|
|
871
1180
|
EvmEventTracker.prototype.onConnected = function (provider, connection) {
|
|
872
1181
|
return __awaiter(this, void 0, void 0, function () {
|
|
873
|
-
var disconnectsBefore, stateTicket, chainId, address, committed, movedElsewhere, wasDisconnected, isActiveProvider, providerInfo, effectiveChainId, providerInfo, e_2;
|
|
1182
|
+
var disconnectsBefore, stateTicket, chainId, session, address, committed, movedElsewhere, wasDisconnected, isActiveProvider, providerInfo, effectiveChainId, providerInfo, e_2;
|
|
874
1183
|
return __generator(this, function (_a) {
|
|
875
1184
|
switch (_a.label) {
|
|
876
1185
|
case 0:
|
|
1186
|
+
// A listener that could not be removed at cleanup (its provider's
|
|
1187
|
+
// removeListener threw) still fires; it must not touch a torn-down
|
|
1188
|
+
// instance.
|
|
1189
|
+
if (this.disposed)
|
|
1190
|
+
return [2 /*return*/];
|
|
877
1191
|
logger.info("onConnected", connection);
|
|
1192
|
+
// A session signal, and BEFORE the account lookup below: suppression
|
|
1193
|
+
// that ends while the lookup is in flight must not lose the refusal.
|
|
1194
|
+
this.awaitingNewSession.delete(provider);
|
|
1195
|
+
this.noteRefusalIfSuppressed(provider);
|
|
878
1196
|
disconnectsBefore = this.wallet.disconnectsSoFar("evm");
|
|
879
1197
|
stateTicket = this.wallet.currentObservation("evm");
|
|
880
1198
|
_a.label = 1;
|
|
@@ -885,9 +1203,18 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
885
1203
|
chainId = parseChainId(connection.chainId);
|
|
886
1204
|
// Record it for this provider before anything can bail out below.
|
|
887
1205
|
this.registry.rememberChain(provider, chainId);
|
|
1206
|
+
session = this.sessionGeneration(provider);
|
|
888
1207
|
return [4 /*yield*/, this.registry.addressOf(provider)];
|
|
889
1208
|
case 2:
|
|
890
1209
|
address = _a.sent();
|
|
1210
|
+
if (this.disposed)
|
|
1211
|
+
return [2 /*return*/];
|
|
1212
|
+
if (this.sessionGeneration(provider) !== session) {
|
|
1213
|
+
// Disconnected while the lookup was in flight: a former account
|
|
1214
|
+
// arriving now must not record a refusal for an ended session.
|
|
1215
|
+
this.dropRefusal(provider);
|
|
1216
|
+
return [2 /*return*/];
|
|
1217
|
+
}
|
|
891
1218
|
// A newer signal arrived while we were resolving the address. Claiming
|
|
892
1219
|
// the namespace now would write this stale view over it, and would make
|
|
893
1220
|
// a disconnect still in flight look stale so it skipped its cleanup. A
|
|
@@ -895,6 +1222,7 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
895
1222
|
// is reported normally.
|
|
896
1223
|
if (this.wallet.disconnectsSoFar("evm") !== disconnectsBefore) {
|
|
897
1224
|
logger.info("onConnected: The wallet disconnected after this observation began; dropping it");
|
|
1225
|
+
this.dropRefusal(provider);
|
|
898
1226
|
return [2 /*return*/];
|
|
899
1227
|
}
|
|
900
1228
|
committed = this.wallet.evmAddress;
|
|
@@ -905,10 +1233,15 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
905
1233
|
!this.wallet.isCurrent(stateTicket) &&
|
|
906
1234
|
movedElsewhere) {
|
|
907
1235
|
logger.info("onConnected: A newer signal from this provider has overtaken this connect observation; dropping it");
|
|
1236
|
+
this.dropRefusal(provider);
|
|
908
1237
|
return [2 /*return*/];
|
|
909
1238
|
}
|
|
910
1239
|
if (chainId && address) {
|
|
911
1240
|
wasDisconnected = !this.wallet.evmAddress;
|
|
1241
|
+
// Same refusal as the accounts path, and before the active-provider
|
|
1242
|
+
// gate: a registered provider that connects while another one is
|
|
1243
|
+
// active is not adopted here, and may never signal again.
|
|
1244
|
+
this.noteRefusalIfSuppressed(provider);
|
|
912
1245
|
// Set provider if none exists
|
|
913
1246
|
if (!this.wallet.provider) {
|
|
914
1247
|
this.wallet.provider = provider;
|
|
@@ -920,12 +1253,15 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
920
1253
|
if (isActiveProvider) {
|
|
921
1254
|
if (this.deps.isTrackingSuppressed()) {
|
|
922
1255
|
this.wallet.clearStaleEvmWalletOnSwitchWhileSuppressed(address);
|
|
1256
|
+
// Again after the await: suppression may have begun mid-flight.
|
|
1257
|
+
this.noteRefusalIfSuppressed(provider);
|
|
923
1258
|
}
|
|
924
1259
|
else {
|
|
925
1260
|
this.wallet.set('evm', {
|
|
926
1261
|
chainId: chainId,
|
|
927
1262
|
address: validateAndChecksumAddress(address) || undefined,
|
|
928
1263
|
});
|
|
1264
|
+
this.settleAdoption(provider);
|
|
929
1265
|
}
|
|
930
1266
|
}
|
|
931
1267
|
// Conditionally emit connect event based on tracking configuration.
|
|
@@ -1150,6 +1486,8 @@ var EvmEventTracker = /** @class */ (function () {
|
|
|
1150
1486
|
this.registry.rememberChain(provider, chainId);
|
|
1151
1487
|
};
|
|
1152
1488
|
EvmEventTracker.prototype.untrackProvider = function (provider) {
|
|
1489
|
+
// An untracked provider has nothing left to finish.
|
|
1490
|
+
this.settleAdoption(provider);
|
|
1153
1491
|
try {
|
|
1154
1492
|
this.registry.removeListeners(provider);
|
|
1155
1493
|
// Only stop tracking it if the listeners actually came off. "Tracked"
|