Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(wallet-dashboard): Add amplitude events #5010

Merged
merged 20 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c5bb370
feat(dashboard): Integrate Amplitude
marc2332 Jan 20, 2025
5745b53
manypkg
marc2332 Jan 20, 2025
ad7f78f
prettier fix dashboard
marc2332 Jan 20, 2025
02efa4e
missing header
marc2332 Jan 20, 2025
f00759a
Merge branch 'develop' into tooling-dashboard/integrate-amplitude
marc2332 Jan 20, 2025
58eed19
feat(wallet-dashboard): Add more amplitude events
marc2332 Jan 24, 2025
56ea0b2
Merge branch 'develop' into tooling-dashboard/integrate-amplitude
marc2332 Jan 24, 2025
4826770
fix: format code
marc2332 Jan 24, 2025
b64b63a
chore: Add `walletDashboardRev`
marc2332 Jan 24, 2025
3612f89
Merge branch 'tooling-dashboard/integrate-amplitude' into tooling-wal…
marc2332 Jan 24, 2025
0c2c749
chore: bring back disabled check
marc2332 Jan 24, 2025
b6c39bd
Merge branch 'tooling-wallet-dashboard/amplitude-events' of https://g…
marc2332 Jan 24, 2025
1aafee9
Merge branches 'tooling-wallet-dashboard/amplitude-events' and 'devel…
cpl121 Jan 30, 2025
1d330a1
fix(dashboard): modify the license header in the prepend file
cpl121 Jan 30, 2025
bcc0b8f
fix(dashboard): remove isTimelock for migration amplitude event
cpl121 Jan 30, 2025
39eca00
fix(dashboard): lint
cpl121 Jan 30, 2025
51f051c
fix(dashboard): remove duplicate file
cpl121 Jan 30, 2025
4260335
Merge branch 'develop' into tooling-wallet-dashboard/amplitude-events
cpl121 Jan 30, 2025
669b338
Merge branches 'tooling-wallet-dashboard/amplitude-events' and 'devel…
cpl121 Jan 30, 2025
965a848
Merge branch 'develop' into tooling-wallet-dashboard/amplitude-events
begonaalvarezd Jan 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/wallet-dashboard/ampli.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"WorkspaceId": "72fb85fc-aed9-46ef-83a2-9345888a1678",
"SourceId": "ca44ad20-3cfd-4618-aa11-4b8befb0b123",
"Branch": "main",
"Version": "1.0.0",
"VersionId": "954386e3-441d-4aa5-b9ad-1f01e0a20e55",
"Version": "3.0.0",
"VersionId": "fd563f8a-ce76-4f47-a8f5-296a8ac394f8",
"Runtime": "browser:typescript-ampli-v2",
"Platform": "Browser",
"Language": "TypeScript",
Expand Down
7 changes: 7 additions & 0 deletions apps/wallet-dashboard/app/(protected)/assets/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Warning } from '@iota/apps-ui-icons';

import { AssetTileLink, Loading } from '@/components';
import { AssetDialog } from '@/components/dialogs/assets';
import { ampli } from '@/lib/utils/analytics';

const ASSET_CATEGORIES: { label: string; value: AssetCategory }[] = [
{
Expand Down Expand Up @@ -63,6 +64,12 @@ export default function AssetsDashboardPage(): React.JSX.Element {

function onAssetClick(asset: IotaObjectData) {
setSelectedAsset(asset);
if (selectedAssetCategory === AssetCategory.Visual) {
ampli.clickedCollectibleCard({
objectId: asset.objectId,
collectibleType: asset.type!,
});
}
}

return (
Expand Down
2 changes: 2 additions & 0 deletions apps/wallet-dashboard/app/(protected)/vesting/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import { useEffect, useState } from 'react';
import { StakedTimelockObject } from '@/components';
import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard';
import toast from 'react-hot-toast';
import { ampli } from '@/lib/utils/analytics';

export default function VestingDashboardPage(): JSX.Element {
const [timelockedObjectsToUnstake, setTimelockedObjectsToUnstake] =
Expand Down Expand Up @@ -180,6 +181,7 @@ export default function VestingDashboardPage(): JSX.Element {
{
onSuccess: (tx) => {
handleOnSuccess(tx.digest);
ampli.timelockCollect();
},
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AssetsDialogView } from './constants';
import { TransactionDetailsView } from '../send-token';
import { DialogLayout } from '../layout';
import toast from 'react-hot-toast';
import { ampli } from '@/lib/utils/analytics';

interface AssetsDialogProps {
onClose: () => void;
Expand Down Expand Up @@ -80,6 +81,9 @@ export function AssetDialog({ onClose, asset, refetchAssets }: AssetsDialogProps
refetchAssets();
toast.success('Transfer transaction successful');
setView(AssetsDialogView.TransactionDetails);
ampli.sentCollectible({
objectId,
});
} catch {
toast.error('Transfer transaction failed');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import toast from 'react-hot-toast';
import { TransactionDialogView } from '../TransactionDialog';
import { MigrationDialogView } from './enums';
import { ConfirmMigrationView } from './views';
import { ampli } from '@/lib/utils/analytics';

interface MigrationDialogProps {
handleClose: () => void;
Expand Down Expand Up @@ -54,6 +55,10 @@ export function MigrationDialog({
onSuccess(tx.digest);
setTxDigest(tx.digest);
setView(MigrationDialogView.TransactionDetails);
ampli.migration({
basicOutputObjects: basicOutputObjects.length,
nftOutputObjects: nftOutputObjects.length,
});
},
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { INITIAL_VALUES } from './constants';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { useTransferTransactionMutation } from '@/hooks';
import toast from 'react-hot-toast';
import { ampli } from '@/lib/utils/analytics';
import { useQueryClient } from '@tanstack/react-query';

interface SendCoinDialogProps {
Expand Down Expand Up @@ -69,6 +70,9 @@ function SendTokenDialogBody({

setStep(FormStep.TransactionDetails);
toast.success('Transfer transaction has been sent');
ampli.sentCoins({
coinType: selectedCoin.coinType,
});
},
onError: () => {
setOpen(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Dialog } from '@iota/apps-ui-kit';
import { DetailsView } from './views';
import { TransactionDialogView } from '../TransactionDialog';
import { StakeDialogView } from './enums/view.enums';
import { ampli } from '@/lib/utils/analytics';

const INITIAL_VALUES = {
amount: '',
Expand Down Expand Up @@ -92,6 +93,10 @@ export function StakeDialog({

function handleValidatorSelect(validator: string): void {
setSelectedValidator?.(validator);

ampli.selectValidator({
validatorAddress: validator,
});
}

function setViewBasedOnStakingType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { useState } from 'react';
import { ExtendedDelegatedStake } from '@iota/core';
import { StakeDialogView } from '../enums/view.enums';
import { ampli } from '@/lib/utils/analytics';

export function useStakeDialog() {
const [stakeDialogView, setStakeDialogView] = useState<StakeDialogView | undefined>();
Expand All @@ -21,6 +22,9 @@ export function useStakeDialog() {
function handleNewStake() {
setSelectedStake(null);
setStakeDialogView(StakeDialogView.SelectValidator);
ampli.clickedStakeIota({
isCurrentlyStaking: true,
});
}

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
// SPDX-License-Identifier: Apache-2.0

import { useFormatCoin, useBalance, CoinFormat, parseAmount, useCoinMetadata } from '@iota/core';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { IOTA_TYPE_ARG, NANOS_PER_IOTA } from '@iota/iota-sdk/utils';
import { useFormikContext } from 'formik';
import { useSignAndExecuteTransaction } from '@iota/dapp-kit';
import { useNewStakeTransaction } from '@/hooks';
import { EnterAmountDialogLayout } from './EnterAmountDialogLayout';
import toast from 'react-hot-toast';
import { ampli } from '@/lib/utils/analytics';

export interface FormValues {
amount: string;
Expand Down Expand Up @@ -75,6 +76,9 @@ export function EnterAmountView({
onSuccess(tx.digest);
toast.success('Stake transaction has been sent');
resetForm();
ampli.stakedIota({
stakedAmount: Number(BigInt(values.amount) / NANOS_PER_IOTA),
});
},
onError: () => {
toast.error('Stake transaction was not sent');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@

import { useMemo } from 'react';
import { useFormatCoin, CoinFormat, useGetAllOwnedObjects, TIMELOCK_IOTA_TYPE } from '@iota/core';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { IOTA_TYPE_ARG, NANOS_PER_IOTA } from '@iota/iota-sdk/utils';
import { useFormikContext } from 'formik';
import { useSignAndExecuteTransaction } from '@iota/dapp-kit';
import { useGetCurrentEpochStartTimestamp, useNewStakeTimelockedTransaction } from '@/hooks';
import {
getAmountFromGroupedTimelockObjects,
useGetCurrentEpochStartTimestamp,
useNewStakeTimelockedTransaction,
} from '@/hooks';
import { prepareObjectsForTimelockedStakingTransaction } from '@/lib/utils';
import { EnterAmountDialogLayout } from './EnterAmountDialogLayout';
import toast from 'react-hot-toast';
import { ampli } from '@/lib/utils/analytics';

interface FormValues {
amount: string;
Expand Down Expand Up @@ -42,20 +47,19 @@ export function EnterTimelockedAmountView({
StructType: TIMELOCK_IOTA_TYPE,
});
const groupedTimelockObjects = useMemo(() => {
if (timelockedObjects && currentEpochMs) {
return prepareObjectsForTimelockedStakingTransaction(
timelockedObjects,
amountWithoutDecimals,
currentEpochMs,
);
} else {
return [];
}
if (!timelockedObjects || !currentEpochMs) return [];
return prepareObjectsForTimelockedStakingTransaction(
timelockedObjects,
amountWithoutDecimals,
currentEpochMs,
);
}, [timelockedObjects, currentEpochMs, amountWithoutDecimals]);

const { data: newStakeData, isLoading: isTransactionLoading } =
useNewStakeTimelockedTransaction(selectedValidator, senderAddress, groupedTimelockObjects);

const stakedAmount = getAmountFromGroupedTimelockObjects(groupedTimelockObjects);

const hasGroupedTimelockObjects = groupedTimelockObjects.length > 0;

const [maxTokenFormatted, maxTokenFormattedSymbol] = useFormatCoin(
Expand Down Expand Up @@ -85,6 +89,10 @@ export function EnterTimelockedAmountView({
onSuccess: (tx) => {
onSuccess?.(tx.digest);
toast.success('Stake transaction has been sent');
ampli.timelockStake({
stakedAmount: Number(stakedAmount / NANOS_PER_IOTA),
validatorAddress: senderAddress,
});
resetForm();
},
onError: () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import { useCurrentAccount, useSignAndExecuteTransaction } from '@iota/dapp-kit';
import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard';
import toast from 'react-hot-toast';
import { ampli } from '@/lib/utils/analytics';

interface UnstakeTimelockedObjectsViewProps {
onClose: () => void;
Expand Down Expand Up @@ -84,6 +85,9 @@ export function UnstakeTimelockedObjectsView({
onSuccess: (tx) => {
toast.success('Unstake transaction has been sent');
onSuccess(tx);
ampli.timelockUnstake({
validatorAddress: groupedTimelockedObjects.validatorAddress,
});
},
},
).catch(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout
import { useNewUnstakeTransaction } from '@/hooks';
import { IotaSignAndExecuteTransactionOutput } from '@iota/wallet-standard';
import toast from 'react-hot-toast';
import { ampli } from '@/lib/utils/analytics';

interface UnstakeDialogProps {
extendedStake: ExtendedDelegatedStake;
Expand Down Expand Up @@ -84,6 +85,10 @@ export function UnstakeView({
onSuccess: (tx) => {
toast.success('Unstake transaction has been sent');
onSuccess(tx);

ampli.unstakedIota({
validatorAddress: extendedStake.validatorAddress,
});
},
},
).catch(() => {
Expand Down
14 changes: 10 additions & 4 deletions apps/wallet-dashboard/hooks/useNewStakeTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,21 @@ export function useNewStakeTransaction(validator: string, amount: bigint, sender
});
}

export function getAmountFromGroupedTimelockObjects(
groupedTimelockObjects: GroupedTimelockObject[],
): bigint {
return groupedTimelockObjects.reduce(
(acc, obj) => acc + (obj.totalLockedAmount - (obj.splitAmount ?? 0n)),
0n,
);
}

export function useNewStakeTimelockedTransaction(
validator: string,
senderAddress: string,
groupedTimelockObjects: GroupedTimelockObject[],
) {
const amount = groupedTimelockObjects.reduce(
(acc, obj) => acc + (obj.totalLockedAmount - (obj.splitAmount ?? 0n)),
0n,
);
const amount = getAmountFromGroupedTimelockObjects(groupedTimelockObjects);
const client = useIotaClient();
return useQuery({
// eslint-disable-next-line @tanstack/query/exhaustive-deps
Expand Down
4 changes: 4 additions & 0 deletions apps/wallet-dashboard/hooks/usePersistedNetwork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { NetworkConfiguration } from '@iota/iota-sdk/client';
import { useLocalStorage } from '@iota/core';
import toast from 'react-hot-toast';
import { useEffect } from 'react';
import { ampli } from '@/lib/utils/analytics';

export function usePersistedNetwork() {
const clientContext = useIotaClientContext();
Expand All @@ -26,6 +27,9 @@ export function usePersistedNetwork() {
clientContext.selectNetwork(network.id);
setPersistedNetwork(network.id);
toast.success(`Switched to ${network.name}`);
ampli.switchedNetwork({
toNetwork: network.name,
});
}

useEffect(() => {
Expand Down
Loading
Loading