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