Skip to content

Commit

Permalink
feat(tooling-dashboard): organize migration stardust objects (#3826)
Browse files Browse the repository at this point in the history
* feat: fetch stardust basic and nft objects

* feat: organize stardust objects on migratable and unmigratable

* fix: migration constants and variable nameing

* fix: variable naming

* fix: move constants to core

* fix: evert adding routes to barrel

* fix: remove undefined object check

---------

Co-authored-by: Marc Espin <[email protected]>
  • Loading branch information
brancoder and marc2332 authored Nov 7, 2024
1 parent 7eac703 commit bd07963
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 36 deletions.
1 change: 1 addition & 0 deletions apps/core/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * from './staking.constants';
export * from './recognizedPackages.constants';
export * from './coins.constants';
export * from './timelock.constants';
export * from './migration.constants';
export * from './features.enum';
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

export const STARDUST_PACKAGE_ID =
'000000000000000000000000000000000000000000000000000000000000107a';
export const STARDUST_BASIC_OUTPUT_TYPE = `${STARDUST_PACKAGE_ID}::basic_output::BasicOutput<0x2::iota::IOTA>`;
Expand Down
77 changes: 41 additions & 36 deletions apps/wallet-dashboard/app/(protected)/migrations/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,74 +3,79 @@
'use client';

import { VirtualList } from '@/components';
import { useGetCurrentEpochStartTimestamp } from '@/hooks';
import { groupStardustObjectsByMigrationStatus } from '@/lib/utils';
import {
STARDUST_BASIC_OUTPUT_TYPE,
STARDUST_NFT_OUTPUT_TYPE,
} from '@/lib/constants/migration.constants';
import { useGetOwnedObjects } from '@iota/core';
useGetAllOwnedObjects,
} from '@iota/core';
import { useCurrentAccount, useIotaClientContext } from '@iota/dapp-kit';
import { getNetwork, IotaObjectData } from '@iota/iota-sdk/client';

function MigrationDashboardPage(): JSX.Element {
const account = useCurrentAccount();
const address = account?.address || '';
const { network } = useIotaClientContext();
const { explorer } = getNetwork(network);
const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp();

const {
data: basicOutputObjects,
fetchNextPage: fetchNextPageBasic,
hasNextPage: hasNextPageBasic,
isFetchingNextPage: isFetchingNextPageBasic,
} = useGetOwnedObjects(account?.address || '', {
const { data: basicOutputObjects } = useGetAllOwnedObjects(address, {
StructType: STARDUST_BASIC_OUTPUT_TYPE,
});
const {
data: nftOutputObjects,
fetchNextPage: fetchNextPageNft,
hasNextPage: hasNextPageNft,
isFetchingNextPage: isFetchingNextPageNft,
} = useGetOwnedObjects(account?.address || '', {
const { data: nftOutputObjects } = useGetAllOwnedObjects(address, {
StructType: STARDUST_NFT_OUTPUT_TYPE,
});

const basicOutputs =
basicOutputObjects?.pages
.flatMap((page) => page.data)
.filter((asset) => asset.data && asset.data.objectId)
.map((response) => response.data!) ?? [];

const nftOutputs =
nftOutputObjects?.pages
.flatMap((page) => page.data)
.filter((asset) => asset.data && asset.data.objectId)
.map((response) => response.data!) ?? [];
const { migratable: migratableBasicOutputs, unmigratable: unmigratableBasicOutputs } =
groupStardustObjectsByMigrationStatus(
basicOutputObjects ?? [],
Number(currentEpochMs),
address,
);

const { migratable: migratableNftOutputs, unmigratable: unmigratableNftOutputs } =
groupStardustObjectsByMigrationStatus(
nftOutputObjects ?? [],
Number(currentEpochMs),
address,
);
const virtualItem = (asset: IotaObjectData): JSX.Element => (
<a href={`${explorer}/object/${asset.objectId}`} target="_blank" rel="noreferrer">
{asset.objectId}
</a>
);

return (
<div className="flex h-full w-full flex-row items-center justify-center space-y-4">
<div className="flex h-full w-full flex-wrap items-center justify-center space-y-4">
<div className="flex w-1/2 flex-col">
<h1>Migratable Basic Outputs: {migratableBasicOutputs.length}</h1>
<VirtualList
items={migratableBasicOutputs}
estimateSize={() => 30}
render={virtualItem}
/>
</div>
<div className="flex w-1/2 flex-col">
<h1>Unmigratable Basic Outputs: {unmigratableBasicOutputs.length}</h1>
<VirtualList
items={unmigratableBasicOutputs}
estimateSize={() => 30}
render={virtualItem}
/>
</div>
<div className="flex w-1/2 flex-col">
<h1>Basic Outputs</h1>
<h1>Migratable NFT Outputs: {migratableNftOutputs.length}</h1>
<VirtualList
items={basicOutputs}
hasNextPage={hasNextPageBasic}
isFetchingNextPage={isFetchingNextPageBasic}
fetchNextPage={fetchNextPageBasic}
items={migratableNftOutputs}
estimateSize={() => 30}
render={virtualItem}
/>
</div>
<div className="flex w-1/2 flex-col">
<h1>Nft Outputs</h1>
<h1>Unmigratable NFT Outputs: {unmigratableNftOutputs.length}</h1>
<VirtualList
items={nftOutputs}
hasNextPage={hasNextPageNft}
isFetchingNextPage={isFetchingNextPageNft}
fetchNextPage={fetchNextPageNft}
items={unmigratableNftOutputs}
estimateSize={() => 30}
render={virtualItem}
/>
Expand Down
1 change: 1 addition & 0 deletions apps/wallet-dashboard/lib/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@

export * from './transactions.interface';
export * from './timelock.interface';
export * from './migration.interface';
export * from './vesting.interface';
export * from './appRoute.interface';
47 changes: 47 additions & 0 deletions apps/wallet-dashboard/lib/interfaces/migration.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

type ExpirationUnlockCondition = {
owner: string;
return_address: string;
unix_time: number;
};
type StorageDepositReturnUnlockCondition = {
return_address: string;
return_amount: string;
};
type TimelockUnlockCondition = {
unix_time: number;
};

export type CommonOutputObject = {
id: { id: string };
balance: string;
native_tokens: {
type: string;
fields: { id: { id: string }; size: string };
};
};

export interface CommonOutputObjectWithUc extends CommonOutputObject {
expiration_uc?: {
type: string;
fields: ExpirationUnlockCondition;
};
storage_deposit_return_uc?: {
type: string;
fields: StorageDepositReturnUnlockCondition;
};
timelock_uc?: {
type: string;
fields: TimelockUnlockCondition;
};
}

export interface BasicOutputObject extends CommonOutputObjectWithUc {
metadata?: number[];
tag?: number[];
sender?: string;
}

export interface NftOutputObject extends CommonOutputObjectWithUc {}
1 change: 1 addition & 0 deletions apps/wallet-dashboard/lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export * from './indexGenerator';
export * from './vesting';
export * from './time';
export * from './timelock';
export * from './migration';
export * from './transaction';
export * from './growthbook';
51 changes: 51 additions & 0 deletions apps/wallet-dashboard/lib/utils/migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { IotaObjectData } from '@iota/iota-sdk/client';
import { CommonOutputObjectWithUc } from '../interfaces/migration.interface';

export type StardustMigrationGroupedObjects = {
migratable: IotaObjectData[];
unmigratable: IotaObjectData[];
};

export function groupStardustObjectsByMigrationStatus(
stardustOutputObjects: IotaObjectData[],
epochTimestamp: number,
address: string,
): StardustMigrationGroupedObjects {
const migratable: IotaObjectData[] = [];
const unmigratable: IotaObjectData[] = [];

const epochUnix = epochTimestamp / 1000;

for (const outputObject of stardustOutputObjects) {
const outputObjectFields = (
outputObject.content as unknown as {
fields: CommonOutputObjectWithUc;
}
).fields;

if (outputObjectFields.expiration_uc) {
const unlockableAddress =
outputObjectFields.expiration_uc.fields.unix_time <= epochUnix
? outputObjectFields.expiration_uc.fields.return_address
: outputObjectFields.expiration_uc.fields.owner;
if (unlockableAddress !== address) {
unmigratable.push(outputObject);
continue;
}
}
if (
outputObjectFields.timelock_uc &&
outputObjectFields.timelock_uc.fields.unix_time > epochUnix
) {
unmigratable.push(outputObject);
continue;
}

migratable.push(outputObject);
}

return { migratable, unmigratable };
}

0 comments on commit bd07963

Please sign in to comment.