Skip to content

Commit

Permalink
feat:add migration popup
Browse files Browse the repository at this point in the history
  • Loading branch information
brancoder committed Nov 4, 2024
1 parent 45bc046 commit 35af4d3
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 2 deletions.
50 changes: 48 additions & 2 deletions apps/wallet-dashboard/app/(protected)/migrations/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,25 @@
'use client';

import { VirtualList } from '@/components';
import { useGetCurrentEpochStartTimestamp } from '@/hooks';
import MigratePopup from '@/components/Popup/Popups/MigratePopup';
import { useGetCurrentEpochStartTimestamp, usePopups } from '@/hooks';
import {
STARDUST_BASIC_OUTPUT_TYPE,
STARDUST_NFT_OUTPUT_TYPE,
} from '@/lib/constants/migration.constants';
import { groupStardustObjectsByMigrationStatus } from '@/lib/utils';
import { Button } from '@iota/apps-ui-kit';
import { useGetAllOwnedObjects } from '@iota/core';
import { useCurrentAccount, useIotaClientContext } from '@iota/dapp-kit';
import { useCurrentAccount, useIotaClient, useIotaClientContext } from '@iota/dapp-kit';
import { getNetwork, IotaObjectData } from '@iota/iota-sdk/client';
import { useQueryClient } from '@tanstack/react-query';

function MigrationDashboardPage(): JSX.Element {
const account = useCurrentAccount();
const address = account?.address || '';
const { openPopup, closePopup } = usePopups();
const queryClient = useQueryClient();
const iotaClient = useIotaClient();
const { network } = useIotaClientContext();
const { explorer } = getNetwork(network);
const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp();
Expand Down Expand Up @@ -46,6 +52,45 @@ function MigrationDashboardPage(): JSX.Element {
</a>
);

function handleOnSuccess(digest: string): void {
iotaClient
.waitForTransaction({
digest,
})
.then(() => {
queryClient.invalidateQueries({
queryKey: [
'get-all-owned-objects',
account?.address,
{
StructType: STARDUST_BASIC_OUTPUT_TYPE,
},
],
});
queryClient.invalidateQueries({
queryKey: [
'get-all-owned-objects',
account?.address,
{
StructType: STARDUST_NFT_OUTPUT_TYPE,
},
],
});
});
}
function openMigratePopup(): void {
const stardustOutputObjects = [...migratableBasicOutputs, ...migratableNftOutputs];
if (stardustOutputObjects.length > 0) {
openPopup(
<MigratePopup
stardustOutputObjects={stardustOutputObjects}
closePopup={closePopup}
onSuccess={handleOnSuccess}
/>,
);
}
}

return (
<div className="flex h-full w-full flex-wrap items-center justify-center space-y-4">
<div className="flex w-1/2 flex-col">
Expand Down Expand Up @@ -80,6 +125,7 @@ function MigrationDashboardPage(): JSX.Element {
render={virtualItem}
/>
</div>
<Button text="Migrate" onClick={openMigratePopup} />
</div>
);
}
Expand Down
82 changes: 82 additions & 0 deletions apps/wallet-dashboard/components/Popup/Popups/MigratePopup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import React from 'react';
import { VirtualList } from '@/components';
import {
useCurrentAccount,
useIotaClientContext,
useSignAndExecuteTransaction,
} from '@iota/dapp-kit';
import { getNetwork, IotaObjectData } from '@iota/iota-sdk/client';
import { useMigrationTransaction } from '@/hooks/useMigrationTransaction';
import { Button } from '@iota/apps-ui-kit';
import { useNotifications } from '@/hooks';
import { NotificationType } from '@/stores/notificationStore';

interface MigratePopupProps {
stardustOutputObjects: IotaObjectData[];
closePopup: () => void;
onSuccess?: (digest: string) => void;
}

function MigratePopup({
stardustOutputObjects,
closePopup,
onSuccess,
}: MigratePopupProps): JSX.Element {
const account = useCurrentAccount();
const { addNotification } = useNotifications();
const { data: migrateData } = useMigrationTransaction(
stardustOutputObjects,
account?.address || '',
);
const { network } = useIotaClientContext();
const { explorer } = getNetwork(network);
const { mutateAsync: signAndExecuteTransaction, isPending } = useSignAndExecuteTransaction();

async function handleMigrate(): Promise<void> {
if (!migrateData) return;
signAndExecuteTransaction(
{
transaction: migrateData.transaction,
},
{
onSuccess: (tx) => {
if (onSuccess) {
onSuccess(tx.digest);
}
},
},
)
.then(() => {
closePopup();
addNotification('Migration transaction has been sent');
})
.catch(() => {
addNotification('Migration transaction was not sent', NotificationType.Error);
});
}

const virtualItem = (asset: IotaObjectData): JSX.Element => (
<a href={`${explorer}/object/${asset.objectId}`} target="_blank" rel="noreferrer">
{asset.objectId}
</a>
);
return (
<div className="flex min-w-[300px] flex-col gap-2">
<div className="flex flex-col">
<h1>Migratable Outputs: {stardustOutputObjects.length}</h1>
<VirtualList
items={stardustOutputObjects}
estimateSize={() => 30}
render={virtualItem}
/>
</div>
<p>Gas Fees: {migrateData?.gasBudget?.toString() || '--'}</p>
<Button text="Migrate" disabled={isPending} onClick={handleMigrate} />
</div>
);
}

export default MigratePopup;
32 changes: 32 additions & 0 deletions apps/wallet-dashboard/hooks/useMigrationTransaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { useIotaClient } from '@iota/dapp-kit';
import { IotaObjectData } from '@iota/iota-sdk/client';
import { Transaction } from '@iota/iota-sdk/transactions';
import { useQuery } from '@tanstack/react-query';

export function useMigrationTransaction(
stardustOutputObjects: IotaObjectData[],
senderAddress: string,
) {
const client = useIotaClient();
return useQuery({
// eslint-disable-next-line @tanstack/query/exhaustive-deps
queryKey: ['migration-transaction', senderAddress],
queryFn: async () => {
const transaction = new Transaction();
transaction.setSender(senderAddress);
await transaction.build({ client });
return transaction;
},
enabled: !!stardustOutputObjects && !!senderAddress,
gcTime: 0,
select: (transaction) => {
return {
transaction,
gasBudget: transaction.getData().gasData.budget,
};
},
});
}

0 comments on commit 35af4d3

Please sign in to comment.