@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
317 lines (282 loc) • 13.1 kB
text/typescript
import type { AppManifest, BroadcastTrackingData, DAppTrackingData } from "./types";
/**
* This signature is to be compatible with track method of `segment.js` file in LLM and LLD
* `track(event: string, properties: ?Object, mandatory: ?boolean)` in jsflow
* {@link @ledger-desktop/renderer/analytics/segment#track}
*/
type TrackWalletAPI = (
event: string,
properties: Record<string, any> | null,
mandatory: boolean | null,
) => void;
/**
* Obtain Event data from WalletAPI App manifest
*
* @param {AppManifest} manifest
* @returns Object - event data
*/
function getEventData(manifest: AppManifest) {
return { walletAPI: manifest.name };
}
/**
* Wrap call to underlying trackCall function.
* @param trackCall
* @returns a dictionary of event to trigger.
*/
// Disabling explicit module boundary types as we're using const
// in order to get the exact type matching the tracking wrapper API
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export default function trackingWrapper(trackCall: TrackWalletAPI) {
const track = (event: string, properties: Record<string, any> | null) =>
trackCall(event, properties, null);
return {
// Failed to load the iframe
load: (manifest: AppManifest) => {
track("WalletAPI Load", getEventData(manifest));
},
// Failed to load the iframe
reload: (manifest: AppManifest) => {
track("WalletAPI Reload", getEventData(manifest));
},
// Failed to load the iframe
loadFail: (manifest: AppManifest) => {
// TODO: handle iframe failed
track("WalletAPI Load Fail", getEventData(manifest));
},
// Successfully loaded the iframe
loadSuccess: (manifest: AppManifest) => {
track("WalletAPI Load Success", getEventData(manifest));
},
// Sign transaction modal open
signTransactionRequested: (
manifest: AppManifest,
isEmbeddedSwap?: boolean,
partner?: string,
) => {
const properties = {
...getEventData(manifest),
...(isEmbeddedSwap !== undefined && { isEmbeddedSwap: String(isEmbeddedSwap) }),
...(partner !== undefined && { partner }),
};
track("WalletAPI SignTransaction", properties);
},
// Failed to sign transaction (cancel or error)
signTransactionFail: (manifest: AppManifest, isEmbeddedSwap?: boolean, partner?: string) => {
const properties = {
...getEventData(manifest),
...(isEmbeddedSwap !== undefined && { isEmbeddedSwap: String(isEmbeddedSwap) }),
...(partner !== undefined && { partner }),
};
track("WalletAPI SignTransaction Fail", properties);
},
// Successfully signed transaction
signTransactionSuccess: (manifest: AppManifest, isEmbeddedSwap?: boolean, partner?: string) => {
const properties = {
...getEventData(manifest),
...(isEmbeddedSwap !== undefined && { isEmbeddedSwap: String(isEmbeddedSwap) }),
...(partner !== undefined && { partner }),
};
track("WalletAPI SignTransaction Success", properties);
},
// Sign Raw transaction modal open
signRawTransactionRequested: (manifest: AppManifest) => {
track("WalletAPI SignRawTransaction", getEventData(manifest));
},
// Failed to sign raw transaction (cancel or error)
signRawTransactionFail: (manifest: AppManifest) => {
track("WalletAPI SignRawTransaction Fail", getEventData(manifest));
},
// Successfully signed raw transaction
signRawTransactionSuccess: (manifest: AppManifest) => {
track("WalletAPI SignRawTransaction Success", getEventData(manifest));
},
// Select account modal open
requestAccountRequested: (manifest: AppManifest) => {
track("WalletAPI RequestAccount", getEventData(manifest));
},
// Failed to select account (cancel or error)
requestAccountFail: (manifest: AppManifest) => {
track("WalletAPI RequestAccount Fail", getEventData(manifest));
},
// The user successfully selected an account
requestAccountSuccess: (manifest: AppManifest) => {
track("WalletAPI RequestAccount Success", getEventData(manifest));
},
// Select account modal open
receiveRequested: (manifest: AppManifest) => {
track("WalletAPI Receive", getEventData(manifest));
},
// Failed to select account (cancel or error)
receiveFail: (manifest: AppManifest) => {
track("WalletAPI Receive Fail", getEventData(manifest));
},
// The user successfully selected an account
receiveSuccess: (manifest: AppManifest) => {
track("WalletAPI Receive Success", getEventData(manifest));
},
// Failed to broadcast a signed transaction
broadcastFail: (manifest: AppManifest, data?: BroadcastTrackingData) => {
const properties: Record<string, unknown> = getEventData(manifest);
if (data?.isEmbeddedSwap !== undefined)
properties.isEmbeddedSwap = String(data.isEmbeddedSwap);
if (data?.partner !== undefined) properties.partner = data.partner;
if (data?.sourceCurrency !== undefined) properties.sourceCurrency = data.sourceCurrency;
if (data?.targetCurrency !== undefined) properties.targetCurrency = data.targetCurrency;
if (data?.network !== undefined) properties.network = data.network;
track("WalletAPI Broadcast Fail", properties);
},
// Successfully broadcast a signed transaction
broadcastSuccess: (manifest: AppManifest, data?: BroadcastTrackingData) => {
const properties: Record<string, unknown> = getEventData(manifest);
if (data?.isEmbeddedSwap !== undefined)
properties.isEmbeddedSwap = String(data.isEmbeddedSwap);
if (data?.partner !== undefined) properties.partner = data.partner;
if (data?.sourceCurrency !== undefined) properties.sourceCurrency = data.sourceCurrency;
if (data?.targetCurrency !== undefined) properties.targetCurrency = data.targetCurrency;
if (data?.network !== undefined) properties.network = data.network;
track("WalletAPI Broadcast Success", properties);
},
// Successfully broadcast a signed transaction
broadcastOperationDetailsClick: (manifest: AppManifest) => {
track("WalletAPI Broadcast OpD Clicked", getEventData(manifest));
},
// Generate Exchange nonce modal open
startExchangeRequested: (manifest: AppManifest) => {
track("WalletAPI start Exchange Nonce request", getEventData(manifest));
},
// Successfully generated an Exchange app nonce
startExchangeSuccess: (manifest: AppManifest) => {
track("WalletAPI start Exchange Nonce success", getEventData(manifest));
},
// Failed to generate an Exchange app nonce
startExchangeFail: (manifest: AppManifest) => {
track("WalletAPI start Exchange Nonce fail", getEventData(manifest));
},
completeExchangeRequested: (manifest: AppManifest) => {
track("WalletAPI complete Exchange requested", getEventData(manifest));
},
// Successfully completed an Exchange
completeExchangeSuccess: (manifest: AppManifest) => {
track("WalletAPI complete Exchange success", getEventData(manifest));
},
// Failed to complete an Exchange
completeExchangeFail: (manifest: AppManifest) => {
track("WalletAPI complete Exchange Nonce fail", getEventData(manifest));
},
signMessageRequested: (manifest: AppManifest) => {
track("WalletAPI sign message requested", getEventData(manifest));
},
signMessageSuccess: (manifest: AppManifest) => {
track("WalletAPI sign message success", getEventData(manifest));
},
signMessageFail: (manifest: AppManifest) => {
track("WalletAPI sign message fail", getEventData(manifest));
},
signMessageUserRefused: (manifest: AppManifest) => {
track("WalletAPI sign message user refused", getEventData(manifest));
},
deviceTransportRequested: (manifest: AppManifest) => {
track("WalletAPI device transport requested", getEventData(manifest));
},
deviceTransportSuccess: (manifest: AppManifest) => {
track("WalletAPI device transport success", getEventData(manifest));
},
deviceTransportFail: (manifest: AppManifest) => {
track("WalletAPI device transport fail", getEventData(manifest));
},
deviceSelectRequested: (manifest: AppManifest) => {
track("WalletAPI device select requested", getEventData(manifest));
},
deviceSelectSuccess: (manifest: AppManifest) => {
track("WalletAPI device select success", getEventData(manifest));
},
deviceSelectFail: (manifest: AppManifest) => {
track("WalletAPI device select fail", getEventData(manifest));
},
deviceOpenRequested: (manifest: AppManifest) => {
track("WalletAPI device open requested", getEventData(manifest));
},
deviceExchangeRequested: (manifest: AppManifest) => {
track("WalletAPI device exchange requested", getEventData(manifest));
},
deviceExchangeSuccess: (manifest: AppManifest) => {
track("WalletAPI device exchange success", getEventData(manifest));
},
deviceExchangeFail: (manifest: AppManifest) => {
track("WalletAPI device exchange fail", getEventData(manifest));
},
deviceCloseRequested: (manifest: AppManifest) => {
track("WalletAPI device close requested", getEventData(manifest));
},
deviceCloseSuccess: (manifest: AppManifest) => {
track("WalletAPI device close success", getEventData(manifest));
},
deviceCloseFail: (manifest: AppManifest) => {
track("WalletAPI device close fail", getEventData(manifest));
},
bitcoinFamilyAccountAddressRequested: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account address requested", getEventData(manifest));
},
bitcoinFamilyAccountAddressFail: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account address fail", getEventData(manifest));
},
bitcoinFamilyAccountAddressSuccess: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account address success", getEventData(manifest));
},
bitcoinFamilyAccountPublicKeyRequested: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account publicKey requested", getEventData(manifest));
},
bitcoinFamilyAccountPublicKeyFail: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account publicKey fail", getEventData(manifest));
},
bitcoinFamilyAccountPublicKeySuccess: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account publicKey success", getEventData(manifest));
},
bitcoinFamilyAccountXpubRequested: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account xpub requested", getEventData(manifest));
},
bitcoinFamilyAccountXpubFail: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account xpub fail", getEventData(manifest));
},
bitcoinFamilyAccountXpubSuccess: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account xpub success", getEventData(manifest));
},
bitcoinFamilyAccountAddressesRequested: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account addresses requested", getEventData(manifest));
},
bitcoinFamilyAccountAddressesFail: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account addresses fail", getEventData(manifest));
},
bitcoinFamilyAccountAddressesSuccess: (manifest: AppManifest) => {
track("WalletAPI bitcoin family account addresses success", getEventData(manifest));
},
dappSendTransactionRequested: (manifest: AppManifest, trackingData: DAppTrackingData) => {
track("dApp SendTransaction requested", { ...getEventData(manifest), ...trackingData });
},
dappSendTransactionSuccess: (manifest: AppManifest, trackingData: DAppTrackingData) => {
track("dApp SendTransaction success", { ...getEventData(manifest), ...trackingData });
},
dappSendTransactionFail: (manifest: AppManifest, trackingData?: DAppTrackingData) => {
track("dApp SendTransaction fail", { ...getEventData(manifest), ...(trackingData || {}) });
},
dappPersonalSignRequested: (manifest: AppManifest) => {
track("dApp PersonalSign requested", getEventData(manifest));
},
dappPersonalSignSuccess: (manifest: AppManifest) => {
track("dApp PersonalSign success", getEventData(manifest));
},
dappPersonalSignFail: (manifest: AppManifest) => {
track("dApp PersonalSign fail", getEventData(manifest));
},
dappSignTypedDataRequested: (manifest: AppManifest) => {
track("dApp SignTypedData requested", getEventData(manifest));
},
dappSignTypedDataSuccess: (manifest: AppManifest) => {
track("dApp SignTypedData success", getEventData(manifest));
},
dappSignTypedDataFail: (manifest: AppManifest) => {
track("dApp SignTypedData fail", getEventData(manifest));
},
} as const;
}
export type TrackingAPI = ReturnType<typeof trackingWrapper>;