@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.
Files changed (34) hide show
  1. package/dist/cjs/src/FormoAnalytics.d.ts +15 -4
  2. package/dist/cjs/src/FormoAnalytics.js +37 -6
  3. package/dist/cjs/src/FormoAnalyticsProvider.d.ts +8 -0
  4. package/dist/cjs/src/FormoAnalyticsProvider.js +41 -32
  5. package/dist/cjs/src/evm/EvmEventTracker.d.ts +100 -9
  6. package/dist/cjs/src/evm/EvmEventTracker.js +357 -19
  7. package/dist/cjs/src/evm/EvmProviderRegistry.d.ts +34 -2
  8. package/dist/cjs/src/evm/EvmProviderRegistry.js +61 -4
  9. package/dist/cjs/src/evm/EvmRequestTracker.d.ts +21 -4
  10. package/dist/cjs/src/evm/EvmRequestTracker.js +54 -28
  11. package/dist/cjs/src/version.d.ts +1 -1
  12. package/dist/cjs/src/version.js +1 -1
  13. package/dist/cjs/src/wagmi/WagmiEventHandler.d.ts +67 -1
  14. package/dist/cjs/src/wagmi/WagmiEventHandler.js +286 -39
  15. package/dist/cjs/src/wagmi/types.d.ts +6 -0
  16. package/dist/cjs/src/wagmi/utils.js +9 -1
  17. package/dist/esm/src/FormoAnalytics.d.ts +15 -4
  18. package/dist/esm/src/FormoAnalytics.js +37 -6
  19. package/dist/esm/src/FormoAnalyticsProvider.d.ts +8 -0
  20. package/dist/esm/src/FormoAnalyticsProvider.js +39 -31
  21. package/dist/esm/src/evm/EvmEventTracker.d.ts +100 -9
  22. package/dist/esm/src/evm/EvmEventTracker.js +357 -19
  23. package/dist/esm/src/evm/EvmProviderRegistry.d.ts +34 -2
  24. package/dist/esm/src/evm/EvmProviderRegistry.js +61 -4
  25. package/dist/esm/src/evm/EvmRequestTracker.d.ts +21 -4
  26. package/dist/esm/src/evm/EvmRequestTracker.js +54 -28
  27. package/dist/esm/src/version.d.ts +1 -1
  28. package/dist/esm/src/version.js +1 -1
  29. package/dist/esm/src/wagmi/WagmiEventHandler.d.ts +67 -1
  30. package/dist/esm/src/wagmi/WagmiEventHandler.js +286 -39
  31. package/dist/esm/src/wagmi/types.d.ts +6 -0
  32. package/dist/esm/src/wagmi/utils.js +9 -1
  33. package/dist/index.umd.min.js +1 -1
  34. package/package.json +2 -2
@@ -45,6 +45,24 @@ export declare class EvmProviderRegistry {
45
45
  private listeners;
46
46
  /** The window-injected provider, once detected, so it is not re-wrapped. */
47
47
  private injectedDetail?;
48
+ /**
49
+ * Attribution supplied by the integration layer for a provider that was
50
+ * never announced: the wagmi fallback wrap names a connector's provider
51
+ * after the CONNECTOR, so request-derived events carry the same wallet
52
+ * name as the hook-driven events from the same connection. Without it
53
+ * the name came from flag sniffing, and a custom or embedded connector
54
+ * whose provider exposes no recognised flag split one wallet's activity
55
+ * between "Injected Provider" and the connector's name.
56
+ *
57
+ * A RESOLVER, read at each `infoFor`, not a value: the name is live for
58
+ * the connector the integration layer bound it to (a WalletConnect
59
+ * session that resolves or changes its peer renames without a re-wrap),
60
+ * and the integration layer names events on its hook path with the same
61
+ * function, so the two paths cannot disagree. Which connector a
62
+ * provider is bound to is the integration layer's decision; it is not
63
+ * necessarily the connector that is current when the request runs.
64
+ */
65
+ private attributions;
48
66
  constructor(deps: EvmProviderRegistryDeps);
49
67
  get all(): readonly EIP6963ProviderDetail[];
50
68
  isTracked(provider: EIP1193Provider): boolean;
@@ -62,11 +80,25 @@ export declare class EvmProviderRegistry {
62
80
  };
63
81
  /** Add a discovered provider once. Returns false if already present. */
64
82
  add(detail: EIP6963ProviderDetail): boolean;
83
+ /**
84
+ * Record (or, with `undefined`, forget) the integration layer's own
85
+ * attribution resolver for a provider. See `attributions`.
86
+ */
87
+ rememberAttribution(provider: EIP1193Provider | undefined, resolve: (() => {
88
+ name: string;
89
+ rdns?: string;
90
+ } | undefined) | undefined): void;
91
+ /** The supplied attribution for a provider, if any resolves right now. */
92
+ private suppliedAttributionFor;
65
93
  /**
66
94
  * A provider's display name and rdns.
67
95
  *
68
- * EIP-6963 metadata is authoritative when we have it; otherwise fall back to
69
- * sniffing the injected provider, which is all a pre-6963 wallet offers.
96
+ * EIP-6963 metadata is authoritative when we have it. A supplied
97
+ * attribution (the connector a wagmi app connected through) comes next:
98
+ * it describes the SESSION, which is what the hook-driven events report.
99
+ * Otherwise fall back to sniffing the injected provider, which is all a
100
+ * pre-6963 wallet offers; a supplied name without an rdns keeps the
101
+ * sniffed rdns.
70
102
  */
71
103
  infoFor(provider: EIP1193Provider): {
72
104
  name: string;
@@ -77,6 +77,24 @@ var EvmProviderRegistry = /** @class */ (function () {
77
77
  this.chainGenerations = new WeakMap();
78
78
  /** Listeners this SDK attached, so teardown can remove exactly those. */
79
79
  this.listeners = new Map();
80
+ /**
81
+ * Attribution supplied by the integration layer for a provider that was
82
+ * never announced: the wagmi fallback wrap names a connector's provider
83
+ * after the CONNECTOR, so request-derived events carry the same wallet
84
+ * name as the hook-driven events from the same connection. Without it
85
+ * the name came from flag sniffing, and a custom or embedded connector
86
+ * whose provider exposes no recognised flag split one wallet's activity
87
+ * between "Injected Provider" and the connector's name.
88
+ *
89
+ * A RESOLVER, read at each `infoFor`, not a value: the name is live for
90
+ * the connector the integration layer bound it to (a WalletConnect
91
+ * session that resolves or changes its peer renames without a re-wrap),
92
+ * and the integration layer names events on its hook path with the same
93
+ * function, so the two paths cannot disagree. Which connector a
94
+ * provider is bound to is the integration layer's decision; it is not
95
+ * necessarily the connector that is current when the request runs.
96
+ */
97
+ this.attributions = new WeakMap();
80
98
  }
81
99
  Object.defineProperty(EvmProviderRegistry.prototype, "all", {
82
100
  // ── the provider set ─────────────────────────────────────────────────────
@@ -135,19 +153,55 @@ var EvmProviderRegistry = /** @class */ (function () {
135
153
  this.seen.add(provider);
136
154
  return true;
137
155
  };
156
+ /**
157
+ * Record (or, with `undefined`, forget) the integration layer's own
158
+ * attribution resolver for a provider. See `attributions`.
159
+ */
160
+ EvmProviderRegistry.prototype.rememberAttribution = function (provider, resolve) {
161
+ if (!provider)
162
+ return;
163
+ if (!resolve) {
164
+ this.attributions.delete(provider);
165
+ return;
166
+ }
167
+ this.attributions.set(provider, resolve);
168
+ };
169
+ /** The supplied attribution for a provider, if any resolves right now. */
170
+ EvmProviderRegistry.prototype.suppliedAttributionFor = function (provider) {
171
+ var resolve = this.attributions.get(provider);
172
+ if (!resolve)
173
+ return undefined;
174
+ try {
175
+ var info = resolve();
176
+ return (info === null || info === void 0 ? void 0 : info.name) ? info : undefined;
177
+ }
178
+ catch (_a) {
179
+ return undefined;
180
+ }
181
+ };
138
182
  /**
139
183
  * A provider's display name and rdns.
140
184
  *
141
- * EIP-6963 metadata is authoritative when we have it; otherwise fall back to
142
- * sniffing the injected provider, which is all a pre-6963 wallet offers.
185
+ * EIP-6963 metadata is authoritative when we have it. A supplied
186
+ * attribution (the connector a wagmi app connected through) comes next:
187
+ * it describes the SESSION, which is what the hook-driven events report.
188
+ * Otherwise fall back to sniffing the injected provider, which is all a
189
+ * pre-6963 wallet offers; a supplied name without an rdns keeps the
190
+ * sniffed rdns.
143
191
  */
144
192
  EvmProviderRegistry.prototype.infoFor = function (provider) {
145
193
  var announced = this.details.find(function (p) { return p.provider === provider; });
194
+ var supplied = announced
195
+ ? undefined
196
+ : this.suppliedAttributionFor(provider);
146
197
  var info = announced
147
198
  ? { name: announced.info.name, rdns: announced.info.rdns }
148
199
  : (function () {
200
+ var _a;
149
201
  var injected = (0, provider_1.detectInjectedProviderInfo)(provider);
150
- return { name: injected.name, rdns: injected.rdns };
202
+ return supplied
203
+ ? { name: supplied.name, rdns: (_a = supplied.rdns) !== null && _a !== void 0 ? _a : injected.rdns }
204
+ : { name: injected.name, rdns: injected.rdns };
151
205
  })();
152
206
  // WalletConnect names the TRANSPORT; the session's peer names the
153
207
  // wallet. Resolved live, per read: a session established after the
@@ -157,7 +211,10 @@ var EvmProviderRegistry = /** @class */ (function () {
157
211
  // is included because a flagless WalletConnect-compatible provider
158
212
  // registered BEFORE its session exists detects as nothing at all;
159
213
  // the peer appearing later is itself the proof of what it was, so
160
- // the rdns upgrades with it.
214
+ // the rdns upgrades with it. A supplied name gets the same treatment
215
+ // and no more: the integration layer resolves its own peer names
216
+ // where it wants them, and a branded connector must keep its name on
217
+ // both paths.
161
218
  if (info.name === "WalletConnect" || info.name === "Injected Provider") {
162
219
  var peer = (0, provider_1.readWalletConnectPeer)(provider);
163
220
  if (peer === null || peer === void 0 ? void 0 : peer.name) {
@@ -57,6 +57,18 @@ export declare class EvmRequestTracker {
57
57
  * never retry it, and every signature and transaction from that wallet
58
58
  * would be missed for the rest of the session.
59
59
  */
60
+ /** Monotonic creation stamp; owner precedence is decided by it. */
61
+ private static nextCreationSeq;
62
+ readonly creationSeq: number;
63
+ /**
64
+ * Put this tracker into an owner list at its CREATION-ORDER position.
65
+ * Registration can arrive out of order - an older instance's async wrap
66
+ * kick may resolve after a newer instance's - and dispatch picks from
67
+ * the END of the list, so append-on-registration would let resolution
68
+ * order decide which instance owns capture. Creation order is what the
69
+ * newest-live contract promises.
70
+ */
71
+ private insertBySeniority;
60
72
  registerRequestListeners(provider: EIP1193Provider): boolean;
61
73
  /** Install the wrapper function onto the provider; separated so the
62
74
  * routing shim above stays small. */
@@ -71,10 +83,15 @@ export declare class EvmRequestTracker {
71
83
  /**
72
84
  * Wallet attribution for request-derived events.
73
85
  *
74
- * Live per read through the registry, so a WalletConnect session names
75
- * its actual signer ("MetaMask Wallet", "Ledger Live") - the live-test
76
- * rows had provider_name EMPTY on every signature and transaction, which
77
- * made per-wallet activity unanswerable in the warehouse.
86
+ * Resolved through the registry at the START of each request and held
87
+ * for that request's whole lifecycle, receipt included. Reading it per
88
+ * status let a connector switch (two connectors sharing one provider) or
89
+ * a session change made while a prompt was open split one operation
90
+ * between two wallet names. Still live across requests: a WalletConnect
91
+ * session names its actual signer ("MetaMask Wallet", "Ledger Live") -
92
+ * the live-test rows had provider_name EMPTY on every signature and
93
+ * transaction, which made per-wallet activity unanswerable in the
94
+ * warehouse.
78
95
  */
79
96
  private attributionFor;
80
97
  private buildSignatureEventPayload;
@@ -140,6 +140,7 @@ var EvmRequestTracker = /** @class */ (function () {
140
140
  this.disposed = false;
141
141
  /** Providers whose owner list includes this instance; pruned on cleanup. */
142
142
  this.wrappedProviders = new Set();
143
+ this.creationSeq = EvmRequestTracker.nextCreationSeq++;
143
144
  }
144
145
  /** Stop every poll in flight. Terminal, like the event queue's close(). */
145
146
  EvmRequestTracker.prototype.cleanup = function () {
@@ -173,11 +174,24 @@ var EvmRequestTracker = /** @class */ (function () {
173
174
  this.polls.add(timer);
174
175
  };
175
176
  /**
176
- * Wrap a provider's `request`. Returns whether the wrapper is installed:
177
- * a caller that marks the provider as tracked on a false return would
178
- * never retry it, and every signature and transaction from that wallet
179
- * would be missed for the rest of the session.
177
+ * Put this tracker into an owner list at its CREATION-ORDER position.
178
+ * Registration can arrive out of order - an older instance's async wrap
179
+ * kick may resolve after a newer instance's - and dispatch picks from
180
+ * the END of the list, so append-on-registration would let resolution
181
+ * order decide which instance owns capture. Creation order is what the
182
+ * newest-live contract promises.
180
183
  */
184
+ EvmRequestTracker.prototype.insertBySeniority = function (owners) {
185
+ var _this = this;
186
+ var idx = owners.indexOf(this);
187
+ if (idx !== -1)
188
+ owners.splice(idx, 1);
189
+ var insertAt = owners.findIndex(function (o) { return o.creationSeq > _this.creationSeq; });
190
+ if (insertAt === -1)
191
+ owners.push(this);
192
+ else
193
+ owners.splice(insertAt, 0, this);
194
+ };
181
195
  EvmRequestTracker.prototype.registerRequestListeners = function (provider) {
182
196
  var _this = this;
183
197
  logger_1.logger.info("registerRequestListeners");
@@ -199,10 +213,7 @@ var EvmRequestTracker = /** @class */ (function () {
199
213
  logger_1.logger.warn("wrapped without owner list; cannot rebind");
200
214
  return false;
201
215
  }
202
- var idx = owners.indexOf(this);
203
- if (idx !== -1)
204
- owners.splice(idx, 1);
205
- owners.push(this);
216
+ this.insertBySeniority(owners);
206
217
  this.wrappedProviders.add(provider);
207
218
  logger_1.logger.info("Provider already wrapped; rebinding the wrapper to this instance.");
208
219
  return true;
@@ -243,10 +254,7 @@ var EvmRequestTracker = /** @class */ (function () {
243
254
  var slot = provider;
244
255
  var prior = slot[types_1.WRAPPED_REQUEST_OWNER_SYMBOL];
245
256
  var owners = Array.isArray(prior) ? prior : [];
246
- var idx = owners.indexOf(this);
247
- if (idx !== -1)
248
- owners.splice(idx, 1);
249
- owners.push(this);
257
+ this.insertBySeniority(owners);
250
258
  if (!Array.isArray(prior)) {
251
259
  slot[types_1.WRAPPED_REQUEST_OWNER_SYMBOL] = owners;
252
260
  }
@@ -291,7 +299,7 @@ var EvmRequestTracker = /** @class */ (function () {
291
299
  */
292
300
  EvmRequestTracker.prototype.dispatchWrappedRequest = function (_a, provider_2, request_1) {
293
301
  return __awaiter(this, arguments, void 0, function (_b, provider, request) {
294
- var generation_1, responsePromise, capturedChainId_1, response_1, error_1, rpcError, txPromise, txChainId_1, transactionHash_1, error_2, rpcError;
302
+ var generation_1, responsePromise, capturedChainId_1, attribution_1, response_1, error_1, rpcError, txPromise, txChainId_1, attribution_2, transactionHash_1, error_2, rpcError;
295
303
  var _this = this;
296
304
  var _c, _d, _e, _f;
297
305
  var method = _b.method, params = _b.params;
@@ -334,6 +342,7 @@ var EvmRequestTracker = /** @class */ (function () {
334
342
  // below is never reported as unhandled. The real handling is there.
335
343
  responsePromise.catch(function () { return undefined; });
336
344
  capturedChainId_1 = this.registry.resolveChainId(provider);
345
+ attribution_1 = this.attributionFor(provider);
337
346
  // Fire-and-forget tracking
338
347
  (function () { return __awaiter(_this, void 0, void 0, function () {
339
348
  var e_1;
@@ -341,7 +350,7 @@ var EvmRequestTracker = /** @class */ (function () {
341
350
  switch (_a.label) {
342
351
  case 0:
343
352
  _a.trys.push([0, 2, , 3]);
344
- return [4 /*yield*/, this.deps.signature(__assign({ status: types_1.SignatureStatus.REQUESTED }, this.buildSignatureEventPayload(method, params, undefined, capturedChainId_1, provider)), this.attributionFor(provider))];
353
+ return [4 /*yield*/, this.deps.signature(__assign({ status: types_1.SignatureStatus.REQUESTED }, this.buildSignatureEventPayload(method, params, undefined, capturedChainId_1, provider)), attribution_1)];
345
354
  case 1:
346
355
  _a.sent();
347
356
  return [3 /*break*/, 3];
@@ -367,7 +376,7 @@ var EvmRequestTracker = /** @class */ (function () {
367
376
  switch (_a.label) {
368
377
  case 0:
369
378
  _a.trys.push([0, 2, , 3]);
370
- return [4 /*yield*/, this.deps.signature(__assign({ status: types_1.SignatureStatus.CONFIRMED }, this.buildSignatureEventPayload(method, params, response_1, capturedChainId_1, provider)), this.attributionFor(provider))];
379
+ return [4 /*yield*/, this.deps.signature(__assign({ status: types_1.SignatureStatus.CONFIRMED }, this.buildSignatureEventPayload(method, params, response_1, capturedChainId_1, provider)), attribution_1)];
371
380
  case 1:
372
381
  _a.sent();
373
382
  return [3 /*break*/, 3];
@@ -392,7 +401,7 @@ var EvmRequestTracker = /** @class */ (function () {
392
401
  switch (_a.label) {
393
402
  case 0:
394
403
  _a.trys.push([0, 2, , 3]);
395
- return [4 /*yield*/, this.deps.signature(__assign({ status: types_1.SignatureStatus.REJECTED }, this.buildSignatureEventPayload(method, params, undefined, capturedChainId_1, provider)), this.attributionFor(provider))];
404
+ return [4 /*yield*/, this.deps.signature(__assign({ status: types_1.SignatureStatus.REJECTED }, this.buildSignatureEventPayload(method, params, undefined, capturedChainId_1, provider)), attribution_1)];
396
405
  case 1:
397
406
  _a.sent();
398
407
  return [3 /*break*/, 3];
@@ -431,6 +440,7 @@ var EvmRequestTracker = /** @class */ (function () {
431
440
  txPromise = request({ method: method, params: params });
432
441
  txPromise.catch(function () { return undefined; });
433
442
  txChainId_1 = this.registry.resolveChainId(provider);
443
+ attribution_2 = this.attributionFor(provider);
434
444
  (function () { return __awaiter(_this, void 0, void 0, function () {
435
445
  var payload, e_4;
436
446
  return __generator(this, function (_a) {
@@ -440,7 +450,7 @@ var EvmRequestTracker = /** @class */ (function () {
440
450
  return [4 /*yield*/, this.buildTransactionEventPayload(params, provider, txChainId_1)];
441
451
  case 1:
442
452
  payload = _a.sent();
443
- return [4 /*yield*/, this.deps.transaction(__assign({ status: types_1.TransactionStatus.STARTED }, payload), this.attributionFor(provider))];
453
+ return [4 /*yield*/, this.deps.transaction(__assign({ status: types_1.TransactionStatus.STARTED }, payload), attribution_2)];
444
454
  case 2:
445
455
  _a.sent();
446
456
  return [3 /*break*/, 4];
@@ -467,11 +477,11 @@ var EvmRequestTracker = /** @class */ (function () {
467
477
  return [4 /*yield*/, this.buildTransactionEventPayload(params, provider, txChainId_1)];
468
478
  case 1:
469
479
  payload = _a.sent();
470
- return [4 /*yield*/, this.deps.transaction(__assign(__assign({ status: types_1.TransactionStatus.BROADCASTED }, payload), { transactionHash: transactionHash_1 }), this.attributionFor(provider))];
480
+ return [4 /*yield*/, this.deps.transaction(__assign(__assign({ status: types_1.TransactionStatus.BROADCASTED }, payload), { transactionHash: transactionHash_1 }), attribution_2)];
471
481
  case 2:
472
482
  _a.sent();
473
483
  // Start async polling for transaction receipt
474
- this.pollTransactionReceipt(provider, transactionHash_1, payload);
484
+ this.pollTransactionReceipt(provider, transactionHash_1, payload, attribution_2);
475
485
  return [3 /*break*/, 4];
476
486
  case 3:
477
487
  e_5 = _a.sent();
@@ -496,7 +506,7 @@ var EvmRequestTracker = /** @class */ (function () {
496
506
  return [4 /*yield*/, this.buildTransactionEventPayload(params, provider, txChainId_1)];
497
507
  case 1:
498
508
  payload = _a.sent();
499
- return [4 /*yield*/, this.deps.transaction(__assign({ status: types_1.TransactionStatus.REJECTED }, payload), this.attributionFor(provider))];
509
+ return [4 /*yield*/, this.deps.transaction(__assign({ status: types_1.TransactionStatus.REJECTED }, payload), attribution_2)];
500
510
  case 2:
501
511
  _a.sent();
502
512
  return [3 /*break*/, 4];
@@ -518,10 +528,15 @@ var EvmRequestTracker = /** @class */ (function () {
518
528
  /**
519
529
  * Wallet attribution for request-derived events.
520
530
  *
521
- * Live per read through the registry, so a WalletConnect session names
522
- * its actual signer ("MetaMask Wallet", "Ledger Live") - the live-test
523
- * rows had provider_name EMPTY on every signature and transaction, which
524
- * made per-wallet activity unanswerable in the warehouse.
531
+ * Resolved through the registry at the START of each request and held
532
+ * for that request's whole lifecycle, receipt included. Reading it per
533
+ * status let a connector switch (two connectors sharing one provider) or
534
+ * a session change made while a prompt was open split one operation
535
+ * between two wallet names. Still live across requests: a WalletConnect
536
+ * session names its actual signer ("MetaMask Wallet", "Ledger Live") -
537
+ * the live-test rows had provider_name EMPTY on every signature and
538
+ * transaction, which made per-wallet activity unanswerable in the
539
+ * warehouse.
525
540
  */
526
541
  EvmRequestTracker.prototype.attributionFor = function (provider) {
527
542
  var info = this.registry.infoFor(provider);
@@ -591,8 +606,11 @@ var EvmRequestTracker = /** @class */ (function () {
591
606
  /**
592
607
  * Polls for transaction receipt and emits tx.status = CONFIRMED or REVERTED.
593
608
  */
594
- EvmRequestTracker.prototype.pollTransactionReceipt = function (provider_2, transactionHash_2, payload_1) {
595
- return __awaiter(this, arguments, void 0, function (provider, transactionHash, payload, maxAttempts, intervalMs) {
609
+ EvmRequestTracker.prototype.pollTransactionReceipt = function (provider_2, transactionHash_2, payload_1, attribution_3) {
610
+ return __awaiter(this, arguments, void 0, function (provider, transactionHash, payload,
611
+ // Snapshot from the broadcast: a connector or session change during
612
+ // the poll window must not relabel the receipt.
613
+ attribution, maxAttempts, intervalMs) {
596
614
  var attempts, poll;
597
615
  var _this = this;
598
616
  if (maxAttempts === void 0) { maxAttempts = 10; }
@@ -621,7 +639,7 @@ var EvmRequestTracker = /** @class */ (function () {
621
639
  // status: 1 = success, 0 = reverted
622
640
  if (receipt.status === "0x1" || receipt.status === 1) {
623
641
  this.deps
624
- .transaction(__assign(__assign({ status: types_1.TransactionStatus.CONFIRMED }, payload), { transactionHash: transactionHash }), this.attributionFor(provider))
642
+ .transaction(__assign(__assign({ status: types_1.TransactionStatus.CONFIRMED }, payload), { transactionHash: transactionHash }), attribution)
625
643
  .catch(function (e) {
626
644
  return logger_1.logger.error("Formo: Failed to track transaction confirmation", e);
627
645
  });
@@ -629,7 +647,7 @@ var EvmRequestTracker = /** @class */ (function () {
629
647
  }
630
648
  else if (receipt.status === "0x0" || receipt.status === 0) {
631
649
  this.deps
632
- .transaction(__assign(__assign({ status: types_1.TransactionStatus.REVERTED }, payload), { transactionHash: transactionHash }), this.attributionFor(provider))
650
+ .transaction(__assign(__assign({ status: types_1.TransactionStatus.REVERTED }, payload), { transactionHash: transactionHash }), attribution)
633
651
  .catch(function (e) {
634
652
  return logger_1.logger.error("Formo: Failed to track transaction revert", e);
635
653
  });
@@ -851,6 +869,14 @@ var EvmRequestTracker = /** @class */ (function () {
851
869
  });
852
870
  });
853
871
  };
872
+ /**
873
+ * Wrap a provider's `request`. Returns whether the wrapper is installed:
874
+ * a caller that marks the provider as tracked on a false return would
875
+ * never retry it, and every signature and transaction from that wallet
876
+ * would be missed for the rest of the session.
877
+ */
878
+ /** Monotonic creation stamp; owner precedence is decided by it. */
879
+ EvmRequestTracker.nextCreationSeq = 0;
854
880
  return EvmRequestTracker;
855
881
  }());
856
882
  exports.EvmRequestTracker = EvmRequestTracker;
@@ -1,2 +1,2 @@
1
- export declare const version = "1.38.0";
1
+ export declare const version = "1.38.2";
2
2
  //# sourceMappingURL=version.d.ts.map
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
4
  // This file is auto-generated by scripts/update-version.js during npm version
5
5
  // Do not edit manually - it will be overwritten
6
- exports.version = '1.38.0';
6
+ exports.version = '1.38.2';
7
7
  //# sourceMappingURL=version.js.map
@@ -6,7 +6,7 @@
6
6
  * wrapping approach when Wagmi mode is enabled.
7
7
  */
8
8
  import { FormoAnalytics } from "../FormoAnalytics";
9
- import { WagmiConfig, QueryClient } from "./types";
9
+ import { QueryClient, WagmiConfig } from "./types";
10
10
  /**
11
11
  * How long the markers stay trustworthy after the last handler goes away.
12
12
  *
@@ -337,6 +337,35 @@ export declare class WagmiEventHandler {
337
337
  * (still connected through its own connector).
338
338
  */
339
339
  private isAddressConnected;
340
+ /**
341
+ * A specific connector's name and rdns, for the fallback-wrapped
342
+ * provider's request-derived events.
343
+ *
344
+ * The NAME is exactly what the hook path emits for that connector
345
+ * (`getConnectorName`: the live WalletConnect peer for a WalletConnect
346
+ * connector, the connector's own name otherwise), so a branded connector
347
+ * keeps its name on both paths and a session that changes wallets
348
+ * renames on both. The rdns is the connector's when wagmi knows it as
349
+ * ONE value (EIP-6963 discovered connectors carry theirs, some as a
350
+ * one-element list); a connector that matches several rdns values does
351
+ * not say which one this provider is, so nothing is passed and the
352
+ * registry keeps the sniffed one.
353
+ */
354
+ private attributionForConnector;
355
+ /**
356
+ * Resolver handed to the registry at wrap time, read at each request
357
+ * start. BOUND to the connector whose `getProvider` resolved to the
358
+ * wrapped provider, not to whichever connector is current: an app can
359
+ * keep a wallet client over a previous connector's provider and issue a
360
+ * request through it after switching, and that request belongs to the
361
+ * wallet that handles it. The peer name is still read live. A provider
362
+ * SHARED by two connectors is re-bound when the new connector's
363
+ * resolution lands (one microtask for an injected connector); a request
364
+ * issued inside that gap keeps the previous label.
365
+ */
366
+ private boundConnectorAttribution;
367
+ /** `getConnectorName` for a SPECIFIC connector, current or not. */
368
+ private nameForConnector;
340
369
  /**
341
370
  * Get the connector name from Wagmi state
342
371
  */
@@ -362,6 +391,43 @@ export declare class WagmiEventHandler {
362
391
  * dedup. Fire-and-forget per connection; a provider that cannot be
363
392
  * produced simply keeps mutation-only capture.
364
393
  */
394
+ /**
395
+ * Connections THIS instance has wrapped. Deliberately per-instance, not
396
+ * module-level: a module-level guard let a rebuilt SDK instance skip
397
+ * re-wrapping, so ownership stayed with the torn-down instance and every
398
+ * capture died in its closed queue - and it also stopped a second
399
+ * write-key instance from ever registering. Re-wrapping is safe and
400
+ * cheap: the request tracker rebinds ownership of an intact wrapper.
401
+ */
402
+ /**
403
+ * Latest wrap attempt per connector. Every kick re-resolves
404
+ * getProvider() - a connector can hand out a REPLACEMENT provider after
405
+ * a reconnect, so a once-only guard would leave the new session's
406
+ * provider unwrapped forever. Re-wrapping is idempotent: the request
407
+ * tracker rebinds ownership of an intact wrapper. The epoch lets a slow
408
+ * resolution from a superseded kick (an earlier session, an earlier
409
+ * chain) be discarded instead of overwriting fresher state.
410
+ */
411
+ private wrapEpochs;
412
+ /** Consecutive automatic wrap retries per connector; see below. */
413
+ private wrapRetryCounts;
414
+ /** Pending retry timers, cancelled by cleanup(). */
415
+ private wrapRetryTimers;
416
+ /**
417
+ * Bumped on every observed disconnect. Every wrap attempt captures it
418
+ * at kick time and its resolution stands down on a mismatch, so a
419
+ * disconnect invalidates ALL pending wraps at once - including ones
420
+ * whose getProvider() had not resolved yet, which no per-connector
421
+ * bookkeeping can reach because nothing has been recorded for them.
422
+ */
423
+ private wrapSessionGeneration;
424
+ /** The active connector this instance wrapped, and its provider, for
425
+ * chain updates. Kept as a pair so a chain report is only ever applied
426
+ * to the provider of the connector it describes. Keyed by connector,
427
+ * not by connection record: wagmi REPLACES the connection object on
428
+ * every account or chain update, so record identity is not stable. */
429
+ private fallbackConnector?;
430
+ private fallbackProvider?;
365
431
  private wrapActiveConnectorProvider;
366
432
  private kickWalletConnectPeerLookup;
367
433
  /**