@formo/analytics 1.35.1 → 1.35.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 +134 -0
- package/dist/cjs/src/FormoAnalytics.js +636 -178
- package/dist/cjs/src/constants/base.d.ts +0 -1
- package/dist/cjs/src/constants/base.js +1 -3
- package/dist/cjs/src/event/EventFactory.js +1 -1
- package/dist/cjs/src/utils/mergeDeepRight.d.ts +22 -0
- package/dist/cjs/src/utils/mergeDeepRight.js +54 -0
- 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 +193 -1
- package/dist/cjs/src/wagmi/WagmiEventHandler.js +1317 -77
- package/dist/cjs/src/wagmi/types.d.ts +6 -0
- package/dist/esm/src/FormoAnalytics.d.ts +134 -0
- package/dist/esm/src/FormoAnalytics.js +636 -178
- package/dist/esm/src/constants/base.d.ts +0 -1
- package/dist/esm/src/constants/base.js +0 -2
- package/dist/esm/src/event/EventFactory.js +1 -1
- package/dist/esm/src/utils/mergeDeepRight.d.ts +22 -0
- package/dist/esm/src/utils/mergeDeepRight.js +51 -0
- 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 +193 -1
- package/dist/esm/src/wagmi/WagmiEventHandler.js +1315 -76
- package/dist/esm/src/wagmi/types.d.ts +6 -0
- package/dist/index.umd.min.js +1 -1
- package/package.json +1 -10
- package/dist/cjs/src/ramda/internal/_curry1.d.ts +0 -10
- package/dist/cjs/src/ramda/internal/_curry1.js +0 -26
- package/dist/cjs/src/ramda/internal/_curry2.d.ts +0 -10
- package/dist/cjs/src/ramda/internal/_curry2.js +0 -43
- package/dist/cjs/src/ramda/internal/_curry3.d.ts +0 -10
- package/dist/cjs/src/ramda/internal/_curry3.js +0 -74
- package/dist/cjs/src/ramda/internal/_has.d.ts +0 -2
- package/dist/cjs/src/ramda/internal/_has.js +0 -7
- package/dist/cjs/src/ramda/internal/_isObject.d.ts +0 -2
- package/dist/cjs/src/ramda/internal/_isObject.js +0 -7
- package/dist/cjs/src/ramda/internal/_isPlaceholder.d.ts +0 -2
- package/dist/cjs/src/ramda/internal/_isPlaceholder.js +0 -7
- package/dist/cjs/src/ramda/mergeDeepRight.d.ts +0 -3
- package/dist/cjs/src/ramda/mergeDeepRight.js +0 -14
- package/dist/cjs/src/ramda/mergeDeepWithKey.d.ts +0 -3
- package/dist/cjs/src/ramda/mergeDeepWithKey.js +0 -20
- package/dist/cjs/src/ramda/mergeWithKey.d.ts +0 -3
- package/dist/cjs/src/ramda/mergeWithKey.js +0 -26
- package/dist/esm/src/ramda/internal/_curry1.d.ts +0 -10
- package/dist/esm/src/ramda/internal/_curry1.js +0 -20
- package/dist/esm/src/ramda/internal/_curry2.d.ts +0 -10
- package/dist/esm/src/ramda/internal/_curry2.js +0 -37
- package/dist/esm/src/ramda/internal/_curry3.d.ts +0 -10
- package/dist/esm/src/ramda/internal/_curry3.js +0 -68
- package/dist/esm/src/ramda/internal/_has.d.ts +0 -2
- package/dist/esm/src/ramda/internal/_has.js +0 -4
- package/dist/esm/src/ramda/internal/_isObject.d.ts +0 -2
- package/dist/esm/src/ramda/internal/_isObject.js +0 -4
- package/dist/esm/src/ramda/internal/_isPlaceholder.d.ts +0 -2
- package/dist/esm/src/ramda/internal/_isPlaceholder.js +0 -4
- package/dist/esm/src/ramda/mergeDeepRight.d.ts +0 -3
- package/dist/esm/src/ramda/mergeDeepRight.js +0 -9
- package/dist/esm/src/ramda/mergeDeepWithKey.d.ts +0 -3
- package/dist/esm/src/ramda/mergeDeepWithKey.js +0 -15
- package/dist/esm/src/ramda/mergeWithKey.d.ts +0 -3
- package/dist/esm/src/ramda/mergeWithKey.js +0 -21
|
@@ -97,6 +97,39 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
97
97
|
evm: {},
|
|
98
98
|
solana: {},
|
|
99
99
|
};
|
|
100
|
+
/**
|
|
101
|
+
* Last known chain per tracked provider, fed by `chainChanged` / `connect`
|
|
102
|
+
* and by a one-off probe at tracking time. Read synchronously when labelling
|
|
103
|
+
* an autocaptured event, so the wallet's request transport is never used for
|
|
104
|
+
* analytics. Weak so an untracked provider can be collected.
|
|
105
|
+
*/
|
|
106
|
+
/**
|
|
107
|
+
* The connect this SDK has actually REPORTED for a provider.
|
|
108
|
+
*
|
|
109
|
+
* Deduplicating on "is an address known" was wrong in both directions.
|
|
110
|
+
* `onConnected` and `onAccountsChanged` both observe one connection, so
|
|
111
|
+
* something has to stop them double-reporting - but an address can be
|
|
112
|
+
* present without a connect ever having been sent: restored from the
|
|
113
|
+
* active-wallet cookie, or reported with an unresolved chain and then
|
|
114
|
+
* refused by `tracking.excludeChains`. Suppressing on address presence lost
|
|
115
|
+
* the connect entirely in those cases.
|
|
116
|
+
*
|
|
117
|
+
* Records what was reported, so a later event can be recognised as a
|
|
118
|
+
* genuine improvement on it rather than a duplicate.
|
|
119
|
+
*/
|
|
120
|
+
this._announcedConnect = new WeakMap();
|
|
121
|
+
this._providerChainIds = new WeakMap();
|
|
122
|
+
/**
|
|
123
|
+
* Bumped on every chain observation, PER PROVIDER. An `eth_chainId` answer
|
|
124
|
+
* that resolves after a newer observation for the same provider must not
|
|
125
|
+
* overwrite it.
|
|
126
|
+
*
|
|
127
|
+
* Deliberately per provider, not per SDK instance: a global counter meant
|
|
128
|
+
* any activity on wallet B discarded a perfectly valid in-flight answer for
|
|
129
|
+
* wallet A, leaving A at chain 0 - and, since an unresolved chain fails
|
|
130
|
+
* closed, dropping all of A's events whenever `excludeChains` is set.
|
|
131
|
+
*/
|
|
132
|
+
this._providerChainGenerations = new WeakMap();
|
|
100
133
|
this._providerListenersMap = new Map();
|
|
101
134
|
/**
|
|
102
135
|
* EIP-6963 provider details discovered through the browser
|
|
@@ -225,11 +258,37 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
225
258
|
return this._chainState.evm.provider;
|
|
226
259
|
},
|
|
227
260
|
set: function (value) {
|
|
261
|
+
var previous = this._chainState.evm.provider;
|
|
262
|
+
// A provider that stops being the active one has, from this SDK's point of
|
|
263
|
+
// view, ended its connection - so the connect it reported must stop
|
|
264
|
+
// counting. Otherwise toggling between two installed wallets silently
|
|
265
|
+
// loses every connect after the first: A's stale record suppresses the
|
|
266
|
+
// connect when the user comes back to it.
|
|
267
|
+
//
|
|
268
|
+
// Done in the setter rather than at each switch site because the active
|
|
269
|
+
// provider is reassigned from several paths - `accountsChanged`,
|
|
270
|
+
// `chainChanged`, `connect`, `handleProviderMismatch`, `untrackProvider` -
|
|
271
|
+
// and any one of them missed would reopen the same hole.
|
|
272
|
+
this.forgetConnectRecord(previous, value);
|
|
228
273
|
this._chainState.evm.provider = value;
|
|
229
274
|
},
|
|
230
275
|
enumerable: false,
|
|
231
276
|
configurable: true
|
|
232
277
|
});
|
|
278
|
+
/**
|
|
279
|
+
* Drop a provider's reported-connect record when it stops being active.
|
|
280
|
+
*
|
|
281
|
+
* The active provider is displaced from several places, and not all of them
|
|
282
|
+
* go through the `_provider` setter: `setChainState()` writes
|
|
283
|
+
* `_chainState.evm.provider` directly and `clearChainState()` replaces the
|
|
284
|
+
* whole namespace. Guarding only the setter left A's record alive across a
|
|
285
|
+
* real A-to-B switch, so returning to A was suppressed.
|
|
286
|
+
*/
|
|
287
|
+
FormoAnalytics.prototype.forgetConnectRecord = function (previous, next) {
|
|
288
|
+
if (previous && previous !== next) {
|
|
289
|
+
this._announcedConnect.delete(previous);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
233
292
|
Object.defineProperty(FormoAnalytics.prototype, "_evmAddress", {
|
|
234
293
|
get: function () {
|
|
235
294
|
return this._chainState.evm.address;
|
|
@@ -846,6 +905,18 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
846
905
|
* Opt out of tracking.
|
|
847
906
|
* @returns {void}
|
|
848
907
|
*/
|
|
908
|
+
/**
|
|
909
|
+
* Whether an event carrying this chain would currently be sent.
|
|
910
|
+
*
|
|
911
|
+
* Exposed for integrations that keep their own "already reported" state.
|
|
912
|
+
* `syncWalletState()` can accept a wallet that `trackEvent()` then drops -
|
|
913
|
+
* `tracking: false`, or a chain in `excludeChains` - and an integration that
|
|
914
|
+
* marked it as reported would stay silent about that wallet even after the
|
|
915
|
+
* configuration changed to allow it.
|
|
916
|
+
*/
|
|
917
|
+
FormoAnalytics.prototype.willTrackEvent = function (chainId) {
|
|
918
|
+
return this.shouldTrack(chainId);
|
|
919
|
+
};
|
|
849
920
|
FormoAnalytics.prototype.optOutTracking = function () {
|
|
850
921
|
logger_1.logger.info("Opting out of tracking");
|
|
851
922
|
// Set opt-out flag in persistent storage using direct cookie access
|
|
@@ -863,9 +934,15 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
863
934
|
* @returns {void}
|
|
864
935
|
*/
|
|
865
936
|
FormoAnalytics.prototype.optInTracking = function () {
|
|
937
|
+
var _a;
|
|
866
938
|
logger_1.logger.info("Opting back into tracking");
|
|
867
939
|
// Remove opt-out flag
|
|
868
940
|
(0, consent_1.removeConsentFlag)(this.writeKey, constants_1.CONSENT_OPT_OUT_KEY);
|
|
941
|
+
// A wallet connected while opted out was declined by syncWalletState, and
|
|
942
|
+
// an unchanged wagmi connection produces no status or chain update to
|
|
943
|
+
// retry on. Without this, opting back in leaves that wallet invisible for
|
|
944
|
+
// the rest of the page load.
|
|
945
|
+
(_a = this.wagmiHandler) === null || _a === void 0 ? void 0 : _a.retryAdoption();
|
|
869
946
|
logger_1.logger.info("Successfully opted back into tracking");
|
|
870
947
|
};
|
|
871
948
|
/**
|
|
@@ -907,20 +984,43 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
907
984
|
// This ensures currentAddress, currentChainId, and _provider are always up-to-date
|
|
908
985
|
// Event emission is controlled conditionally inside the handlers
|
|
909
986
|
this.registerAccountsChangedListener(provider);
|
|
910
|
-
//
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
987
|
+
// `chainChanged` and `connect` are registered UNCONDITIONALLY: they are
|
|
988
|
+
// how this provider's chain is observed, and every signature and
|
|
989
|
+
// transaction has to be labelled with it. Gating registration on
|
|
990
|
+
// `autocapture.chain` conflated observing a chain with reporting one, so
|
|
991
|
+
// `{ chain: false, signature: true }` left the chain frozen at whatever
|
|
992
|
+
// was first seen - a switch to an excluded chain went unnoticed and its
|
|
993
|
+
// signatures were emitted under the old, allowed chain. Whether an
|
|
994
|
+
// event is emitted is decided inside each handler.
|
|
995
|
+
this.registerChainChangedListener(provider);
|
|
914
996
|
if (this.isAutocaptureEnabled("connect")) {
|
|
915
997
|
this.registerConnectListener(provider);
|
|
916
998
|
}
|
|
999
|
+
else {
|
|
1000
|
+
// Observation only. The full connect handler calls `getAddress()`,
|
|
1001
|
+
// which issues `eth_accounts`, and nothing analytics-only may go on
|
|
1002
|
+
// the wallet's transport - a stalled request there sits in front of
|
|
1003
|
+
// the next signature the dapp makes. The chain rides along on the
|
|
1004
|
+
// event itself, so it costs nothing to record.
|
|
1005
|
+
this.registerConnectChainObserver(provider);
|
|
1006
|
+
}
|
|
1007
|
+
// Seed the chain from the provider's own synchronous state if it exposes
|
|
1008
|
+
// one. Deliberately a property read and never an RPC: see
|
|
1009
|
+
// resolveChainIdForProvider for why nothing analytics-only may go on the
|
|
1010
|
+
// wallet's transport.
|
|
1011
|
+
this.seedProviderChainFromState(provider);
|
|
917
1012
|
if (this.isAutocaptureEnabled("signature") || this.isAutocaptureEnabled("transaction")) {
|
|
918
1013
|
this.registerRequestListeners(provider);
|
|
919
1014
|
}
|
|
920
1015
|
else {
|
|
921
1016
|
logger_1.logger.debug("TrackProvider: Skipping request wrapping (both signature and transaction autocapture disabled)");
|
|
922
1017
|
}
|
|
923
|
-
|
|
1018
|
+
// Registered UNCONDITIONALLY: this listener also ends the provider's
|
|
1019
|
+
// reported-connect record, and with `{ connect: true, disconnect: false }`
|
|
1020
|
+
// a wallet that disconnected and reconnected would otherwise find its
|
|
1021
|
+
// old record still standing and have the new connect suppressed. Whether
|
|
1022
|
+
// a disconnect EVENT is emitted is decided inside the handler.
|
|
1023
|
+
{
|
|
924
1024
|
this.registerDisconnectListener(provider);
|
|
925
1025
|
}
|
|
926
1026
|
// Only add to tracked providers after all listeners are successfully registered
|
|
@@ -1014,6 +1114,10 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1014
1114
|
evmChainId: this._evmChainId,
|
|
1015
1115
|
providerMatch: this._provider === provider,
|
|
1016
1116
|
});
|
|
1117
|
+
// The reported connect ends with the connection, so a genuine
|
|
1118
|
+
// reconnect later reports again rather than being taken for a
|
|
1119
|
+
// duplicate.
|
|
1120
|
+
this._announcedConnect.delete(provider);
|
|
1017
1121
|
if (!this.isAutocaptureEnabled("disconnect")) return [3 /*break*/, 5];
|
|
1018
1122
|
_a.label = 1;
|
|
1019
1123
|
case 1:
|
|
@@ -1162,9 +1266,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1162
1266
|
if (this._provider === provider && address === this._evmAddress) {
|
|
1163
1267
|
return [2 /*return*/];
|
|
1164
1268
|
}
|
|
1165
|
-
|
|
1166
|
-
case 26:
|
|
1167
|
-
nextChainId = _a.sent();
|
|
1269
|
+
nextChainId = this.resolveChainIdForProvider(provider);
|
|
1168
1270
|
wasDisconnected = !this._evmAddress;
|
|
1169
1271
|
// Update state regardless of whether connect *event* tracking is enabled,
|
|
1170
1272
|
// so disconnect events keep valid address/chainId values. (excludeChains is
|
|
@@ -1178,7 +1280,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1178
1280
|
}
|
|
1179
1281
|
providerInfo = this.getProviderInfo(provider);
|
|
1180
1282
|
effectiveChainId = nextChainId || 0;
|
|
1181
|
-
if (this.isAutocaptureEnabled("connect")
|
|
1283
|
+
if (this.isAutocaptureEnabled("connect") &&
|
|
1284
|
+
this.shouldReportConnect(provider, address)) {
|
|
1182
1285
|
logger_1.logger.info("OnAccountsChanged: Detected wallet connection, emitting connect event", {
|
|
1183
1286
|
chainId: nextChainId,
|
|
1184
1287
|
address: address,
|
|
@@ -1190,6 +1293,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1190
1293
|
if (effectiveChainId === 0) {
|
|
1191
1294
|
logger_1.logger.info("OnAccountsChanged: Using fallback chainId 0 for connect event");
|
|
1192
1295
|
}
|
|
1296
|
+
this.markConnectReported(provider, address, effectiveChainId);
|
|
1193
1297
|
this.connect({
|
|
1194
1298
|
chainId: effectiveChainId,
|
|
1195
1299
|
address: address,
|
|
@@ -1227,46 +1331,140 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1227
1331
|
};
|
|
1228
1332
|
FormoAnalytics.prototype.onChainChanged = function (provider, chainIdHex) {
|
|
1229
1333
|
return __awaiter(this, void 0, void 0, function () {
|
|
1230
|
-
var nextChainId;
|
|
1334
|
+
var nextChainId, error_3;
|
|
1231
1335
|
return __generator(this, function (_a) {
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1336
|
+
switch (_a.label) {
|
|
1337
|
+
case 0:
|
|
1338
|
+
logger_1.logger.info("onChainChanged", chainIdHex);
|
|
1339
|
+
nextChainId = (0, chain_1.parseChainId)(chainIdHex);
|
|
1340
|
+
// Record it for THIS provider regardless of which one is active. This is
|
|
1341
|
+
// the only way an autocaptured event from a non-active wallet can learn
|
|
1342
|
+
// its chain without putting an RPC on that wallet's transport.
|
|
1343
|
+
this.rememberProviderChain(provider, nextChainId);
|
|
1344
|
+
// Beyond that, a chain event from a NON-active provider is observation
|
|
1345
|
+
// only when chain autocapture is off.
|
|
1346
|
+
//
|
|
1347
|
+
// This listener is now registered unconditionally, so that a signature can
|
|
1348
|
+
// be labelled with its signer's chain. `handleProviderMismatch()` treats a
|
|
1349
|
+
// chain event from another wallet as a wallet switch and clears the active
|
|
1350
|
+
// wallet's address and chain. That is the established behaviour of the
|
|
1351
|
+
// chain feature and stays exactly as it was, but it must not start firing
|
|
1352
|
+
// for apps that never asked for chain tracking: a second wallet switching
|
|
1353
|
+
// network would silently erase the active wallet's attribution.
|
|
1354
|
+
// Observation only when chain autocapture is off, whether or not an
|
|
1355
|
+
// active provider has been established yet.
|
|
1356
|
+
//
|
|
1357
|
+
// `isProviderMismatch()` is false while `_provider` is undefined, which is
|
|
1358
|
+
// exactly the state left by restoring a wallet from the active-wallet
|
|
1359
|
+
// cookie. A background wallet's `chainChanged` could therefore claim the
|
|
1360
|
+
// active slot and overwrite the restored wallet's chain - suppressing
|
|
1361
|
+
// allowed events, or letting excluded ones through. The active provider is
|
|
1362
|
+
// established by an actual account/connect/request association, not by
|
|
1363
|
+
// another wallet changing network.
|
|
1364
|
+
if (!this.isAutocaptureEnabled("chain") && provider !== this._provider) {
|
|
1365
|
+
return [2 /*return*/];
|
|
1366
|
+
}
|
|
1367
|
+
// Only handle chain changes for the active provider (or if none is set yet)
|
|
1368
|
+
if (this.isProviderMismatch(provider)) {
|
|
1369
|
+
this.handleProviderMismatch(provider);
|
|
1370
|
+
}
|
|
1371
|
+
// Chain changes only matter for connected users
|
|
1372
|
+
if (!this._evmAddress) {
|
|
1373
|
+
logger_1.logger.info("OnChainChanged: No current address, user appears disconnected");
|
|
1374
|
+
return [2 /*return*/, Promise.resolve()];
|
|
1375
|
+
}
|
|
1376
|
+
// Set provider if none exists
|
|
1377
|
+
if (!this._provider) {
|
|
1378
|
+
this._provider = provider;
|
|
1379
|
+
}
|
|
1380
|
+
this.setChainState('evm', { chainId: nextChainId });
|
|
1381
|
+
_a.label = 1;
|
|
1382
|
+
case 1:
|
|
1383
|
+
_a.trys.push([1, 5, , 6]);
|
|
1384
|
+
if (!this.isAutocaptureEnabled("chain")) return [3 /*break*/, 3];
|
|
1385
|
+
// Awaited, so a failing emission is caught below rather than escaping
|
|
1386
|
+
// as an unhandled rejection out of the provider's event listener.
|
|
1387
|
+
// `return`ing the promise left the catch here unreachable.
|
|
1388
|
+
return [4 /*yield*/, this.chain({
|
|
1252
1389
|
chainId: nextChainId,
|
|
1253
1390
|
address: this._evmAddress,
|
|
1254
1391
|
})];
|
|
1255
|
-
|
|
1256
|
-
|
|
1392
|
+
case 2:
|
|
1393
|
+
// Awaited, so a failing emission is caught below rather than escaping
|
|
1394
|
+
// as an unhandled rejection out of the provider's event listener.
|
|
1395
|
+
// `return`ing the promise left the catch here unreachable.
|
|
1396
|
+
_a.sent();
|
|
1397
|
+
return [3 /*break*/, 4];
|
|
1398
|
+
case 3:
|
|
1257
1399
|
logger_1.logger.debug("OnChainChanged: Chain event skipped (autocapture.chain: false)", {
|
|
1258
1400
|
chainId: this._evmChainId,
|
|
1259
1401
|
address: this._evmAddress,
|
|
1260
1402
|
});
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1403
|
+
_a.label = 4;
|
|
1404
|
+
case 4: return [3 /*break*/, 6];
|
|
1405
|
+
case 5:
|
|
1406
|
+
error_3 = _a.sent();
|
|
1407
|
+
logger_1.logger.error("OnChainChanged: Failed to emit chain event:", error_3);
|
|
1408
|
+
return [3 /*break*/, 6];
|
|
1409
|
+
case 6: return [2 /*return*/];
|
|
1265
1410
|
}
|
|
1266
|
-
return [2 /*return*/];
|
|
1267
1411
|
});
|
|
1268
1412
|
});
|
|
1269
1413
|
};
|
|
1414
|
+
/**
|
|
1415
|
+
* Record a provider's chain from its `connect` event, and nothing else.
|
|
1416
|
+
*
|
|
1417
|
+
* Used when connect autocapture is off. `connect` carries `chainId` in its
|
|
1418
|
+
* payload, so this needs no RPC - unlike the full handler, which resolves
|
|
1419
|
+
* the account.
|
|
1420
|
+
*/
|
|
1421
|
+
FormoAnalytics.prototype.registerConnectChainObserver = function (provider) {
|
|
1422
|
+
var _this = this;
|
|
1423
|
+
var listener = function () {
|
|
1424
|
+
var args = [];
|
|
1425
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1426
|
+
args[_i] = arguments[_i];
|
|
1427
|
+
}
|
|
1428
|
+
var connection = args[0];
|
|
1429
|
+
if (typeof (connection === null || connection === void 0 ? void 0 : connection.chainId) !== "string")
|
|
1430
|
+
return;
|
|
1431
|
+
_this.rememberProviderChain(provider, (0, chain_1.parseChainId)(connection.chainId));
|
|
1432
|
+
};
|
|
1433
|
+
provider.on("connect", listener);
|
|
1434
|
+
this.addProviderListener(provider, "connect", listener);
|
|
1435
|
+
};
|
|
1436
|
+
/**
|
|
1437
|
+
* Whether a connect for this wallet still needs reporting.
|
|
1438
|
+
*
|
|
1439
|
+
* True when nothing has been reported for this provider, or when the account
|
|
1440
|
+
* changed. A wallet already reported is not reported again.
|
|
1441
|
+
*
|
|
1442
|
+
* Deliberately does NOT re-report to correct a chain. When `accountsChanged`
|
|
1443
|
+
* wins the race on a provider that exposes no synchronous `chainId`, the
|
|
1444
|
+
* connect carries 0 - honestly, since the chain is unknown at that instant -
|
|
1445
|
+
* and the `connect` payload that follows knows the real one. Emitting again
|
|
1446
|
+
* to relabel would mean two connects for one connection, which is the bug
|
|
1447
|
+
* this whole path exists to prevent. That payload still corrects
|
|
1448
|
+
* `currentChainId`, so everything after it is attributed properly.
|
|
1449
|
+
*/
|
|
1450
|
+
FormoAnalytics.prototype.shouldReportConnect = function (provider, address) {
|
|
1451
|
+
var reported = this._announcedConnect.get(provider);
|
|
1452
|
+
if (!reported)
|
|
1453
|
+
return true;
|
|
1454
|
+
return reported.address.toLowerCase() !== address.toLowerCase();
|
|
1455
|
+
};
|
|
1456
|
+
/**
|
|
1457
|
+
* Record a connect as reported - but only if it will actually be sent.
|
|
1458
|
+
*
|
|
1459
|
+
* `connect()` passes through `shouldTrack()`, which refuses an unresolvable
|
|
1460
|
+
* chain when `tracking.excludeChains` is configured. Marking a refused event
|
|
1461
|
+
* as reported would suppress the authoritative one that follows.
|
|
1462
|
+
*/
|
|
1463
|
+
FormoAnalytics.prototype.markConnectReported = function (provider, address, chainId) {
|
|
1464
|
+
if (!this.willTrackEvent(chainId))
|
|
1465
|
+
return;
|
|
1466
|
+
this._announcedConnect.set(provider, { address: address, chainId: chainId });
|
|
1467
|
+
};
|
|
1270
1468
|
FormoAnalytics.prototype.registerConnectListener = function (provider) {
|
|
1271
1469
|
var _this = this;
|
|
1272
1470
|
logger_1.logger.info("registerConnectListener");
|
|
@@ -1291,6 +1489,9 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1291
1489
|
case 0:
|
|
1292
1490
|
if (this._provider !== provider)
|
|
1293
1491
|
return [2 /*return*/];
|
|
1492
|
+
// As in the accountsChanged disconnect path: the reported connect ends
|
|
1493
|
+
// with the connection.
|
|
1494
|
+
this._announcedConnect.delete(provider);
|
|
1294
1495
|
logger_1.logger.info("OnDisconnect: Wallet disconnect event received, current state:", {
|
|
1295
1496
|
currentAddress: this._evmAddress,
|
|
1296
1497
|
currentChainId: this._evmChainId,
|
|
@@ -1338,6 +1539,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1338
1539
|
if (!(connection === null || connection === void 0 ? void 0 : connection.chainId) || typeof connection.chainId !== "string")
|
|
1339
1540
|
return [2 /*return*/];
|
|
1340
1541
|
chainId = (0, chain_1.parseChainId)(connection.chainId);
|
|
1542
|
+
// Record it for this provider before anything can bail out below.
|
|
1543
|
+
this.rememberProviderChain(provider, chainId);
|
|
1341
1544
|
return [4 /*yield*/, this.getAddress(provider)];
|
|
1342
1545
|
case 2:
|
|
1343
1546
|
address = _a.sent();
|
|
@@ -1362,8 +1565,18 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1362
1565
|
});
|
|
1363
1566
|
}
|
|
1364
1567
|
}
|
|
1365
|
-
// Conditionally emit connect event based on tracking configuration
|
|
1366
|
-
|
|
1568
|
+
// Conditionally emit connect event based on tracking configuration.
|
|
1569
|
+
//
|
|
1570
|
+
// Both handlers observe one connection, so `shouldReportConnect()`
|
|
1571
|
+
// decides which of them reports it. It keys on what was actually
|
|
1572
|
+
// REPORTED, not on whether an address is known: an address can be
|
|
1573
|
+
// present with no connect ever sent - restored from the active-wallet
|
|
1574
|
+
// cookie, or reported with an unresolved chain and then refused by
|
|
1575
|
+
// `excludeChains` - and this payload carries the authoritative chain,
|
|
1576
|
+
// so it must be able to supersede such a report.
|
|
1577
|
+
if (isActiveProvider &&
|
|
1578
|
+
this._evmAddress &&
|
|
1579
|
+
this.shouldReportConnect(provider, address)) {
|
|
1367
1580
|
providerInfo = this.getProviderInfo(provider);
|
|
1368
1581
|
effectiveChainId = chainId || 0;
|
|
1369
1582
|
if (this.isAutocaptureEnabled("connect")) {
|
|
@@ -1378,6 +1591,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1378
1591
|
if (effectiveChainId === 0) {
|
|
1379
1592
|
logger_1.logger.info("OnConnected: Using fallback chainId 0 for connect event");
|
|
1380
1593
|
}
|
|
1594
|
+
this.markConnectReported(provider, address, effectiveChainId);
|
|
1381
1595
|
this.connect({
|
|
1382
1596
|
chainId: effectiveChainId,
|
|
1383
1597
|
address: address,
|
|
@@ -1434,162 +1648,209 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1434
1648
|
}
|
|
1435
1649
|
var request = provider.request.bind(provider);
|
|
1436
1650
|
var wrappedRequest = function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
|
|
1437
|
-
var
|
|
1651
|
+
var generation_1, responsePromise, capturedChainId_1, response_1, error_4, rpcError, txPromise, txChainId_1, transactionHash_1, error_5, rpcError;
|
|
1438
1652
|
var _this = this;
|
|
1653
|
+
var _c;
|
|
1439
1654
|
var method = _b.method, params = _b.params;
|
|
1440
1655
|
return __generator(this, function (_d) {
|
|
1441
1656
|
switch (_d.label) {
|
|
1442
1657
|
case 0:
|
|
1658
|
+
// Learn the chain from a call the APP was making anyway.
|
|
1659
|
+
//
|
|
1660
|
+
// A standards-compliant provider need not expose a synchronous `chainId`
|
|
1661
|
+
// property, and if it connected before the SDK initialised, its
|
|
1662
|
+
// `connect` event is never replayed. Such a provider stayed unknown -
|
|
1663
|
+
// reported as chain 0, and with `excludeChains` configured its events
|
|
1664
|
+
// were dropped even on an allowed chain. This adds no request of its
|
|
1665
|
+
// own; it only reads the answer to one the dapp already sent.
|
|
1666
|
+
if (method === "eth_chainId") {
|
|
1667
|
+
generation_1 = (_c = this._providerChainGenerations.get(provider)) !== null && _c !== void 0 ? _c : 0;
|
|
1668
|
+
return [2 /*return*/, request({ method: method, params: params }).then(function (result) {
|
|
1669
|
+
var _a;
|
|
1670
|
+
// A `chainChanged` for THIS provider may have landed while this was
|
|
1671
|
+
// in flight. It is newer by definition, so it must not be
|
|
1672
|
+
// overwritten by this answer.
|
|
1673
|
+
if (generation_1 === ((_a = _this._providerChainGenerations.get(provider)) !== null && _a !== void 0 ? _a : 0) &&
|
|
1674
|
+
typeof result === "string") {
|
|
1675
|
+
_this.rememberProviderChain(provider, (0, chain_1.parseChainId)(result));
|
|
1676
|
+
}
|
|
1677
|
+
return result;
|
|
1678
|
+
})];
|
|
1679
|
+
}
|
|
1443
1680
|
if (!(Array.isArray(params) &&
|
|
1444
|
-
["eth_signTypedData_v4", "personal_sign"].includes(method))) return [3 /*break*/,
|
|
1681
|
+
["eth_signTypedData_v4", "personal_sign"].includes(method))) return [3 /*break*/, 4];
|
|
1445
1682
|
if (!this.isAutocaptureEnabled("signature")) {
|
|
1446
1683
|
logger_1.logger.debug("Signature event skipped (autocapture.signature: false)", { method: method });
|
|
1447
1684
|
return [2 /*return*/, request({ method: method, params: params })];
|
|
1448
1685
|
}
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
_d.label = 2;
|
|
1455
|
-
case 2:
|
|
1456
|
-
capturedChainId_1 = _c;
|
|
1686
|
+
responsePromise = request({ method: method, params: params });
|
|
1687
|
+
// Attach a no-op handler now so a rejection arriving before the await
|
|
1688
|
+
// below is never reported as unhandled. The real handling is there.
|
|
1689
|
+
responsePromise.catch(function () { return undefined; });
|
|
1690
|
+
capturedChainId_1 = this.resolveChainIdForProvider(provider);
|
|
1457
1691
|
// Fire-and-forget tracking
|
|
1458
1692
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1693
|
+
var e_4;
|
|
1459
1694
|
return __generator(this, function (_a) {
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1695
|
+
switch (_a.label) {
|
|
1696
|
+
case 0:
|
|
1697
|
+
_a.trys.push([0, 2, , 3]);
|
|
1698
|
+
return [4 /*yield*/, this.signature(__assign({ status: types_1.SignatureStatus.REQUESTED }, this.buildSignatureEventPayload(method, params, undefined, capturedChainId_1, provider)))];
|
|
1699
|
+
case 1:
|
|
1700
|
+
_a.sent();
|
|
1701
|
+
return [3 /*break*/, 3];
|
|
1702
|
+
case 2:
|
|
1703
|
+
e_4 = _a.sent();
|
|
1704
|
+
logger_1.logger.error("Formo: Failed to track signature request", e_4);
|
|
1705
|
+
return [3 /*break*/, 3];
|
|
1706
|
+
case 3: return [2 /*return*/];
|
|
1465
1707
|
}
|
|
1466
|
-
return [2 /*return*/];
|
|
1467
1708
|
});
|
|
1468
1709
|
}); })();
|
|
1469
|
-
_d.label =
|
|
1470
|
-
case
|
|
1471
|
-
_d.trys.push([
|
|
1472
|
-
return [4 /*yield*/,
|
|
1473
|
-
case
|
|
1474
|
-
response_1 =
|
|
1710
|
+
_d.label = 1;
|
|
1711
|
+
case 1:
|
|
1712
|
+
_d.trys.push([1, 3, , 4]);
|
|
1713
|
+
return [4 /*yield*/, responsePromise];
|
|
1714
|
+
case 2:
|
|
1715
|
+
response_1 = _d.sent();
|
|
1475
1716
|
// Track signature confirmation only for truthy responses
|
|
1476
1717
|
if (response_1) {
|
|
1477
1718
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1719
|
+
var e_5;
|
|
1478
1720
|
return __generator(this, function (_a) {
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1721
|
+
switch (_a.label) {
|
|
1722
|
+
case 0:
|
|
1723
|
+
_a.trys.push([0, 2, , 3]);
|
|
1724
|
+
return [4 /*yield*/, this.signature(__assign({ status: types_1.SignatureStatus.CONFIRMED }, this.buildSignatureEventPayload(method, params, response_1, capturedChainId_1, provider)))];
|
|
1725
|
+
case 1:
|
|
1726
|
+
_a.sent();
|
|
1727
|
+
return [3 /*break*/, 3];
|
|
1728
|
+
case 2:
|
|
1729
|
+
e_5 = _a.sent();
|
|
1730
|
+
logger_1.logger.error("Formo: Failed to track signature confirmation", e_5);
|
|
1731
|
+
return [3 /*break*/, 3];
|
|
1732
|
+
case 3: return [2 /*return*/];
|
|
1484
1733
|
}
|
|
1485
|
-
return [2 /*return*/];
|
|
1486
1734
|
});
|
|
1487
1735
|
}); })();
|
|
1488
1736
|
}
|
|
1489
1737
|
return [2 /*return*/, response_1];
|
|
1490
|
-
case
|
|
1491
|
-
|
|
1492
|
-
rpcError =
|
|
1738
|
+
case 3:
|
|
1739
|
+
error_4 = _d.sent();
|
|
1740
|
+
rpcError = error_4;
|
|
1493
1741
|
if ((rpcError === null || rpcError === void 0 ? void 0 : rpcError.code) === 4001) {
|
|
1494
1742
|
// Use the already cast rpcError to avoid duplication
|
|
1495
1743
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1744
|
+
var e_6;
|
|
1496
1745
|
return __generator(this, function (_a) {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1746
|
+
switch (_a.label) {
|
|
1747
|
+
case 0:
|
|
1748
|
+
_a.trys.push([0, 2, , 3]);
|
|
1749
|
+
return [4 /*yield*/, this.signature(__assign({ status: types_1.SignatureStatus.REJECTED }, this.buildSignatureEventPayload(method, params, undefined, capturedChainId_1, provider)))];
|
|
1750
|
+
case 1:
|
|
1751
|
+
_a.sent();
|
|
1752
|
+
return [3 /*break*/, 3];
|
|
1753
|
+
case 2:
|
|
1754
|
+
e_6 = _a.sent();
|
|
1755
|
+
logger_1.logger.error("Formo: Failed to track signature rejection", e_6);
|
|
1756
|
+
return [3 /*break*/, 3];
|
|
1757
|
+
case 3: return [2 /*return*/];
|
|
1502
1758
|
}
|
|
1503
|
-
return [2 /*return*/];
|
|
1504
1759
|
});
|
|
1505
1760
|
}); })();
|
|
1506
1761
|
}
|
|
1507
|
-
throw
|
|
1508
|
-
case
|
|
1762
|
+
throw error_4;
|
|
1763
|
+
case 4:
|
|
1509
1764
|
if (!(Array.isArray(params) &&
|
|
1510
1765
|
method === "eth_sendTransaction" &&
|
|
1511
|
-
params[0])) return [3 /*break*/,
|
|
1766
|
+
params[0])) return [3 /*break*/, 8];
|
|
1512
1767
|
if (!this.isAutocaptureEnabled("transaction")) {
|
|
1513
1768
|
logger_1.logger.debug("Transaction event skipped (autocapture.transaction: false)", { method: method });
|
|
1514
1769
|
return [2 /*return*/, request({ method: method, params: params })];
|
|
1515
1770
|
}
|
|
1771
|
+
txPromise = request({ method: method, params: params });
|
|
1772
|
+
txPromise.catch(function () { return undefined; });
|
|
1773
|
+
txChainId_1 = this.resolveChainIdForProvider(provider);
|
|
1516
1774
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1517
|
-
var payload,
|
|
1775
|
+
var payload, e_7;
|
|
1518
1776
|
return __generator(this, function (_a) {
|
|
1519
1777
|
switch (_a.label) {
|
|
1520
1778
|
case 0:
|
|
1521
|
-
_a.trys.push([0,
|
|
1522
|
-
return [4 /*yield*/, this.buildTransactionEventPayload(params, provider)];
|
|
1779
|
+
_a.trys.push([0, 3, , 4]);
|
|
1780
|
+
return [4 /*yield*/, this.buildTransactionEventPayload(params, provider, txChainId_1)];
|
|
1523
1781
|
case 1:
|
|
1524
1782
|
payload = _a.sent();
|
|
1525
|
-
this.transaction(__assign({ status: types_1.TransactionStatus.STARTED }, payload));
|
|
1526
|
-
return [3 /*break*/, 3];
|
|
1783
|
+
return [4 /*yield*/, this.transaction(__assign({ status: types_1.TransactionStatus.STARTED }, payload))];
|
|
1527
1784
|
case 2:
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1785
|
+
_a.sent();
|
|
1786
|
+
return [3 /*break*/, 4];
|
|
1787
|
+
case 3:
|
|
1788
|
+
e_7 = _a.sent();
|
|
1789
|
+
logger_1.logger.error("Formo: Failed to track transaction start", e_7);
|
|
1790
|
+
return [3 /*break*/, 4];
|
|
1791
|
+
case 4: return [2 /*return*/];
|
|
1532
1792
|
}
|
|
1533
1793
|
});
|
|
1534
1794
|
}); })();
|
|
1535
|
-
_d.label =
|
|
1536
|
-
case
|
|
1537
|
-
_d.trys.push([
|
|
1538
|
-
return [4 /*yield*/,
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
})];
|
|
1542
|
-
case 8:
|
|
1543
|
-
transactionHash_1 = (_d.sent());
|
|
1795
|
+
_d.label = 5;
|
|
1796
|
+
case 5:
|
|
1797
|
+
_d.trys.push([5, 7, , 8]);
|
|
1798
|
+
return [4 /*yield*/, txPromise];
|
|
1799
|
+
case 6:
|
|
1800
|
+
transactionHash_1 = _d.sent();
|
|
1544
1801
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1545
|
-
var payload,
|
|
1802
|
+
var payload, e_8;
|
|
1546
1803
|
return __generator(this, function (_a) {
|
|
1547
1804
|
switch (_a.label) {
|
|
1548
1805
|
case 0:
|
|
1549
|
-
_a.trys.push([0,
|
|
1550
|
-
return [4 /*yield*/, this.buildTransactionEventPayload(params, provider)];
|
|
1806
|
+
_a.trys.push([0, 3, , 4]);
|
|
1807
|
+
return [4 /*yield*/, this.buildTransactionEventPayload(params, provider, txChainId_1)];
|
|
1551
1808
|
case 1:
|
|
1552
1809
|
payload = _a.sent();
|
|
1553
|
-
this.transaction(__assign(__assign({ status: types_1.TransactionStatus.BROADCASTED }, payload), { transactionHash: transactionHash_1 }));
|
|
1810
|
+
return [4 /*yield*/, this.transaction(__assign(__assign({ status: types_1.TransactionStatus.BROADCASTED }, payload), { transactionHash: transactionHash_1 }))];
|
|
1811
|
+
case 2:
|
|
1812
|
+
_a.sent();
|
|
1554
1813
|
// Start async polling for transaction receipt
|
|
1555
1814
|
this.pollTransactionReceipt(provider, transactionHash_1, payload);
|
|
1556
|
-
return [3 /*break*/,
|
|
1557
|
-
case
|
|
1558
|
-
|
|
1559
|
-
logger_1.logger.error("Formo: Failed to track transaction broadcast",
|
|
1560
|
-
return [3 /*break*/,
|
|
1561
|
-
case
|
|
1815
|
+
return [3 /*break*/, 4];
|
|
1816
|
+
case 3:
|
|
1817
|
+
e_8 = _a.sent();
|
|
1818
|
+
logger_1.logger.error("Formo: Failed to track transaction broadcast", e_8);
|
|
1819
|
+
return [3 /*break*/, 4];
|
|
1820
|
+
case 4: return [2 /*return*/];
|
|
1562
1821
|
}
|
|
1563
1822
|
});
|
|
1564
1823
|
}); })();
|
|
1565
1824
|
return [2 /*return*/, transactionHash_1];
|
|
1566
|
-
case
|
|
1567
|
-
|
|
1568
|
-
rpcError =
|
|
1825
|
+
case 7:
|
|
1826
|
+
error_5 = _d.sent();
|
|
1827
|
+
rpcError = error_5;
|
|
1569
1828
|
if ((rpcError === null || rpcError === void 0 ? void 0 : rpcError.code) === 4001) {
|
|
1570
1829
|
// Use the already cast rpcError to avoid duplication
|
|
1571
1830
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1572
|
-
var payload,
|
|
1831
|
+
var payload, e_9;
|
|
1573
1832
|
return __generator(this, function (_a) {
|
|
1574
1833
|
switch (_a.label) {
|
|
1575
1834
|
case 0:
|
|
1576
|
-
_a.trys.push([0,
|
|
1577
|
-
return [4 /*yield*/, this.buildTransactionEventPayload(params, provider)];
|
|
1835
|
+
_a.trys.push([0, 3, , 4]);
|
|
1836
|
+
return [4 /*yield*/, this.buildTransactionEventPayload(params, provider, txChainId_1)];
|
|
1578
1837
|
case 1:
|
|
1579
1838
|
payload = _a.sent();
|
|
1580
|
-
this.transaction(__assign({ status: types_1.TransactionStatus.REJECTED }, payload));
|
|
1581
|
-
return [3 /*break*/, 3];
|
|
1839
|
+
return [4 /*yield*/, this.transaction(__assign({ status: types_1.TransactionStatus.REJECTED }, payload))];
|
|
1582
1840
|
case 2:
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1841
|
+
_a.sent();
|
|
1842
|
+
return [3 /*break*/, 4];
|
|
1843
|
+
case 3:
|
|
1844
|
+
e_9 = _a.sent();
|
|
1845
|
+
logger_1.logger.error("Formo: Failed to track transaction rejection", e_9);
|
|
1846
|
+
return [3 /*break*/, 4];
|
|
1847
|
+
case 4: return [2 /*return*/];
|
|
1587
1848
|
}
|
|
1588
1849
|
});
|
|
1589
1850
|
}); })();
|
|
1590
1851
|
}
|
|
1591
|
-
throw
|
|
1592
|
-
case
|
|
1852
|
+
throw error_5;
|
|
1853
|
+
case 8: return [2 /*return*/, request({ method: method, params: params })];
|
|
1593
1854
|
}
|
|
1594
1855
|
});
|
|
1595
1856
|
}); };
|
|
@@ -1607,9 +1868,16 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1607
1868
|
};
|
|
1608
1869
|
FormoAnalytics.prototype.onLocationChange = function () {
|
|
1609
1870
|
return __awaiter(this, void 0, void 0, function () {
|
|
1610
|
-
|
|
1871
|
+
var _a;
|
|
1872
|
+
return __generator(this, function (_b) {
|
|
1611
1873
|
if (this._currentUrl !== window.location.href) {
|
|
1612
1874
|
this._currentUrl = window.location.href;
|
|
1875
|
+
// Host/path exclusions are evaluated per navigation, so a SPA can leave
|
|
1876
|
+
// an excluded route and become trackable without any wallet event
|
|
1877
|
+
// firing. The wagmi handler only observes *changes*, so an unchanged
|
|
1878
|
+
// connection it was forced to decline earlier would stay invisible for
|
|
1879
|
+
// the rest of the page load. Give it a chance to adopt it now.
|
|
1880
|
+
(_a = this.wagmiHandler) === null || _a === void 0 ? void 0 : _a.retryAdoption();
|
|
1613
1881
|
this.trackPageHit();
|
|
1614
1882
|
}
|
|
1615
1883
|
return [2 /*return*/];
|
|
@@ -1680,7 +1948,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1680
1948
|
if (_this._pageHooksDisposed)
|
|
1681
1949
|
return;
|
|
1682
1950
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1683
|
-
var
|
|
1951
|
+
var e_10;
|
|
1684
1952
|
return __generator(this, function (_a) {
|
|
1685
1953
|
switch (_a.label) {
|
|
1686
1954
|
case 0:
|
|
@@ -1693,8 +1961,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1693
1961
|
_a.sent();
|
|
1694
1962
|
return [3 /*break*/, 3];
|
|
1695
1963
|
case 2:
|
|
1696
|
-
|
|
1697
|
-
logger_1.logger.error("Formo: Failed to track page hit",
|
|
1964
|
+
e_10 = _a.sent();
|
|
1965
|
+
logger_1.logger.error("Formo: Failed to track page hit", e_10);
|
|
1698
1966
|
return [3 /*break*/, 3];
|
|
1699
1967
|
case 3: return [2 /*return*/];
|
|
1700
1968
|
}
|
|
@@ -1707,12 +1975,17 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1707
1975
|
};
|
|
1708
1976
|
FormoAnalytics.prototype.trackEvent = function (type, payload, properties, context, callback) {
|
|
1709
1977
|
return __awaiter(this, void 0, void 0, function () {
|
|
1710
|
-
var
|
|
1978
|
+
var error_6;
|
|
1711
1979
|
return __generator(this, function (_a) {
|
|
1712
1980
|
switch (_a.label) {
|
|
1713
1981
|
case 0:
|
|
1714
1982
|
_a.trys.push([0, 2, , 3]);
|
|
1715
|
-
|
|
1983
|
+
// Gate on the chain the event actually carries. `connect`, `disconnect`,
|
|
1984
|
+
// `chain`, `signature` and `transaction` all put one in the payload, and
|
|
1985
|
+
// it is authoritative: it can name a provider or a wagmi mutation chain
|
|
1986
|
+
// that is not the active one. Events without a chain (page, track,
|
|
1987
|
+
// identify) fall back to the central value.
|
|
1988
|
+
if (!this.shouldTrack(payload === null || payload === void 0 ? void 0 : payload.chainId)) {
|
|
1716
1989
|
logger_1.logger.info("Skipping ".concat(type, " event due to tracking configuration"));
|
|
1717
1990
|
return [2 /*return*/];
|
|
1718
1991
|
}
|
|
@@ -1721,8 +1994,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1721
1994
|
_a.sent();
|
|
1722
1995
|
return [3 /*break*/, 3];
|
|
1723
1996
|
case 2:
|
|
1724
|
-
|
|
1725
|
-
logger_1.logger.error("Error tracking event:",
|
|
1997
|
+
error_6 = _a.sent();
|
|
1998
|
+
logger_1.logger.error("Error tracking event:", error_6);
|
|
1726
1999
|
return [3 /*break*/, 3];
|
|
1727
2000
|
case 3: return [2 /*return*/];
|
|
1728
2001
|
}
|
|
@@ -1759,16 +2032,24 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1759
2032
|
* an options object with `excludeChains` set, and only once a chain id is
|
|
1760
2033
|
* known.
|
|
1761
2034
|
*/
|
|
1762
|
-
FormoAnalytics.prototype.isCurrentChainExcluded = function () {
|
|
2035
|
+
FormoAnalytics.prototype.isCurrentChainExcluded = function (eventChainId) {
|
|
1763
2036
|
if (this.options.tracking === null ||
|
|
1764
2037
|
typeof this.options.tracking !== "object" ||
|
|
1765
2038
|
Array.isArray(this.options.tracking)) {
|
|
1766
2039
|
return false;
|
|
1767
2040
|
}
|
|
1768
2041
|
var _a = this.options.tracking.excludeChains, excludeChains = _a === void 0 ? [] : _a;
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
2042
|
+
if (excludeChains.length === 0)
|
|
2043
|
+
return false;
|
|
2044
|
+
// Mirrors `shouldTrack()`: the event's own chain wins when it has one,
|
|
2045
|
+
// and an unresolvable chain on a known wallet counts as excluded rather
|
|
2046
|
+
// than allowed.
|
|
2047
|
+
var chainToCheck = eventChainId !== null && eventChainId !== void 0 ? eventChainId : this.currentChainId;
|
|
2048
|
+
if (chainToCheck === 0)
|
|
2049
|
+
return true;
|
|
2050
|
+
if (chainToCheck === undefined)
|
|
2051
|
+
return false;
|
|
2052
|
+
return excludeChains.includes(chainToCheck);
|
|
1772
2053
|
};
|
|
1773
2054
|
/**
|
|
1774
2055
|
* Whether the current environment is excluded from tracking - the visitor's
|
|
@@ -1863,7 +2144,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1863
2144
|
* Determines if tracking should be enabled based on configuration and consent
|
|
1864
2145
|
* @returns {boolean} True if tracking should be enabled
|
|
1865
2146
|
*/
|
|
1866
|
-
FormoAnalytics.prototype.shouldTrack = function () {
|
|
2147
|
+
FormoAnalytics.prototype.shouldTrack = function (eventChainId) {
|
|
1867
2148
|
// First check if user has opted out of tracking
|
|
1868
2149
|
if (this.hasOptedOutTracking()) {
|
|
1869
2150
|
return false;
|
|
@@ -1882,11 +2163,42 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1882
2163
|
if (this.isCurrentEnvironmentExcluded()) {
|
|
1883
2164
|
return false;
|
|
1884
2165
|
}
|
|
1885
|
-
// Check chainId exclusions
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
2166
|
+
// Check chainId exclusions.
|
|
2167
|
+
//
|
|
2168
|
+
// The event's OWN chain wins over `currentChainId`. They differ whenever
|
|
2169
|
+
// the event did not come from the active provider: a second wallet
|
|
2170
|
+
// signing through its own provider, or a wagmi mutation that names an
|
|
2171
|
+
// explicit chain. Reading only the central field there would emit an
|
|
2172
|
+
// event that is labelled with an excluded chain, which is precisely what
|
|
2173
|
+
// the exclusion forbids - and would drop an allowed event whenever the
|
|
2174
|
+
// active provider happened to sit on an excluded chain.
|
|
2175
|
+
var chainToCheck = eventChainId !== null && eventChainId !== void 0 ? eventChainId : this.currentChainId;
|
|
2176
|
+
if (excludeChains.length > 0) {
|
|
2177
|
+
// Fail CLOSED on an unknown chain. `resolveChainIdForProvider` reports
|
|
2178
|
+
// 0 when it has never heard a chain from the signing wallet, and 0 is
|
|
2179
|
+
// in no exclusion list, so treating it as "not excluded" would let
|
|
2180
|
+
// exactly the events an operator excluded through - the wallet on the
|
|
2181
|
+
// excluded chain is often the one we know least about. An explicit
|
|
2182
|
+
// exclusion is a directive, so an unresolvable chain is refused.
|
|
2183
|
+
//
|
|
2184
|
+
// This covers the central value too, not just an explicit event
|
|
2185
|
+
// chain: `page`, `track` and `identify` carry no chain of their own
|
|
2186
|
+
// and fall back to `currentChainId`, so an unknown chain there would
|
|
2187
|
+
// otherwise send wallet-attributed events for a wallet that may well
|
|
2188
|
+
// be sitting on an excluded chain.
|
|
2189
|
+
// Deliberately keyed on 0 and NOT on `undefined`. 0 is the explicit
|
|
2190
|
+
// "we asked and could not tell" marker. `undefined` means no chain
|
|
2191
|
+
// state yet, which is a legitimate transient - the Privy path
|
|
2192
|
+
// reconciles a Solana wallet through exactly that state - and
|
|
2193
|
+
// refusing it would drop real events.
|
|
2194
|
+
//
|
|
2195
|
+
// `backfillActiveWallet()` never persists 0, so an unresolvable chain
|
|
2196
|
+
// cannot leak into `currentChainId` and reach the unscoped events
|
|
2197
|
+
// (page / track / identify) that fall back to it.
|
|
2198
|
+
if (chainToCheck === 0)
|
|
2199
|
+
return false;
|
|
2200
|
+
if (chainToCheck && excludeChains.includes(chainToCheck))
|
|
2201
|
+
return false;
|
|
1890
2202
|
}
|
|
1891
2203
|
// If nothing is excluded, tracking is enabled
|
|
1892
2204
|
return true;
|
|
@@ -1970,7 +2282,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1970
2282
|
_this.trackProviders(newDetails);
|
|
1971
2283
|
// Detect newly discovered wallets (session de-dupes) with error handling
|
|
1972
2284
|
(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1973
|
-
var
|
|
2285
|
+
var e_11;
|
|
1974
2286
|
return __generator(this, function (_a) {
|
|
1975
2287
|
switch (_a.label) {
|
|
1976
2288
|
case 0:
|
|
@@ -1980,8 +2292,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1980
2292
|
_a.sent();
|
|
1981
2293
|
return [3 /*break*/, 3];
|
|
1982
2294
|
case 2:
|
|
1983
|
-
|
|
1984
|
-
logger_1.logger.error("Formo: Failed to detect wallets",
|
|
2295
|
+
e_11 = _a.sent();
|
|
2296
|
+
logger_1.logger.error("Formo: Failed to detect wallets", e_11);
|
|
1985
2297
|
return [3 /*break*/, 3];
|
|
1986
2298
|
case 3: return [2 /*return*/];
|
|
1987
2299
|
}
|
|
@@ -2174,6 +2486,105 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2174
2486
|
});
|
|
2175
2487
|
});
|
|
2176
2488
|
};
|
|
2489
|
+
/**
|
|
2490
|
+
* Resolve the chain an autocaptured request actually ran on.
|
|
2491
|
+
*
|
|
2492
|
+
* `_evmChainId` is maintained by `chainChanged` from whichever provider is
|
|
2493
|
+
* currently active. When a request arrives from a *different* tracked
|
|
2494
|
+
* provider - which happens whenever a visitor has two wallets installed -
|
|
2495
|
+
* that cached value describes the wrong wallet, and tagging the event with
|
|
2496
|
+
* it silently mis-attributes the chain.
|
|
2497
|
+
*
|
|
2498
|
+
* Answered entirely from a per-provider snapshot. This is deliberately
|
|
2499
|
+
* SYNCHRONOUS and never issues an RPC.
|
|
2500
|
+
*
|
|
2501
|
+
* An earlier version called `eth_chainId` on the signing provider and
|
|
2502
|
+
* time-boxed it with `Promise.race`. That is not safe: the race abandons the
|
|
2503
|
+
* SDK's promise but cannot cancel the provider's request. On a transport
|
|
2504
|
+
* that serializes - WalletConnect's relay socket, the very case this path
|
|
2505
|
+
* exists to serve - an abandoned lookup stays at the head of the wallet's
|
|
2506
|
+
* queue, and every later RPC the dapp makes queues behind it until reload.
|
|
2507
|
+
* Mislabelling a chain is a reporting defect; wedging the user's wallet is
|
|
2508
|
+
* not acceptable to avoid one.
|
|
2509
|
+
*
|
|
2510
|
+
* When nothing is known, this reports 0 ("unknown") rather than guessing
|
|
2511
|
+
* with the active provider's chain, which is known-wrong for another wallet.
|
|
2512
|
+
*/
|
|
2513
|
+
FormoAnalytics.prototype.resolveChainIdForProvider = function (provider) {
|
|
2514
|
+
if (provider) {
|
|
2515
|
+
var known = this._providerChainIds.get(provider);
|
|
2516
|
+
if (known)
|
|
2517
|
+
return known;
|
|
2518
|
+
// Only the active provider's chain is described by the central cache.
|
|
2519
|
+
if (provider === this._provider && this._evmChainId) {
|
|
2520
|
+
return this._evmChainId;
|
|
2521
|
+
}
|
|
2522
|
+
// A tracked provider we have never heard a chain from. Deliberately no
|
|
2523
|
+
// fall back to `_evmChainId`: it belongs to a different wallet.
|
|
2524
|
+
return 0;
|
|
2525
|
+
}
|
|
2526
|
+
return this._evmChainId || 0;
|
|
2527
|
+
};
|
|
2528
|
+
/**
|
|
2529
|
+
* Record a provider's chain. Fed by `chainChanged` and `connect`, and by the
|
|
2530
|
+
* one-off probe at tracking time - never from inside a user request.
|
|
2531
|
+
*/
|
|
2532
|
+
FormoAnalytics.prototype.rememberProviderChain = function (provider, chainId) {
|
|
2533
|
+
if (!provider || !chainId)
|
|
2534
|
+
return;
|
|
2535
|
+
// Any observation is newer than an `eth_chainId` still in flight for this
|
|
2536
|
+
// provider.
|
|
2537
|
+
this.bumpProviderChainGeneration(provider);
|
|
2538
|
+
this._providerChainIds.set(provider, chainId);
|
|
2539
|
+
// If this IS the active provider, central state has to follow. Recording
|
|
2540
|
+
// it only per provider left `currentChainId` on a chain restored from a
|
|
2541
|
+
// previous session, and the unscoped events that fall back to it were sent
|
|
2542
|
+
// despite an exclusion covering the chain the wallet was really on.
|
|
2543
|
+
//
|
|
2544
|
+
// Guarded on EVM already being the active namespace. `setChainState()`
|
|
2545
|
+
// makes whichever namespace it touches active, so syncing here
|
|
2546
|
+
// unconditionally let a background EVM wallet's chain report steal the
|
|
2547
|
+
// active slot from a live Solana wallet, and every later page or track
|
|
2548
|
+
// event was attributed to the wrong wallet entirely.
|
|
2549
|
+
if (provider === this._provider &&
|
|
2550
|
+
this._activeNamespace === "evm" &&
|
|
2551
|
+
this._evmChainId !== chainId) {
|
|
2552
|
+
this.setChainState('evm', { chainId: chainId });
|
|
2553
|
+
}
|
|
2554
|
+
};
|
|
2555
|
+
/** Advance and return this provider's chain-observation generation. */
|
|
2556
|
+
FormoAnalytics.prototype.bumpProviderChainGeneration = function (provider) {
|
|
2557
|
+
var _a;
|
|
2558
|
+
var next = ((_a = this._providerChainGenerations.get(provider)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
2559
|
+
this._providerChainGenerations.set(provider, next);
|
|
2560
|
+
return next;
|
|
2561
|
+
};
|
|
2562
|
+
/**
|
|
2563
|
+
* Seed a provider's chain from whatever it already exposes synchronously.
|
|
2564
|
+
*
|
|
2565
|
+
* Most EIP-1193 implementations carry a `chainId` property (MetaMask,
|
|
2566
|
+
* WalletConnect, Coinbase). Reading it costs nothing and cannot block.
|
|
2567
|
+
*
|
|
2568
|
+
* There is deliberately no RPC fallback. An earlier version probed with
|
|
2569
|
+
* `eth_chainId` when a provider was first tracked, on the theory that
|
|
2570
|
+
* tracking time is off the user's critical path. It is not: a serialized
|
|
2571
|
+
* transport has ONE queue, so a stalled probe sits in front of every later
|
|
2572
|
+
* signature and transaction the dapp makes. It could also land out of order
|
|
2573
|
+
* - a slow probe response overwriting a newer `chainChanged` - and relabel
|
|
2574
|
+
* events onto a chain the wallet had already left.
|
|
2575
|
+
*
|
|
2576
|
+
* A provider that exposes nothing stays unknown until it emits
|
|
2577
|
+
* `chainChanged` or `connect`, and unknown is reported honestly as 0.
|
|
2578
|
+
*/
|
|
2579
|
+
FormoAnalytics.prototype.seedProviderChainFromState = function (provider) {
|
|
2580
|
+
var raw = provider.chainId;
|
|
2581
|
+
var chainId = typeof raw === "string"
|
|
2582
|
+
? (0, chain_1.parseChainId)(raw)
|
|
2583
|
+
: typeof raw === "number"
|
|
2584
|
+
? raw
|
|
2585
|
+
: undefined;
|
|
2586
|
+
this.rememberProviderChain(provider, chainId);
|
|
2587
|
+
};
|
|
2177
2588
|
FormoAnalytics.prototype.getCurrentChainId = function (provider) {
|
|
2178
2589
|
return __awaiter(this, void 0, void 0, function () {
|
|
2179
2590
|
var p, chainIdHex, err_5;
|
|
@@ -2209,7 +2620,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2209
2620
|
};
|
|
2210
2621
|
FormoAnalytics.prototype.buildSignatureEventPayload = function (method, params,
|
|
2211
2622
|
// Intentionally not read. Kept for positional call-site arity.
|
|
2212
|
-
_response, chainId) {
|
|
2623
|
+
_response, chainId, provider) {
|
|
2213
2624
|
var _a;
|
|
2214
2625
|
var rawAddress = method === "personal_sign"
|
|
2215
2626
|
? params[1]
|
|
@@ -2219,7 +2630,11 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2219
2630
|
throw new Error("Invalid address in signature payload: ".concat(rawAddress));
|
|
2220
2631
|
}
|
|
2221
2632
|
var effectiveChainId = (_a = chainId !== null && chainId !== void 0 ? chainId : this._evmChainId) !== null && _a !== void 0 ? _a : undefined;
|
|
2222
|
-
|
|
2633
|
+
// Only the active provider may write central wallet state - see the same
|
|
2634
|
+
// guard in buildTransactionEventPayload.
|
|
2635
|
+
if (!provider || provider === this._provider || !this._provider) {
|
|
2636
|
+
this.backfillActiveWallet(validAddress, effectiveChainId, provider);
|
|
2637
|
+
}
|
|
2223
2638
|
var basePayload = {
|
|
2224
2639
|
chainId: effectiveChainId,
|
|
2225
2640
|
address: validAddress,
|
|
@@ -2231,34 +2646,37 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2231
2646
|
// eth_signTypedData*: params[1] is the full EIP-712 struct.
|
|
2232
2647
|
return __assign(__assign({}, basePayload), { message: params[1] });
|
|
2233
2648
|
};
|
|
2234
|
-
FormoAnalytics.prototype.buildTransactionEventPayload = function (params, provider
|
|
2649
|
+
FormoAnalytics.prototype.buildTransactionEventPayload = function (params, provider,
|
|
2650
|
+
/**
|
|
2651
|
+
* Chain resolved once for this request's whole lifecycle. Passing it keeps
|
|
2652
|
+
* every status of one transaction on the same chain even if the user
|
|
2653
|
+
* switches network while the wallet prompt is open.
|
|
2654
|
+
*/
|
|
2655
|
+
capturedChainId) {
|
|
2235
2656
|
return __awaiter(this, void 0, void 0, function () {
|
|
2236
|
-
var _a, data, from, to, value, validAddress, chainId
|
|
2237
|
-
return __generator(this, function (
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
case 2:
|
|
2252
|
-
chainId = _b;
|
|
2253
|
-
this.backfillActiveWallet(validAddress, chainId);
|
|
2254
|
-
return [2 /*return*/, {
|
|
2255
|
-
chainId: chainId,
|
|
2256
|
-
data: data,
|
|
2257
|
-
address: validAddress,
|
|
2258
|
-
to: to,
|
|
2259
|
-
value: value,
|
|
2260
|
-
}];
|
|
2657
|
+
var _a, data, from, to, value, validAddress, chainId;
|
|
2658
|
+
return __generator(this, function (_b) {
|
|
2659
|
+
_a = params[0], data = _a.data, from = _a.from, to = _a.to, value = _a.value;
|
|
2660
|
+
validAddress = (0, address_1.validateAndChecksumAddress)(from);
|
|
2661
|
+
if (!validAddress) {
|
|
2662
|
+
throw new Error("Invalid address in transaction payload: ".concat(from));
|
|
2663
|
+
}
|
|
2664
|
+
chainId = capturedChainId !== null && capturedChainId !== void 0 ? capturedChainId : this.resolveChainIdForProvider(provider);
|
|
2665
|
+
// Only the ACTIVE provider may write central wallet state. A request from
|
|
2666
|
+
// a second, non-active wallet would otherwise overwrite the active
|
|
2667
|
+
// provider's address and chain, and every later request through the active
|
|
2668
|
+
// provider would then trust the other wallet's chain - persistent
|
|
2669
|
+
// mis-attribution, and a way around `excludeChains`.
|
|
2670
|
+
if (!provider || provider === this._provider || !this._provider) {
|
|
2671
|
+
this.backfillActiveWallet(validAddress, chainId, provider);
|
|
2261
2672
|
}
|
|
2673
|
+
return [2 /*return*/, {
|
|
2674
|
+
chainId: chainId,
|
|
2675
|
+
data: data,
|
|
2676
|
+
address: validAddress,
|
|
2677
|
+
to: to,
|
|
2678
|
+
value: value,
|
|
2679
|
+
}];
|
|
2262
2680
|
});
|
|
2263
2681
|
});
|
|
2264
2682
|
};
|
|
@@ -2270,16 +2688,51 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2270
2688
|
* social-login wrappers). If `accountsChanged` later fires it overwrites this
|
|
2271
2689
|
* value in the normal way; existing connections are never clobbered.
|
|
2272
2690
|
*/
|
|
2273
|
-
FormoAnalytics.prototype.backfillActiveWallet = function (address, chainId) {
|
|
2691
|
+
FormoAnalytics.prototype.backfillActiveWallet = function (address, chainId, provider) {
|
|
2692
|
+
// Refuse a chain the provider has since moved off.
|
|
2693
|
+
//
|
|
2694
|
+
// A request captures its chain once and reuses that snapshot for every
|
|
2695
|
+
// status it emits, which is right for the event payload - a confirmation
|
|
2696
|
+
// must not be relabelled mid-flight. But writing that captured value back
|
|
2697
|
+
// into central state on the LATER statuses restored a chain the wallet had
|
|
2698
|
+
// already left, and the unscoped events that fall back to it then bypassed
|
|
2699
|
+
// an exclusion that should have caught them.
|
|
2700
|
+
if (provider && chainId !== undefined && chainId !== 0) {
|
|
2701
|
+
var current = this._providerChainIds.get(provider);
|
|
2702
|
+
if (current !== undefined && current !== chainId) {
|
|
2703
|
+
chainId = current;
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
// `0` is kept deliberately. It means "could not resolve", and persisting
|
|
2707
|
+
// it is what lets the exclusion gate refuse the unscoped events - `page`,
|
|
2708
|
+
// `track`, `identify` - that carry no chain of their own and fall back to
|
|
2709
|
+
// `currentChainId`. Erasing it to `undefined` looked tidier but removed
|
|
2710
|
+
// the only marker distinguishing "unknown" from "no wallet yet", and those
|
|
2711
|
+
// events then went out attributed to a wallet that might be sitting on an
|
|
2712
|
+
// excluded chain.
|
|
2274
2713
|
// Never learn identity while suppressed (opt-out / timezone / excluded host
|
|
2275
2714
|
// or path). A signature/transaction observed on an excluded route must not
|
|
2276
|
-
// populate currentAddress for later allowed-page events.
|
|
2277
|
-
// *adds* an address (it no-ops when one is already known), so there is no
|
|
2278
|
-
// stale state to clear here.
|
|
2715
|
+
// populate currentAddress for later allowed-page events.
|
|
2279
2716
|
if (this.isTrackingSuppressed())
|
|
2280
2717
|
return;
|
|
2281
|
-
|
|
2718
|
+
var known = this._evmAddress;
|
|
2719
|
+
if (known) {
|
|
2720
|
+
// Same wallet, newer chain: correct it rather than returning.
|
|
2721
|
+
//
|
|
2722
|
+
// A persisted wallet restores a chain from a previous session. If the
|
|
2723
|
+
// provider has since moved - to an excluded chain, or to one we cannot
|
|
2724
|
+
// resolve - the autocaptured event is gated correctly, but the stale
|
|
2725
|
+
// restored chain stayed in `currentChainId` and the unscoped events
|
|
2726
|
+
// that fall back to it went out under an exclusion that should have
|
|
2727
|
+
// caught them.
|
|
2728
|
+
if (chainId !== undefined &&
|
|
2729
|
+
known.toLowerCase() === address.toLowerCase() &&
|
|
2730
|
+
this._evmChainId !== chainId) {
|
|
2731
|
+
this.setChainState('evm', { address: known, chainId: chainId });
|
|
2732
|
+
}
|
|
2733
|
+
// A DIFFERENT address is another wallet's business; never overwrite.
|
|
2282
2734
|
return;
|
|
2735
|
+
}
|
|
2283
2736
|
this.setChainState('evm', { address: address, chainId: chainId });
|
|
2284
2737
|
};
|
|
2285
2738
|
/**
|
|
@@ -2310,7 +2763,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2310
2763
|
if (!provider)
|
|
2311
2764
|
return [2 /*return*/];
|
|
2312
2765
|
poll = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
2313
|
-
var receipt,
|
|
2766
|
+
var receipt, e_12;
|
|
2314
2767
|
return __generator(this, function (_a) {
|
|
2315
2768
|
switch (_a.label) {
|
|
2316
2769
|
case 0:
|
|
@@ -2334,8 +2787,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2334
2787
|
}
|
|
2335
2788
|
return [3 /*break*/, 3];
|
|
2336
2789
|
case 2:
|
|
2337
|
-
|
|
2338
|
-
logger_1.logger.error("Error polling transaction receipt",
|
|
2790
|
+
e_12 = _a.sent();
|
|
2791
|
+
logger_1.logger.error("Error polling transaction receipt", e_12);
|
|
2339
2792
|
return [3 /*break*/, 3];
|
|
2340
2793
|
case 3:
|
|
2341
2794
|
attempts++;
|
|
@@ -2465,6 +2918,9 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2465
2918
|
ns.chainId = namespaceOrChainId;
|
|
2466
2919
|
}
|
|
2467
2920
|
if (namespace === 'evm' && 'provider' in update) {
|
|
2921
|
+
// Displacing the active provider ends its connection as far as this SDK
|
|
2922
|
+
// is concerned, so the connect it reported stops counting.
|
|
2923
|
+
this.forgetConnectRecord(ns.provider, update.provider);
|
|
2468
2924
|
ns.provider = update.provider;
|
|
2469
2925
|
}
|
|
2470
2926
|
this._activeNamespace = namespace;
|
|
@@ -2478,6 +2934,8 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
2478
2934
|
? namespaceOrChainId
|
|
2479
2935
|
: this.getNamespace(namespaceOrChainId);
|
|
2480
2936
|
if (namespace === 'evm') {
|
|
2937
|
+
// Same rule: wiping the namespace drops the active provider.
|
|
2938
|
+
this.forgetConnectRecord(this._chainState.evm.provider, undefined);
|
|
2481
2939
|
this._chainState.evm = {};
|
|
2482
2940
|
}
|
|
2483
2941
|
else {
|