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 more amplitude events #5010

Open
wants to merge 6 commits into
base: tooling-dashboard/integrate-amplitude
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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,11 @@ export function MigrationDialog({
onSuccess(tx.digest);
setTxDigest(tx.digest);
setView(MigrationDialogView.TransactionDetails);
ampli.migration({
basicOutputObjects: basicOutputObjects.length,
nftOutputObjects: nftOutputObjects.length,
isTimelocked: isTimelocked,
});
},
},
)
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
@@ -1,21 +1,20 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { useEffect, useState } from 'react';
import {
useFormatCoin,
CoinFormat,
GroupedTimelockObject,
useGetAllOwnedObjects,
TIMELOCK_IOTA_TYPE,
} from '@iota/core';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { useMemo } from 'react';
import { useFormatCoin, CoinFormat, useGetAllOwnedObjects, TIMELOCK_IOTA_TYPE } from '@iota/core';
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 @@ -47,23 +46,19 @@ export function EnterTimelockedAmountView({
const { data: timelockedObjects } = useGetAllOwnedObjects(senderAddress, {
StructType: TIMELOCK_IOTA_TYPE,
});
const [groupedTimelockObjects, setGroupedTimelockObjects] = useState<GroupedTimelockObject[]>(
[],
);
const groupedTimelockObjects = useMemo(() => {
if (!timelockedObjects || !currentEpochMs) return [];
return prepareObjectsForTimelockedStakingTransaction(
timelockedObjects,
amountWithoutDecimals,
currentEpochMs,
);
}, [timelockedObjects, currentEpochMs, amountWithoutDecimals]);

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

useEffect(() => {
if (timelockedObjects && currentEpochMs) {
const groupedTimelockObjects = prepareObjectsForTimelockedStakingTransaction(
timelockedObjects,
amountWithoutDecimals,
currentEpochMs,
);
setGroupedTimelockObjects(groupedTimelockObjects);
}
}, [timelockedObjects, currentEpochMs, amountWithoutDecimals]);
const stakedAmount = getAmountFromGroupedTimelockObjects(groupedTimelockObjects);

const hasGroupedTimelockObjects = groupedTimelockObjects.length > 0;

Expand Down Expand Up @@ -94,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