@formo/analytics 1.27.0 → 1.28.1
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 +69 -12
- package/dist/cjs/src/FormoAnalytics.js +273 -147
- package/dist/cjs/src/event/EventFactory.d.ts +10 -2
- package/dist/cjs/src/event/EventFactory.js +32 -21
- package/dist/cjs/src/index.d.ts +4 -0
- package/dist/cjs/src/index.js +6 -0
- package/dist/cjs/src/privy/index.d.ts +9 -0
- package/dist/cjs/src/privy/index.js +12 -0
- package/dist/cjs/src/privy/types.d.ts +176 -0
- package/dist/cjs/src/privy/types.js +12 -0
- package/dist/cjs/src/privy/utils.d.ts +32 -0
- package/dist/cjs/src/privy/utils.js +191 -0
- package/dist/cjs/src/session/index.js +2 -1
- package/dist/cjs/src/solana/SolanaAdapter.d.ts +211 -0
- package/dist/cjs/src/solana/SolanaAdapter.js +975 -0
- package/dist/cjs/src/solana/SolanaManager.d.ts +24 -0
- package/dist/cjs/src/solana/SolanaManager.js +80 -0
- package/dist/cjs/src/solana/address.d.ts +72 -0
- package/dist/cjs/src/solana/address.js +176 -0
- package/dist/cjs/src/solana/index.d.ts +13 -0
- package/dist/cjs/src/solana/index.js +32 -0
- package/dist/cjs/src/solana/types.d.ts +206 -0
- package/dist/cjs/src/solana/types.js +80 -0
- package/dist/cjs/src/types/base.d.ts +17 -0
- package/dist/cjs/src/types/events.d.ts +4 -3
- package/dist/cjs/src/utils/address.d.ts +21 -0
- package/dist/cjs/src/utils/address.js +48 -1
- package/dist/cjs/src/utils/builderCode.d.ts +30 -0
- package/dist/cjs/src/utils/builderCode.js +143 -0
- package/dist/cjs/src/utils/index.d.ts +1 -0
- package/dist/cjs/src/utils/index.js +1 -0
- package/dist/cjs/src/version.d.ts +1 -1
- package/dist/cjs/src/version.js +1 -1
- package/dist/cjs/src/wagmi/WagmiEventHandler.js +13 -15
- package/dist/cjs/src/wagmi/utils.d.ts +5 -0
- package/dist/cjs/src/wagmi/utils.js +20 -0
- package/dist/esm/src/FormoAnalytics.d.ts +69 -12
- package/dist/esm/src/FormoAnalytics.js +274 -148
- package/dist/esm/src/event/EventFactory.d.ts +10 -2
- package/dist/esm/src/event/EventFactory.js +34 -23
- package/dist/esm/src/index.d.ts +4 -0
- package/dist/esm/src/index.js +3 -0
- package/dist/esm/src/privy/index.d.ts +9 -0
- package/dist/esm/src/privy/index.js +8 -0
- package/dist/esm/src/privy/types.d.ts +176 -0
- package/dist/esm/src/privy/types.js +11 -0
- package/dist/esm/src/privy/utils.d.ts +32 -0
- package/dist/esm/src/privy/utils.js +188 -0
- package/dist/esm/src/session/index.js +2 -1
- package/dist/esm/src/solana/SolanaAdapter.d.ts +211 -0
- package/dist/esm/src/solana/SolanaAdapter.js +972 -0
- package/dist/esm/src/solana/SolanaManager.d.ts +24 -0
- package/dist/esm/src/solana/SolanaManager.js +77 -0
- package/dist/esm/src/solana/address.d.ts +72 -0
- package/dist/esm/src/solana/address.js +167 -0
- package/dist/esm/src/solana/index.d.ts +13 -0
- package/dist/esm/src/solana/index.js +13 -0
- package/dist/esm/src/solana/types.d.ts +206 -0
- package/dist/esm/src/solana/types.js +74 -0
- package/dist/esm/src/types/base.d.ts +17 -0
- package/dist/esm/src/types/events.d.ts +4 -3
- package/dist/esm/src/utils/address.d.ts +21 -0
- package/dist/esm/src/utils/address.js +45 -0
- package/dist/esm/src/utils/builderCode.d.ts +30 -0
- package/dist/esm/src/utils/builderCode.js +140 -0
- package/dist/esm/src/utils/index.d.ts +1 -0
- package/dist/esm/src/utils/index.js +1 -0
- package/dist/esm/src/version.d.ts +1 -1
- package/dist/esm/src/version.js +1 -1
- package/dist/esm/src/wagmi/WagmiEventHandler.js +14 -16
- package/dist/esm/src/wagmi/utils.d.ts +5 -0
- package/dist/esm/src/wagmi/utils.js +19 -0
- package/dist/index.umd.min.js +1 -1
- package/package.json +15 -3
|
@@ -4,6 +4,14 @@ declare class EventFactory implements IEventFactory {
|
|
|
4
4
|
private options?;
|
|
5
5
|
private compiledPathPattern?;
|
|
6
6
|
constructor(options?: Options);
|
|
7
|
+
/**
|
|
8
|
+
* Validate an address for both EVM and Solana chains.
|
|
9
|
+
* Uses chainId for strict validation when available.
|
|
10
|
+
* @param address The address to validate
|
|
11
|
+
* @param chainId Optional chain ID for strict chain-specific validation
|
|
12
|
+
* @returns The validated address or null if invalid
|
|
13
|
+
*/
|
|
14
|
+
private validateEventAddress;
|
|
7
15
|
private getTimezone;
|
|
8
16
|
private getLocation;
|
|
9
17
|
private getLanguage;
|
|
@@ -22,12 +30,12 @@ declare class EventFactory implements IEventFactory {
|
|
|
22
30
|
private getEnrichedEvent;
|
|
23
31
|
generatePageEvent(category?: string, name?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
24
32
|
generateDetectWalletEvent(providerName: string, rdns: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
25
|
-
generateIdentifyEvent(providerName
|
|
33
|
+
generateIdentifyEvent(providerName?: string, rdns?: string, address?: Nullable<Address>, userId?: Nullable<string>, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
26
34
|
generateConnectEvent(chainId: ChainID, address: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
27
35
|
generateDisconnectEvent(chainId?: ChainID, address?: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
28
36
|
generateChainChangedEvent(chainId: ChainID, address: Address, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
29
37
|
generateSignatureEvent(status: SignatureStatus, chainId: ChainID, address: Address, message: string, signatureHash?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
30
|
-
generateTransactionEvent(status: TransactionStatus, chainId: ChainID, address: Address, data?: string, to?: string, value?: string, transactionHash?: string, function_name?: string, function_args?: Record<string, unknown>, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
38
|
+
generateTransactionEvent(status: TransactionStatus, chainId: ChainID, address: Address, data?: string, to?: string, value?: string, transactionHash?: string, function_name?: string, function_args?: Record<string, unknown>, builder_codes?: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
31
39
|
generateTrackEvent(event: string, properties?: IFormoEventProperties, context?: IFormoEventContext): Promise<IFormoEvent>;
|
|
32
40
|
create(event: APIEvent, address?: Address, userId?: string): Promise<IFormoEvent>;
|
|
33
41
|
}
|
|
@@ -198,6 +198,19 @@ var EventFactory = /** @class */ (function () {
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Validate an address for both EVM and Solana chains.
|
|
203
|
+
* Uses chainId for strict validation when available.
|
|
204
|
+
* @param address The address to validate
|
|
205
|
+
* @param chainId Optional chain ID for strict chain-specific validation
|
|
206
|
+
* @returns The validated address or null if invalid
|
|
207
|
+
*/
|
|
208
|
+
EventFactory.prototype.validateEventAddress = function (address, chainId) {
|
|
209
|
+
if (!address) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
return (0, address_1.validateAddress)(address, chainId) || null;
|
|
213
|
+
};
|
|
201
214
|
EventFactory.prototype.getTimezone = function () {
|
|
202
215
|
try {
|
|
203
216
|
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
@@ -280,15 +293,16 @@ var EventFactory = /** @class */ (function () {
|
|
|
280
293
|
};
|
|
281
294
|
EventFactory.prototype.getEnrichedEvent = function (formoEvent, context) {
|
|
282
295
|
return __awaiter(this, void 0, void 0, function () {
|
|
283
|
-
var commonEventData, validAddress, processedEvent;
|
|
296
|
+
var commonEventData, eventChainId, validAddress, processedEvent;
|
|
284
297
|
var _a;
|
|
285
|
-
|
|
286
|
-
|
|
298
|
+
var _b;
|
|
299
|
+
return __generator(this, function (_c) {
|
|
300
|
+
switch (_c.label) {
|
|
287
301
|
case 0:
|
|
288
302
|
_a = {};
|
|
289
303
|
return [4 /*yield*/, this.generateContext(context)];
|
|
290
304
|
case 1:
|
|
291
|
-
commonEventData = (_a.context =
|
|
305
|
+
commonEventData = (_a.context = _c.sent(),
|
|
292
306
|
_a.original_timestamp = (0, timestamp_1.getCurrentTimeFormatted)(),
|
|
293
307
|
_a.user_id = formoEvent.user_id,
|
|
294
308
|
_a.type = formoEvent.type,
|
|
@@ -296,13 +310,9 @@ var EventFactory = /** @class */ (function () {
|
|
|
296
310
|
_a.version = constants_2.VERSION,
|
|
297
311
|
_a);
|
|
298
312
|
commonEventData.anonymous_id = (0, utils_2.generateAnonymousId)(constants_1.LOCAL_ANONYMOUS_ID_KEY);
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
else {
|
|
304
|
-
commonEventData.address = null;
|
|
305
|
-
}
|
|
313
|
+
eventChainId = (_b = formoEvent.properties) === null || _b === void 0 ? void 0 : _b.chainId;
|
|
314
|
+
validAddress = this.validateEventAddress(formoEvent.address, eventChainId);
|
|
315
|
+
commonEventData.address = validAddress;
|
|
306
316
|
processedEvent = (0, mergeDeepRight_1.default)(formoEvent, commonEventData);
|
|
307
317
|
if (processedEvent.event === undefined) {
|
|
308
318
|
processedEvent.event = null;
|
|
@@ -348,7 +358,7 @@ var EventFactory = /** @class */ (function () {
|
|
|
348
358
|
var identifyEvent;
|
|
349
359
|
return __generator(this, function (_a) {
|
|
350
360
|
identifyEvent = {
|
|
351
|
-
properties: __assign({ providerName: providerName, rdns: rdns }, properties),
|
|
361
|
+
properties: __assign(__assign(__assign({}, (providerName !== undefined && { providerName: providerName })), (rdns !== undefined && { rdns: rdns })), properties),
|
|
352
362
|
user_id: userId,
|
|
353
363
|
address: address,
|
|
354
364
|
type: "identify",
|
|
@@ -409,12 +419,12 @@ var EventFactory = /** @class */ (function () {
|
|
|
409
419
|
});
|
|
410
420
|
});
|
|
411
421
|
};
|
|
412
|
-
EventFactory.prototype.generateTransactionEvent = function (status, chainId, address, data, to, value, transactionHash, function_name, function_args, properties, context) {
|
|
422
|
+
EventFactory.prototype.generateTransactionEvent = function (status, chainId, address, data, to, value, transactionHash, function_name, function_args, builder_codes, properties, context) {
|
|
413
423
|
return __awaiter(this, void 0, void 0, function () {
|
|
414
424
|
var transactionEvent;
|
|
415
425
|
return __generator(this, function (_a) {
|
|
416
426
|
transactionEvent = {
|
|
417
|
-
properties: __assign(__assign(__assign(__assign(__assign(__assign(__assign({ status: status, chainId: chainId }, (data && { data: data })), (to && { to: to })), (value && { value: value })), (transactionHash && { transactionHash: transactionHash })), (function_name && { function_name: function_name })), (function_args && { function_args: function_args })), properties),
|
|
427
|
+
properties: __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({ status: status, chainId: chainId }, (data && { data: data })), (to && { to: to })), (value && { value: value })), (transactionHash && { transactionHash: transactionHash })), (function_name && { function_name: function_name })), (function_args && { function_args: function_args })), (builder_codes && { builder_codes: builder_codes })), properties),
|
|
418
428
|
address: address,
|
|
419
429
|
type: "transaction",
|
|
420
430
|
};
|
|
@@ -447,7 +457,7 @@ var EventFactory = /** @class */ (function () {
|
|
|
447
457
|
// Returns an event with type, context, properties, and common properties
|
|
448
458
|
EventFactory.prototype.create = function (event, address, userId) {
|
|
449
459
|
return __awaiter(this, void 0, void 0, function () {
|
|
450
|
-
var formoEvent, _a,
|
|
460
|
+
var formoEvent, _a, chainId;
|
|
451
461
|
return __generator(this, function (_b) {
|
|
452
462
|
switch (_b.label) {
|
|
453
463
|
case 0:
|
|
@@ -493,7 +503,7 @@ var EventFactory = /** @class */ (function () {
|
|
|
493
503
|
case 14:
|
|
494
504
|
formoEvent = _b.sent();
|
|
495
505
|
return [3 /*break*/, 19];
|
|
496
|
-
case 15: return [4 /*yield*/, this.generateTransactionEvent(event.status, event.chainId, event.address, event.data, event.to, event.value, event.transactionHash, event.function_name, event.function_args, event.properties, event.context)];
|
|
506
|
+
case 15: return [4 /*yield*/, this.generateTransactionEvent(event.status, event.chainId, event.address, event.data, event.to, event.value, event.transactionHash, event.function_name, event.function_args, event.builder_codes, event.properties, event.context)];
|
|
497
507
|
case 16:
|
|
498
508
|
formoEvent = _b.sent();
|
|
499
509
|
return [3 /*break*/, 19];
|
|
@@ -503,11 +513,12 @@ var EventFactory = /** @class */ (function () {
|
|
|
503
513
|
return [3 /*break*/, 19];
|
|
504
514
|
case 19:
|
|
505
515
|
// Set address if not already set by the specific event generator
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
516
|
+
// Uses chainId for strict chain-specific validation
|
|
517
|
+
// Skip backfill for identify events to prevent stale address being used
|
|
518
|
+
if ((formoEvent.address === undefined || formoEvent.address === null) &&
|
|
519
|
+
event.type !== "identify") {
|
|
520
|
+
chainId = 'chainId' in event ? event.chainId : undefined;
|
|
521
|
+
formoEvent.address = this.validateEventAddress(address, chainId);
|
|
511
522
|
}
|
|
512
523
|
formoEvent.user_id = userId || null;
|
|
513
524
|
return [2 /*return*/, formoEvent];
|
package/dist/cjs/src/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
export * from "./FormoAnalyticsProvider";
|
|
2
2
|
export * from "./FormoAnalytics";
|
|
3
3
|
export * from "./types";
|
|
4
|
+
export { parsePrivyProperties } from "./privy";
|
|
5
|
+
export type { PrivyUser, PrivyLinkedAccount, PrivyAccountType, PrivyProfileProperties, PrivyWalletInfo } from "./privy";
|
|
6
|
+
export { SolanaManager } from "./solana";
|
|
7
|
+
export type { SolanaOptions, SolanaCluster, ISolanaAdapter, SolanaWalletContext, SolanaPublicKey, SolanaConnection, } from "./solana";
|
|
4
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/src/index.js
CHANGED
|
@@ -14,10 +14,16 @@ 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
18
|
var initialization_1 = require("./initialization");
|
|
18
19
|
__exportStar(require("./FormoAnalyticsProvider"), exports);
|
|
19
20
|
__exportStar(require("./FormoAnalytics"), exports);
|
|
20
21
|
__exportStar(require("./types"), exports);
|
|
22
|
+
var privy_1 = require("./privy");
|
|
23
|
+
Object.defineProperty(exports, "parsePrivyProperties", { enumerable: true, get: function () { return privy_1.parsePrivyProperties; } });
|
|
24
|
+
// Solana integration exports
|
|
25
|
+
var solana_1 = require("./solana");
|
|
26
|
+
Object.defineProperty(exports, "SolanaManager", { enumerable: true, get: function () { return solana_1.SolanaManager; } });
|
|
21
27
|
if (typeof window !== "undefined")
|
|
22
28
|
window.formofy = initialization_1.formofy;
|
|
23
29
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Privy integration module
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for enriching wallet profiles with Privy user data.
|
|
5
|
+
* This module exports the property extraction utility and related types.
|
|
6
|
+
*/
|
|
7
|
+
export { parsePrivyProperties } from "./utils";
|
|
8
|
+
export type { PrivyUser, PrivyLinkedAccount, PrivyAccountType, PrivyProfileProperties, PrivyWalletInfo, } from "./types";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Privy integration module
|
|
4
|
+
*
|
|
5
|
+
* Provides utilities for enriching wallet profiles with Privy user data.
|
|
6
|
+
* This module exports the property extraction utility and related types.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.parsePrivyProperties = void 0;
|
|
10
|
+
var utils_1 = require("./utils");
|
|
11
|
+
Object.defineProperty(exports, "parsePrivyProperties", { enumerable: true, get: function () { return utils_1.parsePrivyProperties; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Privy-specific type definitions for user profile enrichment
|
|
3
|
+
*
|
|
4
|
+
* These types provide TypeScript interfaces for Privy user objects
|
|
5
|
+
* from the Privy React SDK (`usePrivy()` hook).
|
|
6
|
+
*
|
|
7
|
+
* Based on the Privy user object structure:
|
|
8
|
+
* https://docs.privy.io/user-management/users/the-user-object
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Valid Privy linked account type strings.
|
|
12
|
+
*/
|
|
13
|
+
export type PrivyAccountType = "email" | "phone" | "wallet" | "smart_wallet" | "farcaster" | "telegram" | "apple_oauth" | "discord_oauth" | "github_oauth" | "google_oauth" | "instagram_oauth" | "linkedin_oauth" | "spotify_oauth" | "tiktok_oauth" | "twitter_oauth" | "twitch_oauth" | "line_oauth" | "custom_auth" | "passkey" | "cross_app" | "guest" | string;
|
|
14
|
+
/**
|
|
15
|
+
* A linked account entry from the Privy user object.
|
|
16
|
+
* Each linked account has a `type` discriminator and type-specific fields.
|
|
17
|
+
*/
|
|
18
|
+
export interface PrivyLinkedAccount {
|
|
19
|
+
type: PrivyAccountType;
|
|
20
|
+
address?: string | null;
|
|
21
|
+
number?: string | null;
|
|
22
|
+
username?: string | null;
|
|
23
|
+
name?: string | null;
|
|
24
|
+
displayName?: string | null;
|
|
25
|
+
subject?: string | null;
|
|
26
|
+
email?: string | null;
|
|
27
|
+
chainType?: string | null;
|
|
28
|
+
walletClient?: string | null;
|
|
29
|
+
walletClientType?: string | null;
|
|
30
|
+
connectorType?: string | null;
|
|
31
|
+
delegated?: boolean;
|
|
32
|
+
fid?: number | null;
|
|
33
|
+
ownerAddress?: string | null;
|
|
34
|
+
bio?: string | null;
|
|
35
|
+
pfp?: string | null;
|
|
36
|
+
url?: string | null;
|
|
37
|
+
signerPublicKey?: string | null;
|
|
38
|
+
telegramUserId?: string | null;
|
|
39
|
+
firstName?: string | null;
|
|
40
|
+
lastName?: string | null;
|
|
41
|
+
firstVerifiedAt?: Date | null;
|
|
42
|
+
latestVerifiedAt?: Date | null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Privy user object as returned by the Privy React SDK.
|
|
46
|
+
*
|
|
47
|
+
* Convenience accessors: user.email, user.phone, user.wallet, user.discord,
|
|
48
|
+
* user.twitter, user.farcaster, user.github, user.google, user.linkedin,
|
|
49
|
+
* user.apple, user.instagram, user.spotify, user.tiktok, user.telegram, user.line
|
|
50
|
+
*/
|
|
51
|
+
export interface PrivyUser {
|
|
52
|
+
/** Privy user ID in DID format (e.g., "did:privy:cm3np...") */
|
|
53
|
+
id: string;
|
|
54
|
+
/** Account creation timestamp */
|
|
55
|
+
createdAt?: Date;
|
|
56
|
+
/** All linked accounts */
|
|
57
|
+
linkedAccounts?: PrivyLinkedAccount[];
|
|
58
|
+
/** Optional custom metadata */
|
|
59
|
+
customMetadata?: Record<string, unknown>;
|
|
60
|
+
email?: {
|
|
61
|
+
address: string;
|
|
62
|
+
};
|
|
63
|
+
phone?: {
|
|
64
|
+
number: string;
|
|
65
|
+
};
|
|
66
|
+
wallet?: {
|
|
67
|
+
address: string;
|
|
68
|
+
chainType?: string;
|
|
69
|
+
walletClient?: string;
|
|
70
|
+
walletClientType?: string;
|
|
71
|
+
connectorType?: string;
|
|
72
|
+
};
|
|
73
|
+
google?: {
|
|
74
|
+
subject: string;
|
|
75
|
+
email: string;
|
|
76
|
+
name: string | null;
|
|
77
|
+
};
|
|
78
|
+
discord?: {
|
|
79
|
+
subject: string;
|
|
80
|
+
username: string | null;
|
|
81
|
+
email: string | null;
|
|
82
|
+
};
|
|
83
|
+
twitter?: {
|
|
84
|
+
subject: string;
|
|
85
|
+
username: string | null;
|
|
86
|
+
name: string | null;
|
|
87
|
+
profilePictureUrl: string | null;
|
|
88
|
+
};
|
|
89
|
+
farcaster?: {
|
|
90
|
+
fid: number | null;
|
|
91
|
+
ownerAddress: string;
|
|
92
|
+
username: string | null;
|
|
93
|
+
displayName: string | null;
|
|
94
|
+
bio: string | null;
|
|
95
|
+
pfp: string | null;
|
|
96
|
+
};
|
|
97
|
+
github?: {
|
|
98
|
+
subject: string;
|
|
99
|
+
username: string | null;
|
|
100
|
+
name: string | null;
|
|
101
|
+
};
|
|
102
|
+
linkedin?: {
|
|
103
|
+
subject: string;
|
|
104
|
+
name: string | null;
|
|
105
|
+
email: string | null;
|
|
106
|
+
vanityName: string | null;
|
|
107
|
+
};
|
|
108
|
+
apple?: {
|
|
109
|
+
subject: string;
|
|
110
|
+
email: string;
|
|
111
|
+
};
|
|
112
|
+
instagram?: {
|
|
113
|
+
subject: string;
|
|
114
|
+
username: string | null;
|
|
115
|
+
};
|
|
116
|
+
spotify?: {
|
|
117
|
+
subject: string;
|
|
118
|
+
email: string | null;
|
|
119
|
+
name: string | null;
|
|
120
|
+
};
|
|
121
|
+
tiktok?: {
|
|
122
|
+
subject: string;
|
|
123
|
+
username: string | null;
|
|
124
|
+
name: string | null;
|
|
125
|
+
};
|
|
126
|
+
line?: {
|
|
127
|
+
subject: string;
|
|
128
|
+
name: string | null;
|
|
129
|
+
email: string | null;
|
|
130
|
+
};
|
|
131
|
+
telegram?: {
|
|
132
|
+
telegramUserId: string;
|
|
133
|
+
firstName: string | null;
|
|
134
|
+
lastName: string | null;
|
|
135
|
+
username: string | null;
|
|
136
|
+
photoUrl: string | null;
|
|
137
|
+
};
|
|
138
|
+
/** MFA methods */
|
|
139
|
+
mfaMethods?: Array<string>;
|
|
140
|
+
/** Whether the user has accepted terms */
|
|
141
|
+
hasAcceptedTerms?: boolean;
|
|
142
|
+
/** Whether this is a guest user */
|
|
143
|
+
isGuest?: boolean;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Extracted profile properties from a Privy user.
|
|
147
|
+
* These are the properties that get sent as event properties via `identify()`.
|
|
148
|
+
*/
|
|
149
|
+
export interface PrivyProfileProperties {
|
|
150
|
+
privyDid: string;
|
|
151
|
+
privyCreatedAt?: number;
|
|
152
|
+
email?: string;
|
|
153
|
+
apple?: string;
|
|
154
|
+
discord?: string;
|
|
155
|
+
twitter?: string;
|
|
156
|
+
farcaster?: string;
|
|
157
|
+
github?: string;
|
|
158
|
+
google?: string;
|
|
159
|
+
linkedin?: string;
|
|
160
|
+
line?: string;
|
|
161
|
+
spotify?: string;
|
|
162
|
+
telegram?: string;
|
|
163
|
+
tiktok?: string;
|
|
164
|
+
instagram?: string;
|
|
165
|
+
[key: string]: unknown;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Wallet info extracted from Privy linked accounts.
|
|
169
|
+
*/
|
|
170
|
+
export interface PrivyWalletInfo {
|
|
171
|
+
address: string;
|
|
172
|
+
walletClient?: string;
|
|
173
|
+
chainType?: string;
|
|
174
|
+
isEmbedded: boolean;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Privy-specific type definitions for user profile enrichment
|
|
4
|
+
*
|
|
5
|
+
* These types provide TypeScript interfaces for Privy user objects
|
|
6
|
+
* from the Privy React SDK (`usePrivy()` hook).
|
|
7
|
+
*
|
|
8
|
+
* Based on the Privy user object structure:
|
|
9
|
+
* https://docs.privy.io/user-management/users/the-user-object
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for extracting profile properties from Privy user objects.
|
|
3
|
+
*/
|
|
4
|
+
import { PrivyProfileProperties, PrivyUser, PrivyWalletInfo } from "./types";
|
|
5
|
+
/**
|
|
6
|
+
* Extract profile properties and wallet addresses from a Privy user object.
|
|
7
|
+
*
|
|
8
|
+
* Parses the Privy user's linked accounts into a flat properties object
|
|
9
|
+
* (email, social accounts, etc.) and extracts all linked wallet addresses.
|
|
10
|
+
*
|
|
11
|
+
* @param user - The Privy user object from `usePrivy()`
|
|
12
|
+
* @returns An object with `properties` and `wallets`
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { parsePrivyProperties } from '@formo/analytics';
|
|
17
|
+
*
|
|
18
|
+
* const { user } = usePrivy();
|
|
19
|
+
* if (user) {
|
|
20
|
+
* const { properties, wallets } = parsePrivyProperties(user);
|
|
21
|
+
*
|
|
22
|
+
* for (const wallet of wallets) {
|
|
23
|
+
* formo.identify({ address: wallet.address, userId: user.id }, properties);
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare function parsePrivyProperties(user: PrivyUser): {
|
|
29
|
+
properties: PrivyProfileProperties;
|
|
30
|
+
wallets: PrivyWalletInfo[];
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utility functions for extracting profile properties from Privy user objects.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parsePrivyProperties = parsePrivyProperties;
|
|
7
|
+
/**
|
|
8
|
+
* Extract profile properties and wallet addresses from a Privy user object.
|
|
9
|
+
*
|
|
10
|
+
* Parses the Privy user's linked accounts into a flat properties object
|
|
11
|
+
* (email, social accounts, etc.) and extracts all linked wallet addresses.
|
|
12
|
+
*
|
|
13
|
+
* @param user - The Privy user object from `usePrivy()`
|
|
14
|
+
* @returns An object with `properties` and `wallets`
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { parsePrivyProperties } from '@formo/analytics';
|
|
19
|
+
*
|
|
20
|
+
* const { user } = usePrivy();
|
|
21
|
+
* if (user) {
|
|
22
|
+
* const { properties, wallets } = parsePrivyProperties(user);
|
|
23
|
+
*
|
|
24
|
+
* for (const wallet of wallets) {
|
|
25
|
+
* formo.identify({ address: wallet.address, userId: user.id }, properties);
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
function parsePrivyProperties(user) {
|
|
31
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
32
|
+
var accounts = user.linkedAccounts || [];
|
|
33
|
+
// Extract profile properties
|
|
34
|
+
var properties = {
|
|
35
|
+
privyDid: user.id,
|
|
36
|
+
privyCreatedAt: (_a = user.createdAt) === null || _a === void 0 ? void 0 : _a.getTime(),
|
|
37
|
+
};
|
|
38
|
+
// Email
|
|
39
|
+
if ((_b = user.email) === null || _b === void 0 ? void 0 : _b.address) {
|
|
40
|
+
properties.email = user.email.address;
|
|
41
|
+
}
|
|
42
|
+
// Social accounts - extract usernames/identifiers
|
|
43
|
+
if ((_c = user.apple) === null || _c === void 0 ? void 0 : _c.email) {
|
|
44
|
+
properties.apple = user.apple.email;
|
|
45
|
+
}
|
|
46
|
+
if ((_d = user.discord) === null || _d === void 0 ? void 0 : _d.username) {
|
|
47
|
+
properties.discord = user.discord.username;
|
|
48
|
+
}
|
|
49
|
+
if ((_e = user.farcaster) === null || _e === void 0 ? void 0 : _e.username) {
|
|
50
|
+
properties.farcaster = user.farcaster.username;
|
|
51
|
+
}
|
|
52
|
+
if ((_f = user.github) === null || _f === void 0 ? void 0 : _f.username) {
|
|
53
|
+
properties.github = user.github.username;
|
|
54
|
+
}
|
|
55
|
+
if ((_g = user.google) === null || _g === void 0 ? void 0 : _g.email) {
|
|
56
|
+
properties.google = user.google.email;
|
|
57
|
+
}
|
|
58
|
+
if ((_h = user.instagram) === null || _h === void 0 ? void 0 : _h.username) {
|
|
59
|
+
properties.instagram = user.instagram.username;
|
|
60
|
+
}
|
|
61
|
+
if ((_j = user.line) === null || _j === void 0 ? void 0 : _j.email) {
|
|
62
|
+
properties.line = user.line.email;
|
|
63
|
+
}
|
|
64
|
+
if ((_k = user.linkedin) === null || _k === void 0 ? void 0 : _k.email) {
|
|
65
|
+
properties.linkedin = user.linkedin.email;
|
|
66
|
+
}
|
|
67
|
+
if ((_l = user.spotify) === null || _l === void 0 ? void 0 : _l.email) {
|
|
68
|
+
properties.spotify = user.spotify.email;
|
|
69
|
+
}
|
|
70
|
+
if ((_m = user.telegram) === null || _m === void 0 ? void 0 : _m.username) {
|
|
71
|
+
properties.telegram = user.telegram.username;
|
|
72
|
+
}
|
|
73
|
+
if ((_o = user.tiktok) === null || _o === void 0 ? void 0 : _o.username) {
|
|
74
|
+
properties.tiktok = user.tiktok.username;
|
|
75
|
+
}
|
|
76
|
+
if ((_p = user.twitter) === null || _p === void 0 ? void 0 : _p.username) {
|
|
77
|
+
properties.twitter = user.twitter.username;
|
|
78
|
+
}
|
|
79
|
+
// Fallback to linkedAccounts if convenience accessors are not populated
|
|
80
|
+
if (!properties.email) {
|
|
81
|
+
var emailAccount = accounts.find(function (account) { return account.type === "email"; });
|
|
82
|
+
if (emailAccount === null || emailAccount === void 0 ? void 0 : emailAccount.address) {
|
|
83
|
+
properties.email = emailAccount.address;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (!properties.apple) {
|
|
87
|
+
var appleAccount = accounts.find(function (a) { return a.type === "apple_oauth"; });
|
|
88
|
+
if (appleAccount === null || appleAccount === void 0 ? void 0 : appleAccount.email) {
|
|
89
|
+
properties.apple = appleAccount.email;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!properties.discord) {
|
|
93
|
+
var discordAccount = accounts.find(function (a) { return a.type === "discord_oauth"; });
|
|
94
|
+
if (discordAccount === null || discordAccount === void 0 ? void 0 : discordAccount.username) {
|
|
95
|
+
properties.discord = discordAccount.username;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (!properties.farcaster) {
|
|
99
|
+
var farcasterAccount = accounts.find(function (a) { return a.type === "farcaster"; });
|
|
100
|
+
if (farcasterAccount === null || farcasterAccount === void 0 ? void 0 : farcasterAccount.username) {
|
|
101
|
+
properties.farcaster = farcasterAccount.username;
|
|
102
|
+
}
|
|
103
|
+
else if (farcasterAccount === null || farcasterAccount === void 0 ? void 0 : farcasterAccount.displayName) {
|
|
104
|
+
properties.farcaster = farcasterAccount.displayName;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!properties.github) {
|
|
108
|
+
var githubAccount = accounts.find(function (a) { return a.type === "github_oauth"; });
|
|
109
|
+
if (githubAccount === null || githubAccount === void 0 ? void 0 : githubAccount.username) {
|
|
110
|
+
properties.github = githubAccount.username;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!properties.google) {
|
|
114
|
+
var googleAccount = accounts.find(function (a) { return a.type === "google_oauth"; });
|
|
115
|
+
if (googleAccount === null || googleAccount === void 0 ? void 0 : googleAccount.email) {
|
|
116
|
+
properties.google = googleAccount.email;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (!properties.instagram) {
|
|
120
|
+
var instagramAccount = accounts.find(function (a) { return a.type === "instagram_oauth"; });
|
|
121
|
+
if (instagramAccount === null || instagramAccount === void 0 ? void 0 : instagramAccount.username) {
|
|
122
|
+
properties.instagram = instagramAccount.username;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!properties.line) {
|
|
126
|
+
var lineAccount = accounts.find(function (a) { return a.type === "line_oauth"; });
|
|
127
|
+
if (lineAccount === null || lineAccount === void 0 ? void 0 : lineAccount.email) {
|
|
128
|
+
properties.line = lineAccount.email;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (!properties.linkedin) {
|
|
132
|
+
var linkedinAccount = accounts.find(function (a) { return a.type === "linkedin_oauth"; });
|
|
133
|
+
if (linkedinAccount === null || linkedinAccount === void 0 ? void 0 : linkedinAccount.email) {
|
|
134
|
+
properties.linkedin = linkedinAccount.email;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (!properties.spotify) {
|
|
138
|
+
var spotifyAccount = accounts.find(function (a) { return a.type === "spotify_oauth"; });
|
|
139
|
+
if (spotifyAccount === null || spotifyAccount === void 0 ? void 0 : spotifyAccount.email) {
|
|
140
|
+
properties.spotify = spotifyAccount.email;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (!properties.telegram) {
|
|
144
|
+
var telegramAccount = accounts.find(function (a) { return a.type === "telegram"; });
|
|
145
|
+
if (telegramAccount === null || telegramAccount === void 0 ? void 0 : telegramAccount.username) {
|
|
146
|
+
properties.telegram = telegramAccount.username;
|
|
147
|
+
}
|
|
148
|
+
else if (telegramAccount === null || telegramAccount === void 0 ? void 0 : telegramAccount.telegramUserId) {
|
|
149
|
+
properties.telegram = telegramAccount.telegramUserId;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (!properties.tiktok) {
|
|
153
|
+
var tiktokAccount = accounts.find(function (a) { return a.type === "tiktok_oauth"; });
|
|
154
|
+
if (tiktokAccount === null || tiktokAccount === void 0 ? void 0 : tiktokAccount.username) {
|
|
155
|
+
properties.tiktok = tiktokAccount.username;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (!properties.twitter) {
|
|
159
|
+
var twitterAccount = accounts.find(function (a) { return a.type === "twitter_oauth"; });
|
|
160
|
+
if (twitterAccount === null || twitterAccount === void 0 ? void 0 : twitterAccount.username) {
|
|
161
|
+
properties.twitter = twitterAccount.username;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// Use OAuth emails as fallback for email if still blank
|
|
165
|
+
// Priority: email -> google -> apple -> linkedin
|
|
166
|
+
if (!properties.email) {
|
|
167
|
+
if (properties.google) {
|
|
168
|
+
properties.email = properties.google;
|
|
169
|
+
}
|
|
170
|
+
else if (properties.apple) {
|
|
171
|
+
properties.email = properties.apple;
|
|
172
|
+
}
|
|
173
|
+
else if (properties.linkedin) {
|
|
174
|
+
properties.email = properties.linkedin;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// Extract wallet addresses
|
|
178
|
+
var wallets = accounts
|
|
179
|
+
.filter(function (a) { return (a.type === "wallet" || a.type === "smart_wallet") && a.address; })
|
|
180
|
+
.map(function (a) {
|
|
181
|
+
var _a, _b;
|
|
182
|
+
return ({
|
|
183
|
+
address: a.address,
|
|
184
|
+
walletClient: (_a = (a.walletClientType || a.walletClient)) !== null && _a !== void 0 ? _a : undefined,
|
|
185
|
+
chainType: (_b = a.chainType) !== null && _b !== void 0 ? _b : undefined,
|
|
186
|
+
isEmbedded: a.walletClientType === "privy" || a.walletClient === "privy",
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
return { properties: properties, wallets: wallets };
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -99,7 +99,8 @@ var FormoAnalyticsSession = /** @class */ (function () {
|
|
|
99
99
|
var _a;
|
|
100
100
|
var identifiedKey = this.generateIdentificationKey(address, rdns);
|
|
101
101
|
var identifiedWallets = ((_a = (0, storage_1.cookie)().get(exports.SESSION_WALLET_IDENTIFIED_KEY)) === null || _a === void 0 ? void 0 : _a.split(",")) || [];
|
|
102
|
-
|
|
102
|
+
var alreadyExists = identifiedWallets.includes(identifiedKey);
|
|
103
|
+
if (!alreadyExists) {
|
|
103
104
|
identifiedWallets.push(identifiedKey);
|
|
104
105
|
var newValue = identifiedWallets.join(",");
|
|
105
106
|
(0, storage_1.cookie)().set(exports.SESSION_WALLET_IDENTIFIED_KEY, newValue, {
|