diff --git a/packages/analytics-client/package.json b/packages/analytics-client/package.json index 7e325bd15..94a1a1f63 100644 --- a/packages/analytics-client/package.json +++ b/packages/analytics-client/package.json @@ -36,7 +36,8 @@ }, "dependencies": { "@metamask/sdk-types": "workspace:^", - "cross-fetch": "^4.0.0" + "cross-fetch": "^4.0.0", + "openapi-fetch": "^0.13.5" }, "devDependencies": { "@lavamoat/allow-scripts": "^2.3.1", diff --git a/packages/analytics-client/src/index.ts b/packages/analytics-client/src/index.ts index 7622d8648..4d35df01c 100644 --- a/packages/analytics-client/src/index.ts +++ b/packages/analytics-client/src/index.ts @@ -1,6 +1,9 @@ export { SendAnalytics } from './Analytics'; export type { AnalyticsProps } from './Analytics'; +export { initAnalyticsClient, trackEvent } from './v2'; +export type { AnalyticsProps as V2AnalyticsProps, BaseAnalyticsProps as V2BaseAnalyticsProps } from './v2'; + // Removed re-exports from communication-layer // export type { // TrackingEvents, diff --git a/packages/analytics-client/src/v2/client.ts b/packages/analytics-client/src/v2/client.ts new file mode 100644 index 000000000..268fb6d3d --- /dev/null +++ b/packages/analytics-client/src/v2/client.ts @@ -0,0 +1,121 @@ +import createClient from 'openapi-fetch'; +import { components, paths } from './schema'; +import { type OriginatorInfo } from '@metamask/sdk-types'; + +type AnalyticsClientOptions = { + // TODO Add options + pushInterval: number; + analyticsUrl: string; +}; + +class AnalyticsClient { + private _options: AnalyticsClientOptions | undefined = undefined; + private _pushInterval: NodeJS.Timeout | undefined = undefined; + private _client: ReturnType | undefined = undefined; + private _events: components['schemas']['Event'][] = []; + + public init(options?: AnalyticsClientOptions) { + if (!options) { + options = { + pushInterval: 1000, + analyticsUrl: 'http://localhost:3000', + }; + } + + if (this.isInitialized) { + // Nothing to do + return; + } + + this._options = options; + + this._client = createClient({ + baseUrl: this._options.analyticsUrl, + }); + + this._pushInterval = setInterval(() => { + this.pushEvents(); + }, this._options.pushInterval); + } + + public get isInitialized() { + return this._options !== undefined && this._pushInterval !== undefined && this._client !== undefined; + } + + private checkInitialized() { + if (!this.isInitialized) { + throw new Error('Analytics client is not initialized'); + } + } + + private useClient(): ReturnType> { + this.checkInitialized(); + return this._client as ReturnType>; + } + + private async pushEvents() { + if (this._events.length === 0) { + return; + } + + const client = this.useClient(); + + + const events = this._events as components['schemas']['Event'][]; + this._events = []; + + const result = await client.POST("/v1/events", { + body: events, + }); + + if (!result.data) { + throw new Error(`Failed to post request_initiated event: ${result.error}`); + } + } + + public trackEvent(event: T) { + this._events.push(event); + } +} + +const GlobalAnalyticsClient = new AnalyticsClient(); + +export type BaseAnalyticsProps = { + id: string; + originatorInfo?: OriginatorInfo; // Now uses local type + sdkVersion?: string; + // TODO What is this? + anonId: string; +}; + +export type AnalyticsProps = BaseAnalyticsProps & AnalyticsClientOptions; + +let globalAnalyticsProps: BaseAnalyticsProps | undefined = undefined; + +export function initAnalyticsClient(options?: AnalyticsProps) { + globalAnalyticsProps = options; + GlobalAnalyticsClient.init(options); +} + +export function trackEvent(event: T | Partial) { + if (!globalAnalyticsProps) { + throw new Error('Analytics client is not initialized'); + } + + const baseEventProps = { + sdk_version: globalAnalyticsProps.sdkVersion, + dapp_id: globalAnalyticsProps.originatorInfo?.dappId, + anon_id: globalAnalyticsProps.anonId, + platform: globalAnalyticsProps.originatorInfo?.platform, + integration_type: globalAnalyticsProps.originatorInfo?.source, + } + + const mergedEvent = { + ...baseEventProps, + ...event, + } as T; + + GlobalAnalyticsClient.trackEvent(mergedEvent); +} + +export default GlobalAnalyticsClient; \ No newline at end of file diff --git a/packages/analytics-client/src/v2/index.ts b/packages/analytics-client/src/v2/index.ts new file mode 100644 index 000000000..08a841ede --- /dev/null +++ b/packages/analytics-client/src/v2/index.ts @@ -0,0 +1,6 @@ +import GlobalAnalyticsClient from './client'; + +export { initAnalyticsClient, trackEvent } from './client'; +export type { AnalyticsProps, BaseAnalyticsProps } from './client'; + +export default GlobalAnalyticsClient; diff --git a/packages/analytics-client/src/v2/schema.ts b/packages/analytics-client/src/v2/schema.ts new file mode 100644 index 000000000..554e1ea89 --- /dev/null +++ b/packages/analytics-client/src/v2/schema.ts @@ -0,0 +1,417 @@ +/** + * This file was auto-generated by openapi-typescript. + * Do not make direct changes to the file. + */ + +export interface paths { + "/v1/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** + * Track events + * @description Endpoint to submit analytics events for the MetaMask SDK (version 1). + */ + post: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["Event"][]; + }; + }; + responses: { + /** @description Events tracked successfully */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": { + /** + * @description Indicates the success of the event tracking. + * @example success + */ + status?: string; + }; + }; + }; + }; + }; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; +} +export type webhooks = Record; +export interface components { + schemas: { + /** @description A union of all possible event types, differentiated by the 'name' property. */ + Event: components["schemas"]["SdkInitializedEvent"] | components["schemas"]["SdkUsedChainEvent"] | components["schemas"]["SdkConnectionInitiatedEvent"] | components["schemas"]["SdkConnectionEstablishedEvent"] | components["schemas"]["SdkConnectionRejectedEvent"] | components["schemas"]["SdkConnectionFailedEvent"] | components["schemas"]["WalletConnectionRequestReceivedEvent"] | components["schemas"]["WalletConnectionUserApprovedEvent"] | components["schemas"]["WalletConnectionUserRejectedEvent"] | components["schemas"]["SdkActionRequestedEvent"] | components["schemas"]["SdkActionSucceededEvent"] | components["schemas"]["SdkActionFailedEvent"] | components["schemas"]["SdkActionRejectedEvent"] | components["schemas"]["WalletActionReceivedEvent"] | components["schemas"]["WalletActionUserApprovedEvent"] | components["schemas"]["WalletActionUserRejectedEvent"]; + SdkInitializedEvent: { + /** + * @description Identifies the event as SDK initialization. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_initialized"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Platform on which the SDK is running. + * @enum {string} + */ + platform: "desktop-web" | "mobile-web" | "mobile-app"; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + SdkUsedChainEvent: { + /** + * @description Identifies the event as SDK chain usage. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_used_chain"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** @description CAIP-2 chain ID used by the SDK. */ + caip_chain_id: string; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + SdkConnectionInitiatedEvent: { + /** + * @description Identifies the event as connection initiation. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_connection_initiated"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Type of transport used for the connection. + * @enum {string} + */ + transport_type: "direct" | "websocket" | "deeplink"; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + SdkConnectionEstablishedEvent: { + /** + * @description Identifies the event as connection established. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_connection_established"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Type of transport used for the connection. + * @enum {string} + */ + transport_type: "direct" | "websocket" | "deeplink"; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + SdkConnectionRejectedEvent: { + /** + * @description Identifies the event as connection rejected. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_connection_rejected"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Type of transport used for the connection. + * @enum {string} + */ + transport_type: "direct" | "websocket" | "deeplink"; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + SdkConnectionFailedEvent: { + /** + * @description Identifies the event as connection failed. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_connection_failed"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Type of transport used for the connection. + * @enum {string} + */ + transport_type: "direct" | "websocket" | "deeplink"; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + WalletConnectionRequestReceivedEvent: { + /** + * @description Identifies the event as connection request received. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "wallet_connection_request_received"; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Platform receiving the connection request. + * @enum {string} + */ + platform: "extension" | "mobile"; + }; + WalletConnectionUserApprovedEvent: { + /** + * @description Identifies the event as user-approved connection. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "wallet_connection_user_approved"; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Platform where the approval occurred. + * @enum {string} + */ + platform: "extension" | "mobile"; + }; + WalletConnectionUserRejectedEvent: { + /** + * @description Identifies the event as user-rejected connection. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "wallet_connection_user_rejected"; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Platform where the rejection occurred. + * @enum {string} + */ + platform: "extension" | "mobile"; + }; + SdkActionRequestedEvent: { + /** + * @description Identifies the event as a wallet action request. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_action_requested"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** @description The specific wallet action requested. */ + action: string; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + SdkActionSucceededEvent: { + /** + * @description Identifies the event as a successful wallet action. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_action_succeeded"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** @description The specific wallet action that succeeded. */ + action: string; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + SdkActionFailedEvent: { + /** + * @description Identifies the event as a failed wallet action. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_action_failed"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** @description The specific wallet action that failed. */ + action: string; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + SdkActionRejectedEvent: { + /** + * @description Identifies the event as a rejected wallet action. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "sdk_action_rejected"; + /** @description Version of the SDK. */ + sdk_version: string; + /** + * Format: uuid + * @description Unique identifier for the dApp. + */ + dapp_id: string; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** @description The specific wallet action that was rejected. */ + action: string; + /** @description Type of integration used by the SDK. */ + integration_type: string; + }; + WalletActionReceivedEvent: { + /** + * @description Identifies the event as a received wallet action. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "wallet_action_received"; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Platform receiving the wallet action. + * @enum {string} + */ + platform: "extension" | "mobile"; + }; + WalletActionUserApprovedEvent: { + /** + * @description Identifies the event as an approved wallet action. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "wallet_action_user_approved"; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Platform where the approval occurred. + * @enum {string} + */ + platform: "extension" | "mobile"; + }; + WalletActionUserRejectedEvent: { + /** + * @description Identifies the event as a rejected wallet action. (enum property replaced by openapi-typescript) + * @enum {string} + */ + name: "wallet_action_user_rejected"; + /** + * Format: uuid + * @description Anonymous identifier for the user or session. + */ + anon_id: string; + /** + * @description Platform where the rejection occurred. + * @enum {string} + */ + platform: "extension" | "mobile"; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} +export type $defs = Record; +export type operations = Record; \ No newline at end of file diff --git a/packages/sdk-communication-layer/src/services/RemoteCommunication/ConnectionManager/rejectChannel.ts b/packages/sdk-communication-layer/src/services/RemoteCommunication/ConnectionManager/rejectChannel.ts index 260942c35..e1514b24a 100644 --- a/packages/sdk-communication-layer/src/services/RemoteCommunication/ConnectionManager/rejectChannel.ts +++ b/packages/sdk-communication-layer/src/services/RemoteCommunication/ConnectionManager/rejectChannel.ts @@ -1,6 +1,6 @@ // packages/sdk-communication-layer/src/services/RemoteCommunication/ConnectionManager/connectToChannel.ts import { validate } from 'uuid'; -import { SendAnalytics } from '@metamask/analytics-client'; +import { SendAnalytics, trackEvent } from '@metamask/analytics-client'; import { TrackingEvents } from '@metamask/sdk-types'; import { RemoteCommunicationState } from '../../../RemoteCommunication'; import { EventType } from '../../../types/EventType'; @@ -47,6 +47,11 @@ export async function rejectChannel({ } // Send analytics event + trackEvent({ + name: 'sdk_connection_rejected', + transport_type: 'websocket', + }); + SendAnalytics( { id: channelId, diff --git a/packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleClientsConnectedEvent.ts b/packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleClientsConnectedEvent.ts index 7dd5b9148..18d574a3f 100644 --- a/packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleClientsConnectedEvent.ts +++ b/packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleClientsConnectedEvent.ts @@ -1,4 +1,4 @@ -import { SendAnalytics } from '@metamask/analytics-client'; +import { SendAnalytics, trackEvent } from '@metamask/analytics-client'; import { TrackingEvents } from '@metamask/sdk-types'; import packageJson from '../../../../package.json'; import { RemoteCommunication } from '../../../RemoteCommunication'; @@ -28,6 +28,19 @@ export function handleClientsConnectedEvent(instance: RemoteCommunication) { ); if (state.analytics && state.channelId) { + + if (!state.isOriginator) { + trackEvent({ + name: 'sdk_connection_established', + transport_type: 'websocket', + }) + } else { + trackEvent({ + name: 'wallet_connection_request_received', + platform: 'mobile', + }) + } + SendAnalytics( { id: state.channelId, diff --git a/packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleKeysExchangedEvent.ts b/packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleKeysExchangedEvent.ts index 6d1daf9e3..20d9a09d9 100644 --- a/packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleKeysExchangedEvent.ts +++ b/packages/sdk-communication-layer/src/services/RemoteCommunication/EventListeners/handleKeysExchangedEvent.ts @@ -1,4 +1,4 @@ -import { SendAnalytics } from '@metamask/analytics-client'; +import { SendAnalytics, trackEvent } from '@metamask/analytics-client'; import { type OriginatorInfo, TrackingEvents } from '@metamask/sdk-types'; import packageJson from '../../../../package.json'; import { DEFAULT_SESSION_TIMEOUT_MS } from '../../../config'; @@ -63,6 +63,18 @@ export function handleKeysExchangedEvent(instance: RemoteCommunication) { setLastActiveDate(instance, new Date()); if (state.analytics && state.channelId) { + if (state.isOriginator) { + trackEvent({ + name: 'wallet_connection_user_approved', + platform: 'mobile', + }) + } else { + trackEvent({ + name: 'sdk_connection_established', + transport_type: 'websocket', + }) + } + SendAnalytics( { id: state.channelId, diff --git a/packages/sdk-communication-layer/src/services/SocketService/ConnectionManager/handleJoinChannelResult.ts b/packages/sdk-communication-layer/src/services/SocketService/ConnectionManager/handleJoinChannelResult.ts index a907b80ac..9793fa4fb 100644 --- a/packages/sdk-communication-layer/src/services/SocketService/ConnectionManager/handleJoinChannelResult.ts +++ b/packages/sdk-communication-layer/src/services/SocketService/ConnectionManager/handleJoinChannelResult.ts @@ -1,4 +1,4 @@ -import { SendAnalytics } from '@metamask/analytics-client'; +import { SendAnalytics, trackEvent } from '@metamask/analytics-client'; import { TrackingEvents } from '@metamask/sdk-types'; import { SocketService } from '../../../SocketService'; import { EventType } from '../../../types/EventType'; @@ -102,6 +102,18 @@ export const handleJoinChannelResults = async ( remote.state.authorized = true; remote.emit(EventType.AUTHORIZED); + if (isOriginator) { + trackEvent({ + name: 'wallet_connection_user_approved', + platform: 'mobile', + }) + } else { + trackEvent({ + name: 'sdk_connection_established', + transport_type: 'websocket', + }) + } + SendAnalytics( { id: channelId ?? '', diff --git a/packages/sdk-communication-layer/src/services/SocketService/EventListeners/handleChannelRejected.ts b/packages/sdk-communication-layer/src/services/SocketService/EventListeners/handleChannelRejected.ts index 097b3106a..88604ac0e 100644 --- a/packages/sdk-communication-layer/src/services/SocketService/EventListeners/handleChannelRejected.ts +++ b/packages/sdk-communication-layer/src/services/SocketService/EventListeners/handleChannelRejected.ts @@ -1,4 +1,4 @@ -import { SendAnalytics } from '@metamask/analytics-client'; +import { SendAnalytics, trackEvent } from '@metamask/analytics-client'; import { TrackingEvents } from '@metamask/sdk-types'; import { SocketService } from '../../../SocketService'; import { ConnectionStatus } from '../../../types/ConnectionStatus'; @@ -32,6 +32,11 @@ export function handleChannelRejected( instance.remote.state.originatorInfo, ); + trackEvent({ + name: 'wallet_connection_user_rejected', + platform: 'mobile', + }) + // Emit analytics event SendAnalytics( { diff --git a/packages/sdk-communication-layer/src/services/SocketService/EventListeners/handleMessage.ts b/packages/sdk-communication-layer/src/services/SocketService/EventListeners/handleMessage.ts index ee7d26859..d1cf1d0f8 100644 --- a/packages/sdk-communication-layer/src/services/SocketService/EventListeners/handleMessage.ts +++ b/packages/sdk-communication-layer/src/services/SocketService/EventListeners/handleMessage.ts @@ -1,4 +1,4 @@ -import { SendAnalytics } from '@metamask/analytics-client'; +import { SendAnalytics, trackEvent } from '@metamask/analytics-client'; import { TrackingEvents } from '@metamask/sdk-types'; import packageJson from '../../../../package.json'; import { SocketService } from '../../../SocketService'; @@ -212,6 +212,11 @@ export function handleMessage(instance: SocketService, channelId: string) { instance.remote.state.analytics && lcLogguedRPCs.includes(initialRPCMethod.method.toLowerCase()) ) { + trackEvent({ + name: 'sdk_action_succeeded', + action: initialRPCMethod.method, + }) + SendAnalytics( { id: instance.remote.state.channelId ?? '', diff --git a/packages/sdk-communication-layer/src/services/SocketService/MessageHandlers/handleSendMessage.ts b/packages/sdk-communication-layer/src/services/SocketService/MessageHandlers/handleSendMessage.ts index dbcd4873f..216e8ec97 100644 --- a/packages/sdk-communication-layer/src/services/SocketService/MessageHandlers/handleSendMessage.ts +++ b/packages/sdk-communication-layer/src/services/SocketService/MessageHandlers/handleSendMessage.ts @@ -1,5 +1,5 @@ import { TrackingEvents } from '@metamask/sdk-types'; -import { SendAnalytics } from '@metamask/analytics-client'; +import { SendAnalytics, trackEvent } from '@metamask/analytics-client'; import { SocketService } from '../../../SocketService'; import { CommunicationLayerMessage } from '../../../types/CommunicationLayerMessage'; import { logger } from '../../../utils/logger'; @@ -74,6 +74,10 @@ export async function handleSendMessage( message.method && lcLogguedRPCs.includes(message.method.toLowerCase()) ) { + trackEvent({ + name: 'sdk_action_requested', + action: message.method, + }) SendAnalytics( { id: instance.remote.state.channelId ?? '', diff --git a/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupAnalytics.ts b/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupAnalytics.ts index 4634b270d..705cebbc3 100644 --- a/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupAnalytics.ts +++ b/packages/sdk/src/services/MetaMaskSDK/InitializerManager/setupAnalytics.ts @@ -2,6 +2,7 @@ import { DEFAULT_SERVER_URL } from '@metamask/sdk-communication-layer'; import { type OriginatorInfo } from '@metamask/sdk-types'; import { Analytics } from '../../Analytics'; import { MetaMaskSDK } from '../../../sdk'; +import { initAnalyticsClient } from '@metamask/analytics-client'; /** * Sets up the analytics instance for the MetaMask SDK. @@ -34,4 +35,14 @@ export async function setupAnalytics(instance: MetaMaskSDK) { enabled: options.enableAnalytics, originatorInfo: originator, }); + + initAnalyticsClient({ + originatorInfo: originator, + sdkVersion: instance.getVersion(), + // TODO Set ID and anonId + id: 'TODO: SET ID', + anonId: 'TODO: SET ANON ID', + pushInterval: 1000, + analyticsUrl: options.communicationServerUrl ?? DEFAULT_SERVER_URL, + }); } diff --git a/yarn.lock b/yarn.lock index b70ca926b..24d6df735 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10700,6 +10700,7 @@ __metadata: eslint: ^7.30.0 eslint-config-prettier: ^8.3.0 eslint-plugin-prettier: ^3.4.0 + openapi-fetch: ^0.13.5 prettier: ^2.8.8 rimraf: ^6.0.1 ts-node: ^10.9.1 @@ -42675,6 +42676,22 @@ __metadata: languageName: node linkType: hard +"openapi-fetch@npm:^0.13.5": + version: 0.13.5 + resolution: "openapi-fetch@npm:0.13.5" + dependencies: + openapi-typescript-helpers: ^0.0.15 + checksum: 7f6947d074d3a66fbc1641e46b20652cc92412e6b3238259a29ad72ef6eca5b4ac7529826ff97660fc6ebc8c38f2f151ad66e9e93f16b0736bec5c150f73b06f + languageName: node + linkType: hard + +"openapi-typescript-helpers@npm:^0.0.15": + version: 0.0.15 + resolution: "openapi-typescript-helpers@npm:0.0.15" + checksum: feec0f25d708aaacc086dafd3e21001329b47984f30e24877b34d053fbccd52f3b3a19b1715fda2ed5afaca7056872576eed7de8f64855d2472507dc6df626ca + languageName: node + linkType: hard + "opener@npm:1": version: 1.5.2 resolution: "opener@npm:1.5.2"