@formo/analytics 1.28.5 → 1.29.0
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 +9 -3
- package/dist/cjs/src/FormoAnalytics.js +29 -16
- package/dist/cjs/src/constants/base.d.ts +0 -1
- package/dist/cjs/src/constants/base.js +1 -2
- package/dist/cjs/src/event/EventFactory.d.ts +1 -0
- package/dist/cjs/src/event/EventFactory.js +21 -14
- package/dist/cjs/src/event/constants.d.ts +8 -2
- package/dist/cjs/src/event/constants.js +31 -5
- package/dist/cjs/src/index.d.ts +3 -1
- package/dist/cjs/src/index.js +5 -1
- package/dist/cjs/src/solana/SolanaManager.d.ts +36 -11
- package/dist/cjs/src/solana/SolanaManager.js +47 -49
- package/dist/cjs/src/solana/SolanaStoreHandler.d.ts +88 -0
- package/dist/cjs/src/solana/SolanaStoreHandler.js +471 -0
- package/dist/cjs/src/solana/index.d.ts +8 -4
- package/dist/cjs/src/solana/index.js +10 -6
- package/dist/cjs/src/solana/storeTypes.d.ts +107 -0
- package/dist/cjs/src/solana/storeTypes.js +12 -0
- package/dist/cjs/src/solana/types.d.ts +23 -154
- package/dist/cjs/src/solana/types.js +4 -37
- package/dist/cjs/src/storage/StorageManager.d.ts +1 -0
- package/dist/cjs/src/storage/StorageManager.js +10 -2
- package/dist/cjs/src/types/base.d.ts +16 -5
- package/dist/cjs/src/types/events.d.ts +5 -1
- package/dist/cjs/src/version.d.ts +1 -1
- package/dist/cjs/src/version.js +1 -1
- package/dist/esm/src/FormoAnalytics.d.ts +9 -3
- package/dist/esm/src/FormoAnalytics.js +30 -17
- package/dist/esm/src/constants/base.d.ts +0 -1
- package/dist/esm/src/constants/base.js +0 -1
- package/dist/esm/src/event/EventFactory.d.ts +1 -0
- package/dist/esm/src/event/EventFactory.js +22 -15
- package/dist/esm/src/event/constants.d.ts +8 -2
- package/dist/esm/src/event/constants.js +30 -5
- package/dist/esm/src/index.d.ts +3 -1
- package/dist/esm/src/index.js +1 -0
- package/dist/esm/src/solana/SolanaManager.d.ts +36 -11
- package/dist/esm/src/solana/SolanaManager.js +47 -49
- package/dist/esm/src/solana/SolanaStoreHandler.d.ts +88 -0
- package/dist/esm/src/solana/SolanaStoreHandler.js +468 -0
- package/dist/esm/src/solana/index.d.ts +8 -4
- package/dist/esm/src/solana/index.js +8 -4
- package/dist/esm/src/solana/storeTypes.d.ts +107 -0
- package/dist/esm/src/solana/storeTypes.js +11 -0
- package/dist/esm/src/solana/types.d.ts +23 -154
- package/dist/esm/src/solana/types.js +3 -34
- package/dist/esm/src/storage/StorageManager.d.ts +1 -0
- package/dist/esm/src/storage/StorageManager.js +10 -2
- package/dist/esm/src/types/base.d.ts +16 -5
- package/dist/esm/src/types/events.d.ts +5 -1
- package/dist/esm/src/version.d.ts +1 -1
- package/dist/esm/src/version.js +1 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +14 -14
- package/dist/cjs/src/solana/SolanaAdapter.d.ts +0 -210
- package/dist/cjs/src/solana/SolanaAdapter.js +0 -988
- package/dist/esm/src/solana/SolanaAdapter.d.ts +0 -210
- package/dist/esm/src/solana/SolanaAdapter.js +0 -985
|
@@ -45,8 +45,15 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
45
45
|
* When true, EIP-1193 provider wrapping is skipped
|
|
46
46
|
*/
|
|
47
47
|
private isWagmiMode;
|
|
48
|
+
/**
|
|
49
|
+
* Flag indicating if EVM provider tracking is disabled.
|
|
50
|
+
* When true, all EIP-1193/EIP-6963 detection and wrapping is skipped.
|
|
51
|
+
*/
|
|
52
|
+
private isEvmDisabled;
|
|
48
53
|
/** Instance-level flag so multiple SDK instances don't interfere. */
|
|
49
54
|
private crossSubdomainCookies;
|
|
55
|
+
/** In-memory URL used to deduplicate SPA pageview events. */
|
|
56
|
+
private _currentUrl;
|
|
50
57
|
config: Config;
|
|
51
58
|
currentChainId?: ChainID;
|
|
52
59
|
currentAddress?: Address;
|
|
@@ -294,10 +301,9 @@ export declare class FormoAnalytics implements IFormoAnalytics {
|
|
|
294
301
|
*
|
|
295
302
|
* @example
|
|
296
303
|
* ```tsx
|
|
297
|
-
* formo.solana.
|
|
298
|
-
* formo.solana.setConnection(connection);
|
|
304
|
+
* formo.solana.setStore(client.store);
|
|
299
305
|
* formo.solana.setCluster("devnet");
|
|
300
|
-
* formo.
|
|
306
|
+
* // For signatures, use formo.signature() directly
|
|
301
307
|
* ```
|
|
302
308
|
*/
|
|
303
309
|
get solana(): SolanaManager;
|
|
@@ -117,6 +117,13 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
117
117
|
* When true, EIP-1193 provider wrapping is skipped
|
|
118
118
|
*/
|
|
119
119
|
this.isWagmiMode = false;
|
|
120
|
+
/**
|
|
121
|
+
* Flag indicating if EVM provider tracking is disabled.
|
|
122
|
+
* When true, all EIP-1193/EIP-6963 detection and wrapping is skipped.
|
|
123
|
+
*/
|
|
124
|
+
this.isEvmDisabled = false;
|
|
125
|
+
/** In-memory URL used to deduplicate SPA pageview events. */
|
|
126
|
+
this._currentUrl = "";
|
|
120
127
|
this.currentUserId = "";
|
|
121
128
|
this.config = {
|
|
122
129
|
writeKey: writeKey,
|
|
@@ -124,6 +131,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
124
131
|
this.options = options;
|
|
125
132
|
// Check if Wagmi mode is enabled
|
|
126
133
|
this.isWagmiMode = !!options.wagmi;
|
|
134
|
+
this.isEvmDisabled = options.evm === false;
|
|
127
135
|
this.crossSubdomainCookies = (_a = options.crossSubdomainCookies) !== null && _a !== void 0 ? _a : true;
|
|
128
136
|
// Normalize so downstream consumers (EventFactory) read the resolved value.
|
|
129
137
|
options.crossSubdomainCookies = this.crossSubdomainCookies;
|
|
@@ -156,8 +164,11 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
156
164
|
if (this.hasOptedOutTracking()) {
|
|
157
165
|
logger_1.logger.info("User has previously opted out of tracking");
|
|
158
166
|
}
|
|
159
|
-
// Initialize
|
|
160
|
-
if (this.
|
|
167
|
+
// Initialize EVM provider tracking (unless explicitly disabled)
|
|
168
|
+
if (this.isEvmDisabled) {
|
|
169
|
+
logger_1.logger.info("FormoAnalytics: EVM provider tracking disabled");
|
|
170
|
+
}
|
|
171
|
+
else if (this.isWagmiMode && options.wagmi) {
|
|
161
172
|
logger_1.logger.info("FormoAnalytics: Initializing in Wagmi mode");
|
|
162
173
|
this.wagmiHandler = new wagmi_1.WagmiEventHandler(this, options.wagmi.config, options.wagmi.queryClient);
|
|
163
174
|
}
|
|
@@ -179,6 +190,7 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
179
190
|
if (options.solana) {
|
|
180
191
|
this.solanaManager = new SolanaManager_1.SolanaManager(this, options.solana);
|
|
181
192
|
}
|
|
193
|
+
this._currentUrl = window.location.href;
|
|
182
194
|
this.trackPageHit();
|
|
183
195
|
this.trackPageHits();
|
|
184
196
|
}
|
|
@@ -226,22 +238,26 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
226
238
|
case 0:
|
|
227
239
|
(0, storage_1.initStorageManager)(writeKey);
|
|
228
240
|
analytics = new FormoAnalytics(writeKey, options);
|
|
229
|
-
if (
|
|
241
|
+
if (!analytics.isEvmDisabled) return [3 /*break*/, 1];
|
|
242
|
+
logger_1.logger.info("FormoAnalytics: Skipping provider detection (EVM disabled)");
|
|
243
|
+
return [3 /*break*/, 5];
|
|
244
|
+
case 1:
|
|
245
|
+
if (!!analytics.isWagmiMode) return [3 /*break*/, 4];
|
|
230
246
|
// Auto-detect wallet provider
|
|
231
247
|
_a = analytics;
|
|
232
248
|
return [4 /*yield*/, analytics.getProviders()];
|
|
233
|
-
case
|
|
249
|
+
case 2:
|
|
234
250
|
// Auto-detect wallet provider
|
|
235
251
|
_a._providers = _b.sent();
|
|
236
252
|
return [4 /*yield*/, analytics.detectWallets(analytics._providers)];
|
|
237
|
-
case
|
|
253
|
+
case 3:
|
|
238
254
|
_b.sent();
|
|
239
255
|
analytics.trackProviders(analytics._providers);
|
|
240
|
-
return [3 /*break*/,
|
|
241
|
-
case
|
|
256
|
+
return [3 /*break*/, 5];
|
|
257
|
+
case 4:
|
|
242
258
|
logger_1.logger.info("FormoAnalytics: Skipping provider detection (Wagmi mode)");
|
|
243
|
-
_b.label =
|
|
244
|
-
case
|
|
259
|
+
_b.label = 5;
|
|
260
|
+
case 5: return [2 /*return*/, analytics];
|
|
245
261
|
}
|
|
246
262
|
});
|
|
247
263
|
});
|
|
@@ -1427,11 +1443,9 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1427
1443
|
};
|
|
1428
1444
|
FormoAnalytics.prototype.onLocationChange = function () {
|
|
1429
1445
|
return __awaiter(this, void 0, void 0, function () {
|
|
1430
|
-
var currentUrl;
|
|
1431
1446
|
return __generator(this, function (_a) {
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
(0, storage_1.cookie)().set(constants_1.SESSION_CURRENT_URL_KEY, window.location.href);
|
|
1447
|
+
if (this._currentUrl !== window.location.href) {
|
|
1448
|
+
this._currentUrl = window.location.href;
|
|
1435
1449
|
this.trackPageHit();
|
|
1436
1450
|
}
|
|
1437
1451
|
return [2 /*return*/];
|
|
@@ -1770,10 +1784,9 @@ var FormoAnalytics = /** @class */ (function () {
|
|
|
1770
1784
|
*
|
|
1771
1785
|
* @example
|
|
1772
1786
|
* ```tsx
|
|
1773
|
-
* formo.solana.
|
|
1774
|
-
* formo.solana.setConnection(connection);
|
|
1787
|
+
* formo.solana.setStore(client.store);
|
|
1775
1788
|
* formo.solana.setCluster("devnet");
|
|
1776
|
-
* formo.
|
|
1789
|
+
* // For signatures, use formo.signature() directly
|
|
1777
1790
|
* ```
|
|
1778
1791
|
*/
|
|
1779
1792
|
get: function () {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export declare const SESSION_TRAFFIC_SOURCE_KEY = "traffic-source";
|
|
2
|
-
export declare const SESSION_CURRENT_URL_KEY = "analytics-current-url";
|
|
3
2
|
export declare const SESSION_USER_ID_KEY = "user-id";
|
|
4
3
|
export declare const LOCAL_ANONYMOUS_ID_KEY = "anonymous-id";
|
|
5
4
|
export declare const CONSENT_OPT_OUT_KEY = "opt-out-tracking";
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BLOCKED_ADDRESSES = exports.DEAD_ADDRESS = exports.ZERO_ADDRESS = exports.DEFAULT_PROVIDER_ICON = exports.CONSENT_OPT_OUT_KEY = exports.LOCAL_ANONYMOUS_ID_KEY = exports.SESSION_USER_ID_KEY = exports.
|
|
3
|
+
exports.BLOCKED_ADDRESSES = exports.DEAD_ADDRESS = exports.ZERO_ADDRESS = exports.DEFAULT_PROVIDER_ICON = exports.CONSENT_OPT_OUT_KEY = exports.LOCAL_ANONYMOUS_ID_KEY = exports.SESSION_USER_ID_KEY = exports.SESSION_TRAFFIC_SOURCE_KEY = void 0;
|
|
4
4
|
exports.SESSION_TRAFFIC_SOURCE_KEY = "traffic-source";
|
|
5
5
|
// SESSION_WALLET_DETECTED_KEY and SESSION_WALLET_IDENTIFIED_KEY
|
|
6
6
|
// are now defined in src/session/index.ts
|
|
7
|
-
exports.SESSION_CURRENT_URL_KEY = "analytics-current-url";
|
|
8
7
|
exports.SESSION_USER_ID_KEY = "user-id";
|
|
9
8
|
exports.LOCAL_ANONYMOUS_ID_KEY = "anonymous-id";
|
|
10
9
|
// Consent management keys
|
|
@@ -17,6 +17,7 @@ declare class EventFactory implements IEventFactory {
|
|
|
17
17
|
private getLanguage;
|
|
18
18
|
private getLibraryVersion;
|
|
19
19
|
private extractUTMParameters;
|
|
20
|
+
private extractClickIdParameters;
|
|
20
21
|
private extractReferralParameter;
|
|
21
22
|
private getTrafficSources;
|
|
22
23
|
private getScreen;
|
|
@@ -87,6 +87,15 @@ var EventFactory = /** @class */ (function () {
|
|
|
87
87
|
catch (_a) { }
|
|
88
88
|
return result;
|
|
89
89
|
};
|
|
90
|
+
this.extractClickIdParameters = function (urlObj) {
|
|
91
|
+
var result = {};
|
|
92
|
+
for (var _i = 0, CLICK_ID_PARAMS_1 = constants_2.CLICK_ID_PARAMS; _i < CLICK_ID_PARAMS_1.length; _i++) {
|
|
93
|
+
var param = CLICK_ID_PARAMS_1[_i];
|
|
94
|
+
var value = urlObj.searchParams.get(param);
|
|
95
|
+
result[param] = value ? value.trim() : "";
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
};
|
|
90
99
|
this.extractReferralParameter = function (urlObj) {
|
|
91
100
|
var _a, _b, _c;
|
|
92
101
|
// Strategy: Check query params first, then check path pattern if configured
|
|
@@ -119,25 +128,23 @@ var EventFactory = /** @class */ (function () {
|
|
|
119
128
|
};
|
|
120
129
|
this.getTrafficSources = function (url) {
|
|
121
130
|
var urlObj = new URL(url);
|
|
122
|
-
var contextTrafficSources = __assign(__assign({}, _this.extractUTMParameters(url)), { ref: _this.extractReferralParameter(urlObj), referrer: document.referrer });
|
|
131
|
+
var contextTrafficSources = __assign(__assign(__assign({}, _this.extractUTMParameters(url)), _this.extractClickIdParameters(urlObj)), { ref: _this.extractReferralParameter(urlObj), referrer: document.referrer });
|
|
123
132
|
var storedTrafficSources = (0, storage_1.session)().get(constants_1.SESSION_TRAFFIC_SOURCE_KEY) || {};
|
|
124
|
-
var
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
var mergedClickIds = {};
|
|
134
|
+
for (var _i = 0, CLICK_ID_PARAMS_2 = constants_2.CLICK_ID_PARAMS; _i < CLICK_ID_PARAMS_2.length; _i++) {
|
|
135
|
+
var p = CLICK_ID_PARAMS_2[_i];
|
|
136
|
+
mergedClickIds[p] =
|
|
137
|
+
contextTrafficSources[p] || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources[p]) || "";
|
|
138
|
+
}
|
|
139
|
+
var finalTrafficSources = __assign({ ref: contextTrafficSources.ref || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.ref) || "", referrer: contextTrafficSources.referrer || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.referrer) || "", utm_campaign: contextTrafficSources.utm_campaign ||
|
|
128
140
|
(storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_campaign) ||
|
|
129
|
-
"",
|
|
130
|
-
utm_content: contextTrafficSources.utm_content ||
|
|
141
|
+
"", utm_content: contextTrafficSources.utm_content ||
|
|
131
142
|
(storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_content) ||
|
|
132
|
-
"",
|
|
133
|
-
utm_medium: contextTrafficSources.utm_medium ||
|
|
143
|
+
"", utm_medium: contextTrafficSources.utm_medium ||
|
|
134
144
|
(storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_medium) ||
|
|
135
|
-
"",
|
|
136
|
-
utm_source: contextTrafficSources.utm_source ||
|
|
145
|
+
"", utm_source: contextTrafficSources.utm_source ||
|
|
137
146
|
(storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_source) ||
|
|
138
|
-
"",
|
|
139
|
-
utm_term: contextTrafficSources.utm_term || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_term) || "",
|
|
140
|
-
};
|
|
147
|
+
"", utm_term: contextTrafficSources.utm_term || (storedTrafficSources === null || storedTrafficSources === void 0 ? void 0 : storedTrafficSources.utm_term) || "" }, mergedClickIds);
|
|
141
148
|
// Store to session
|
|
142
149
|
var sessionStoredTrafficSources = Object.keys(finalTrafficSources).reduce(function (res, key) {
|
|
143
150
|
var value = finalTrafficSources[key];
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
declare const CHANNEL = "web";
|
|
2
2
|
declare const VERSION = "0";
|
|
3
|
+
/**
|
|
4
|
+
* Paid-attribution click IDs captured from the landing-page URL and persisted
|
|
5
|
+
* across the session alongside UTM parameters. Keep the ClickIdParameters type
|
|
6
|
+
* in src/types/events.ts derived from this array.
|
|
7
|
+
*/
|
|
8
|
+
declare const CLICK_ID_PARAMS: readonly ["gclid", "gad_source", "fbclid", "msclkid", "twclid", "li_fat_id", "rdt_cid", "ttclid"];
|
|
3
9
|
/**
|
|
4
10
|
* Fields that should be excluded from page event properties parsing
|
|
5
11
|
* These are either:
|
|
6
|
-
* - Already captured in event context (UTM params, referral params)
|
|
12
|
+
* - Already captured in event context (UTM params, referral params, click IDs)
|
|
7
13
|
* - Semantic event properties that should not be overridden by URL params
|
|
8
14
|
*/
|
|
9
15
|
declare const PAGE_PROPERTIES_EXCLUDED_FIELDS: Set<string>;
|
|
10
|
-
export { CHANNEL, VERSION, PAGE_PROPERTIES_EXCLUDED_FIELDS };
|
|
16
|
+
export { CHANNEL, VERSION, CLICK_ID_PARAMS, PAGE_PROPERTIES_EXCLUDED_FIELDS };
|
|
11
17
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1,17 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
3
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
4
|
+
if (ar || !(i in from)) {
|
|
5
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
6
|
+
ar[i] = from[i];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
10
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PAGE_PROPERTIES_EXCLUDED_FIELDS = exports.VERSION = exports.CHANNEL = void 0;
|
|
12
|
+
exports.PAGE_PROPERTIES_EXCLUDED_FIELDS = exports.CLICK_ID_PARAMS = exports.VERSION = exports.CHANNEL = void 0;
|
|
4
13
|
var CHANNEL = "web";
|
|
5
14
|
exports.CHANNEL = CHANNEL;
|
|
6
15
|
var VERSION = "0";
|
|
7
16
|
exports.VERSION = VERSION;
|
|
17
|
+
/**
|
|
18
|
+
* Paid-attribution click IDs captured from the landing-page URL and persisted
|
|
19
|
+
* across the session alongside UTM parameters. Keep the ClickIdParameters type
|
|
20
|
+
* in src/types/events.ts derived from this array.
|
|
21
|
+
*/
|
|
22
|
+
var CLICK_ID_PARAMS = [
|
|
23
|
+
"gclid", // Google Ads
|
|
24
|
+
"gad_source", // Google Ads (newer)
|
|
25
|
+
"fbclid", // Meta (Facebook/Instagram)
|
|
26
|
+
"msclkid", // Microsoft Ads (Bing)
|
|
27
|
+
"twclid", // Twitter/X Ads
|
|
28
|
+
"li_fat_id", // LinkedIn Ads
|
|
29
|
+
"rdt_cid", // Reddit Ads
|
|
30
|
+
"ttclid", // TikTok Ads
|
|
31
|
+
];
|
|
32
|
+
exports.CLICK_ID_PARAMS = CLICK_ID_PARAMS;
|
|
8
33
|
/**
|
|
9
34
|
* Fields that should be excluded from page event properties parsing
|
|
10
35
|
* These are either:
|
|
11
|
-
* - Already captured in event context (UTM params, referral params)
|
|
36
|
+
* - Already captured in event context (UTM params, referral params, click IDs)
|
|
12
37
|
* - Semantic event properties that should not be overridden by URL params
|
|
13
38
|
*/
|
|
14
|
-
var PAGE_PROPERTIES_EXCLUDED_FIELDS = new Set([
|
|
39
|
+
var PAGE_PROPERTIES_EXCLUDED_FIELDS = new Set(__spreadArray(__spreadArray([
|
|
15
40
|
// Context fields (already captured in event context)
|
|
16
41
|
'utm_source',
|
|
17
42
|
'utm_medium',
|
|
@@ -21,7 +46,8 @@ var PAGE_PROPERTIES_EXCLUDED_FIELDS = new Set([
|
|
|
21
46
|
'ref',
|
|
22
47
|
'referral',
|
|
23
48
|
'refcode',
|
|
24
|
-
'referrer'
|
|
49
|
+
'referrer'
|
|
50
|
+
], CLICK_ID_PARAMS, true), [
|
|
25
51
|
// Semantic event properties (should not be overridden by URL params)
|
|
26
52
|
'category',
|
|
27
53
|
'name',
|
|
@@ -29,6 +55,6 @@ var PAGE_PROPERTIES_EXCLUDED_FIELDS = new Set([
|
|
|
29
55
|
'path',
|
|
30
56
|
'hash',
|
|
31
57
|
'query',
|
|
32
|
-
]);
|
|
58
|
+
], false));
|
|
33
59
|
exports.PAGE_PROPERTIES_EXCLUDED_FIELDS = PAGE_PROPERTIES_EXCLUDED_FIELDS;
|
|
34
60
|
//# sourceMappingURL=constants.js.map
|
package/dist/cjs/src/index.d.ts
CHANGED
|
@@ -4,5 +4,7 @@ export * from "./types";
|
|
|
4
4
|
export { parsePrivyProperties } from "./privy";
|
|
5
5
|
export type { PrivyUser, PrivyLinkedAccount, PrivyAccountType, PrivyProfileProperties, PrivyWalletInfo } from "./privy";
|
|
6
6
|
export { SolanaManager } from "./solana";
|
|
7
|
-
export
|
|
7
|
+
export { SOLANA_CHAIN_IDS, DEFAULT_SOLANA_CHAIN_ID, isSolanaChainId } from "./solana";
|
|
8
|
+
export type { SolanaOptions, SolanaCluster, } from "./solana";
|
|
9
|
+
export type { SolanaClientStore, SolanaClientState, } from "./solana";
|
|
8
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/src/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.SolanaManager = exports.parsePrivyProperties = void 0;
|
|
17
|
+
exports.isSolanaChainId = exports.DEFAULT_SOLANA_CHAIN_ID = exports.SOLANA_CHAIN_IDS = exports.SolanaManager = exports.parsePrivyProperties = void 0;
|
|
18
18
|
var initialization_1 = require("./initialization");
|
|
19
19
|
__exportStar(require("./FormoAnalyticsProvider"), exports);
|
|
20
20
|
__exportStar(require("./FormoAnalytics"), exports);
|
|
@@ -24,6 +24,10 @@ Object.defineProperty(exports, "parsePrivyProperties", { enumerable: true, get:
|
|
|
24
24
|
// Solana integration exports
|
|
25
25
|
var solana_1 = require("./solana");
|
|
26
26
|
Object.defineProperty(exports, "SolanaManager", { enumerable: true, get: function () { return solana_1.SolanaManager; } });
|
|
27
|
+
var solana_2 = require("./solana");
|
|
28
|
+
Object.defineProperty(exports, "SOLANA_CHAIN_IDS", { enumerable: true, get: function () { return solana_2.SOLANA_CHAIN_IDS; } });
|
|
29
|
+
Object.defineProperty(exports, "DEFAULT_SOLANA_CHAIN_ID", { enumerable: true, get: function () { return solana_2.DEFAULT_SOLANA_CHAIN_ID; } });
|
|
30
|
+
Object.defineProperty(exports, "isSolanaChainId", { enumerable: true, get: function () { return solana_2.isSolanaChainId; } });
|
|
27
31
|
if (typeof window !== "undefined")
|
|
28
32
|
window.formofy = initialization_1.formofy;
|
|
29
33
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,24 +1,49 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SolanaManager
|
|
3
3
|
*
|
|
4
|
-
* Manages the lifecycle of the
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Manages the lifecycle of the Solana store integration.
|
|
5
|
+
* Subscribes to framework-kit's zustand store for automatic event capture
|
|
6
|
+
* of wallet connect/disconnect and transaction lifecycle events.
|
|
7
|
+
*
|
|
8
|
+
* For signMessage/signTransaction tracking (not captured by the store),
|
|
9
|
+
* use formo.signature() directly with the address and chainId.
|
|
10
|
+
*
|
|
11
|
+
* For manual event tracking without the store, use the core API directly:
|
|
12
|
+
* formo.transaction(), formo.signature(), formo.connect(), formo.disconnect().
|
|
7
13
|
*/
|
|
8
14
|
import { FormoAnalytics } from "../FormoAnalytics";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
15
|
+
import { SolanaCluster, SolanaOptions } from "./types";
|
|
16
|
+
import { SolanaClientStore } from "./storeTypes";
|
|
11
17
|
export declare class SolanaManager {
|
|
12
18
|
private formo;
|
|
13
|
-
private
|
|
14
|
-
private pendingConnection?;
|
|
19
|
+
private storeHandler?;
|
|
15
20
|
private pendingCluster?;
|
|
16
21
|
constructor(formo: FormoAnalytics, options?: SolanaOptions);
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Set the framework-kit zustand store for automatic event tracking.
|
|
24
|
+
* This enables autocapture mode — connect/disconnect and transaction events
|
|
25
|
+
* are tracked automatically by subscribing to store state changes.
|
|
26
|
+
*
|
|
27
|
+
* @param store - The framework-kit client store (client.store)
|
|
28
|
+
* @param options - Optional configuration
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* import { createClient } from '@solana-foundation/framework-kit';
|
|
33
|
+
*
|
|
34
|
+
* const client = createClient({ endpoint: '...', walletConnectors: autoDiscover() });
|
|
35
|
+
* formo.solana.setStore(client.store);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
setStore(store: SolanaClientStore, options?: {
|
|
39
|
+
cluster?: SolanaCluster;
|
|
40
|
+
}): void;
|
|
41
|
+
/**
|
|
42
|
+
* Update the cluster/network. Only needed if the store endpoint doesn't
|
|
43
|
+
* contain a recognizable cluster name (e.g. custom RPC URLs).
|
|
44
|
+
* In most cases, the cluster is auto-detected from the store's endpoint.
|
|
45
|
+
*/
|
|
20
46
|
setCluster(cluster: SolanaCluster): void;
|
|
21
|
-
syncWalletState(): void;
|
|
22
47
|
cleanup(): void;
|
|
23
48
|
}
|
|
24
49
|
//# sourceMappingURL=SolanaManager.d.ts.map
|
|
@@ -2,77 +2,75 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* SolanaManager
|
|
4
4
|
*
|
|
5
|
-
* Manages the lifecycle of the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Manages the lifecycle of the Solana store integration.
|
|
6
|
+
* Subscribes to framework-kit's zustand store for automatic event capture
|
|
7
|
+
* of wallet connect/disconnect and transaction lifecycle events.
|
|
8
|
+
*
|
|
9
|
+
* For signMessage/signTransaction tracking (not captured by the store),
|
|
10
|
+
* use formo.signature() directly with the address and chainId.
|
|
11
|
+
*
|
|
12
|
+
* For manual event tracking without the store, use the core API directly:
|
|
13
|
+
* formo.transaction(), formo.signature(), formo.connect(), formo.disconnect().
|
|
8
14
|
*/
|
|
9
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
16
|
exports.SolanaManager = void 0;
|
|
11
17
|
var logger_1 = require("../logger");
|
|
12
|
-
var
|
|
18
|
+
var SolanaStoreHandler_1 = require("./SolanaStoreHandler");
|
|
13
19
|
var SolanaManager = /** @class */ (function () {
|
|
14
20
|
function SolanaManager(formo, options) {
|
|
15
21
|
this.formo = formo;
|
|
16
|
-
if (options === null || options === void 0 ? void 0 : options.
|
|
17
|
-
logger_1.logger.info("SolanaManager: Initializing Solana
|
|
18
|
-
this.
|
|
19
|
-
wallet: options.wallet,
|
|
20
|
-
connection: options.connection,
|
|
22
|
+
if (options === null || options === void 0 ? void 0 : options.store) {
|
|
23
|
+
logger_1.logger.info("SolanaManager: Initializing store-based Solana tracking");
|
|
24
|
+
this.storeHandler = new SolanaStoreHandler_1.SolanaStoreHandler(formo, options.store, {
|
|
21
25
|
cluster: options.cluster,
|
|
22
26
|
});
|
|
23
27
|
}
|
|
24
|
-
else if (options) {
|
|
25
|
-
// Store pending
|
|
26
|
-
this.pendingConnection = options.connection;
|
|
28
|
+
else if (options === null || options === void 0 ? void 0 : options.cluster) {
|
|
29
|
+
// Store pending cluster for when setStore is called later
|
|
27
30
|
this.pendingCluster = options.cluster;
|
|
28
31
|
}
|
|
29
32
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (this.handler) {
|
|
54
|
-
this.handler.setConnection(connection);
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
this.pendingConnection = connection !== null && connection !== void 0 ? connection : undefined;
|
|
58
|
-
}
|
|
33
|
+
/**
|
|
34
|
+
* Set the framework-kit zustand store for automatic event tracking.
|
|
35
|
+
* This enables autocapture mode — connect/disconnect and transaction events
|
|
36
|
+
* are tracked automatically by subscribing to store state changes.
|
|
37
|
+
*
|
|
38
|
+
* @param store - The framework-kit client store (client.store)
|
|
39
|
+
* @param options - Optional configuration
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```tsx
|
|
43
|
+
* import { createClient } from '@solana-foundation/framework-kit';
|
|
44
|
+
*
|
|
45
|
+
* const client = createClient({ endpoint: '...', walletConnectors: autoDiscover() });
|
|
46
|
+
* formo.solana.setStore(client.store);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
SolanaManager.prototype.setStore = function (store, options) {
|
|
50
|
+
var _a;
|
|
51
|
+
(_a = this.storeHandler) === null || _a === void 0 ? void 0 : _a.cleanup();
|
|
52
|
+
this.storeHandler = new SolanaStoreHandler_1.SolanaStoreHandler(this.formo, store, {
|
|
53
|
+
cluster: (options === null || options === void 0 ? void 0 : options.cluster) || this.pendingCluster,
|
|
54
|
+
});
|
|
55
|
+
this.pendingCluster = undefined;
|
|
59
56
|
};
|
|
57
|
+
/**
|
|
58
|
+
* Update the cluster/network. Only needed if the store endpoint doesn't
|
|
59
|
+
* contain a recognizable cluster name (e.g. custom RPC URLs).
|
|
60
|
+
* In most cases, the cluster is auto-detected from the store's endpoint.
|
|
61
|
+
*/
|
|
60
62
|
SolanaManager.prototype.setCluster = function (cluster) {
|
|
61
|
-
if (this.
|
|
62
|
-
this.
|
|
63
|
+
if (this.storeHandler) {
|
|
64
|
+
this.storeHandler.setCluster(cluster);
|
|
63
65
|
}
|
|
64
66
|
else {
|
|
65
67
|
this.pendingCluster = cluster;
|
|
66
68
|
}
|
|
67
69
|
};
|
|
68
|
-
SolanaManager.prototype.syncWalletState = function () {
|
|
69
|
-
var _a;
|
|
70
|
-
(_a = this.handler) === null || _a === void 0 ? void 0 : _a.syncWalletState();
|
|
71
|
-
};
|
|
72
70
|
SolanaManager.prototype.cleanup = function () {
|
|
73
71
|
var _a;
|
|
74
|
-
(_a = this.
|
|
75
|
-
this.
|
|
72
|
+
(_a = this.storeHandler) === null || _a === void 0 ? void 0 : _a.cleanup();
|
|
73
|
+
this.storeHandler = undefined;
|
|
76
74
|
};
|
|
77
75
|
return SolanaManager;
|
|
78
76
|
}());
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SolanaStoreHandler
|
|
3
|
+
*
|
|
4
|
+
* Handles wallet event tracking by subscribing to framework-kit's zustand store.
|
|
5
|
+
* This provides automatic event capture (autocapture) for Solana wallets without
|
|
6
|
+
* wrapping any wallet methods — similar to how WagmiEventHandler subscribes to
|
|
7
|
+
* TanStack Query's mutation/query caches.
|
|
8
|
+
*
|
|
9
|
+
* Subscribes to:
|
|
10
|
+
* - `state.wallet` — connect/disconnect events
|
|
11
|
+
* - `state.transactions` — transaction lifecycle events (sending → confirmed/failed)
|
|
12
|
+
*
|
|
13
|
+
* @see https://github.com/solana-foundation/framework-kit
|
|
14
|
+
*/
|
|
15
|
+
import { FormoAnalytics } from "../FormoAnalytics";
|
|
16
|
+
import { SolanaClientStore } from "./storeTypes";
|
|
17
|
+
import { SolanaCluster } from "./types";
|
|
18
|
+
export declare class SolanaStoreHandler {
|
|
19
|
+
private formo;
|
|
20
|
+
private store;
|
|
21
|
+
private unsubscribers;
|
|
22
|
+
private cluster;
|
|
23
|
+
private chainId;
|
|
24
|
+
/**
|
|
25
|
+
* Track last known wallet status to detect transitions.
|
|
26
|
+
*/
|
|
27
|
+
private lastWalletStatus;
|
|
28
|
+
private lastAddress?;
|
|
29
|
+
private lastChainId?;
|
|
30
|
+
/**
|
|
31
|
+
* Track processed transaction state changes to prevent duplicate events.
|
|
32
|
+
* Key format: `${signature}:${status}`
|
|
33
|
+
*/
|
|
34
|
+
private processedTransactions;
|
|
35
|
+
/**
|
|
36
|
+
* Track transactions we've emitted STARTED for (status was "sending").
|
|
37
|
+
* Ensures we only emit STARTED once per transaction key.
|
|
38
|
+
*/
|
|
39
|
+
private startedTransactions;
|
|
40
|
+
/**
|
|
41
|
+
* Per-transaction sender address captured at STARTED time.
|
|
42
|
+
* Ensures terminal events (confirmed/failed) are attributed correctly
|
|
43
|
+
* even if the wallet disconnects before the transaction settles.
|
|
44
|
+
*/
|
|
45
|
+
private transactionSenders;
|
|
46
|
+
/**
|
|
47
|
+
* Whether the cluster was explicitly set (via options or setCluster).
|
|
48
|
+
* When true, auto-detection from the store endpoint is disabled.
|
|
49
|
+
*/
|
|
50
|
+
private explicitCluster;
|
|
51
|
+
constructor(formoAnalytics: FormoAnalytics, store: SolanaClientStore, options?: {
|
|
52
|
+
cluster?: SolanaCluster;
|
|
53
|
+
});
|
|
54
|
+
/**
|
|
55
|
+
* Update the cluster/network.
|
|
56
|
+
*/
|
|
57
|
+
setCluster(cluster: SolanaCluster): void;
|
|
58
|
+
/**
|
|
59
|
+
* Get the current chain ID.
|
|
60
|
+
*/
|
|
61
|
+
getChainId(): number;
|
|
62
|
+
/**
|
|
63
|
+
* Resolve the current chainId from the live store state.
|
|
64
|
+
* This ensures correctness when wallet and cluster change in the same tick
|
|
65
|
+
* (the cluster subscription may not have fired yet).
|
|
66
|
+
*/
|
|
67
|
+
private resolveCurrentChainId;
|
|
68
|
+
private setupWalletSubscription;
|
|
69
|
+
private checkInitialWalletState;
|
|
70
|
+
private handleWalletChange;
|
|
71
|
+
private handleConnect;
|
|
72
|
+
private handleDisconnect;
|
|
73
|
+
private setupClusterSubscription;
|
|
74
|
+
private handleClusterChange;
|
|
75
|
+
private setupTransactionSubscription;
|
|
76
|
+
private handleTransactionChanges;
|
|
77
|
+
private handleTransactionStatusChange;
|
|
78
|
+
/**
|
|
79
|
+
* Attempt to detect the Solana cluster from the store's endpoint URL.
|
|
80
|
+
*/
|
|
81
|
+
private detectClusterFromStore;
|
|
82
|
+
/**
|
|
83
|
+
* Detect cluster from an RPC endpoint URL.
|
|
84
|
+
*/
|
|
85
|
+
private detectClusterFromEndpoint;
|
|
86
|
+
cleanup(): void;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=SolanaStoreHandler.d.ts.map
|