Skip to content

Commit

Permalink
Merge branch 'dev' into feat/add-delegation-search
Browse files Browse the repository at this point in the history
  • Loading branch information
brancoder committed Feb 26, 2024
2 parents 81a7c24 + 0f650ad commit c44dbd7
Show file tree
Hide file tree
Showing 24 changed files with 483 additions and 125 deletions.
11 changes: 11 additions & 0 deletions api/src/models/api/nova/ISlotRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface ISlotRequest {
/**
* The network to search on.
*/
network: string;

/**
* The slot index to get the details for.
*/
slotIndex: string;
}
10 changes: 10 additions & 0 deletions api/src/models/api/nova/ISlotResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// eslint-disable-next-line import/no-unresolved
import { SlotCommitment } from "@iota/sdk-nova";
import { IResponse } from "./IResponse";

export interface ISlotResponse extends IResponse {
/**
* The deserialized slot.
*/
slot?: SlotCommitment;
}
1 change: 1 addition & 0 deletions api/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,5 @@ export const routes: IRoute[] = [
},
{ path: "/nova/block/:network/:blockId", method: "get", folder: "nova/block", func: "get" },
{ path: "/nova/block/metadata/:network/:blockId", method: "get", folder: "nova/block/metadata", func: "get" },
{ path: "/nova/slot/:network/:slotIndex", method: "get", folder: "nova/slot", func: "get" },
];
30 changes: 30 additions & 0 deletions api/src/routes/nova/slot/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ServiceFactory } from "../../../factories/serviceFactory";
import { ISlotRequest } from "../../../models/api/nova/ISlotRequest";
import { ISlotResponse } from "../../../models/api/nova/ISlotResponse";
import { IConfiguration } from "../../../models/configuration/IConfiguration";
import { NOVA } from "../../../models/db/protocolVersion";
import { NetworkService } from "../../../services/networkService";
import { NovaApiService } from "../../../services/nova/novaApiService";
import { ValidationHelper } from "../../../utils/validationHelper";

/**
* Fetch the block from the network.
* @param _ The configuration.
* @param request The request.
* @returns The response.
*/
export async function get(_: IConfiguration, request: ISlotRequest): Promise<ISlotResponse> {
const networkService = ServiceFactory.get<NetworkService>("network");
const networks = networkService.networkNames();
ValidationHelper.oneOf(request.network, networks, "network");
ValidationHelper.numberFromString(request.slotIndex, "slotIndex");

const networkConfig = networkService.get(request.network);

if (networkConfig.protocolVersion !== NOVA) {
return {};
}

const novaApiService = ServiceFactory.get<NovaApiService>(`api-service-${networkConfig.network}`);
return novaApiService.getSlotCommitment(Number(request.slotIndex));
}
16 changes: 16 additions & 0 deletions api/src/services/nova/novaApiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { INftDetailsResponse } from "../../models/api/nova/INftDetailsResponse";
import { IOutputDetailsResponse } from "../../models/api/nova/IOutputDetailsResponse";
import { IRewardsResponse } from "../../models/api/nova/IRewardsResponse";
import { ISearchResponse } from "../../models/api/nova/ISearchResponse";
import { ISlotResponse } from "../../models/api/nova/ISlotResponse";
import { ITransactionDetailsResponse } from "../../models/api/nova/ITransactionDetailsResponse";
import { INetwork } from "../../models/db/INetwork";
import { HexHelper } from "../../utils/hexHelper";
Expand Down Expand Up @@ -325,6 +326,21 @@ export class NovaApiService {
return manaRewardsResponse ? { outputId, manaRewards: manaRewardsResponse } : { outputId, message: "Rewards data not found" };
}

/**
* Get the slot commitment.
* @param slotIndex The slot index to get the commitment for.
* @returns The slot commitment.
*/
public async getSlotCommitment(slotIndex: number): Promise<ISlotResponse> {
try {
const slot = await this.client.getCommitmentByIndex(slotIndex);

return { slot };
} catch (e) {
logger.error(`Failed fetching slot with slot index ${slotIndex}. Cause: ${e}`);
}
}

/**
* Find item on the stardust network.
* @param query The query to use for finding items.
Expand Down
30 changes: 30 additions & 0 deletions client/src/app/components/nova/PageDataRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from "react";
import classNames from "classnames";
import TruncatedId from "../stardust/TruncatedId";

export interface IPageDataRow {
label: string;
value?: string | number;
highlight?: boolean;
truncatedId?: {
id: string;
link?: string;
showCopyButton?: boolean;
};
}
const PageDataRow = ({ label, value, truncatedId, highlight }: IPageDataRow): React.JSX.Element => {
return (
<div className="section--data">
<div className="label">{label}</div>
<div className={classNames("value code", { highlight })}>
{truncatedId ? (
<TruncatedId id={truncatedId.id} link={truncatedId.link} showCopyButton={truncatedId.showCopyButton} />
) : (
value
)}
</div>
</div>
);
};

export default PageDataRow;
41 changes: 41 additions & 0 deletions client/src/app/components/nova/StatusPill.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@import "./../../../scss/fonts";
@import "./../../../scss/mixins";
@import "./../../../scss/media-queries";
@import "./../../../scss/variables";

.status-pill {
@include font-size(12px);

display: flex;
align-items: center;
margin-right: 8px;
padding: 6px 12px;
border: 0;
border-radius: 6px;
outline: none;
color: $gray-midnight;
font-family: $inter;
font-weight: 500;
letter-spacing: 0.5px;
white-space: nowrap;

@include phone-down {
height: 32px;
}

&.status__ {
&success {
background-color: var(--message-confirmed-bg);
color: $mint-green-7;
}

&error {
background-color: var(--message-conflicting-bg);
}

&pending {
background-color: var(--light-bg);
color: #8493ad;
}
}
}
42 changes: 42 additions & 0 deletions client/src/app/components/nova/StatusPill.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import classNames from "classnames";
import React from "react";
import { PillStatus } from "~/app/lib/ui/enums";
import Tooltip from "../Tooltip";
import "./StatusPill.scss";

interface IStatusPill {
/**
* Label for the status.
*/
label: string;
/**
* The status of the pill.
*/
status: PillStatus;
/**
* Tooltip explaining further for the label.
*/
tooltip?: string;
}

const StatusPill: React.FC<IStatusPill> = ({ label, status, tooltip }): React.JSX.Element => (
<>
<div
className={classNames("status-pill", {
status__success: status === PillStatus.Success,
status__error: status === PillStatus.Error,
status__pending: status === PillStatus.Pending,
})}
>
{tooltip ? (
<Tooltip tooltipContent={tooltip}>
<span className="capitalize-text">{status}</span>
</Tooltip>
) : (
<span className="capitalize-text">{label}</span>
)}
</div>
</>
);

export default StatusPill;
37 changes: 0 additions & 37 deletions client/src/app/components/nova/block/BlockTangleState.scss
Original file line number Diff line number Diff line change
Expand Up @@ -40,41 +40,4 @@
}
}
}

.block-tangle-state {
@include font-size(12px);

display: flex;
align-items: center;
height: 24px;
margin-right: 8px;
padding: 0 8px;
border: 0;
border-radius: 6px;
outline: none;
background-color: $gray-light;
color: $gray-midnight;
font-family: $inter;
font-weight: 500;
letter-spacing: 0.5px;
white-space: nowrap;

@include phone-down {
height: 32px;
}

&.block-tangle-state__confirmed {
background-color: var(--message-confirmed-bg);
color: $mint-green-7;
}

&.block-tangle-state__conflicting {
background-color: var(--message-conflicting-bg);
}

&.block-tangle-state__pending {
background-color: var(--light-bg);
color: #8493ad;
}
}
}
43 changes: 17 additions & 26 deletions client/src/app/components/nova/block/BlockTangleState.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import classNames from "classnames";
import React from "react";
import Tooltip from "../../Tooltip";
import { BlockState, u64 } from "@iota/sdk-wasm-nova/web";
import { BlockFailureReason, BLOCK_FAILURE_REASON_STRINGS } from "@iota/sdk-wasm-nova/web/lib/types/models/block-failure-reason";
import moment from "moment";
import { BlockState, u64 } from "@iota/sdk-wasm-nova/web";
import { BLOCK_FAILURE_REASON_STRINGS, BlockFailureReason } from "@iota/sdk-wasm-nova/web/lib/types/models/block-failure-reason";
import StatusPill from "~/app/components/nova/StatusPill";
import { PillStatus } from "~/app/lib/ui/enums";
import "./BlockTangleState.scss";

export interface BlockTangleStateProps {
Expand All @@ -23,38 +23,29 @@ export interface BlockTangleStateProps {
failureReason?: BlockFailureReason;
}

const BLOCK_STATE_TO_PILL_STATUS: Record<BlockState, PillStatus> = {
pending: PillStatus.Pending,
accepted: PillStatus.Success,
confirmed: PillStatus.Success,
finalized: PillStatus.Success,
failed: PillStatus.Error,
rejected: PillStatus.Error,
};

const BlockTangleState: React.FC<BlockTangleStateProps> = ({ status, issuingTime, failureReason }) => {
const blockIssueMoment = moment(Number(issuingTime) / 1000000);
const timeReference = blockIssueMoment.fromNow();
const longTimestamp = blockIssueMoment.format("LLLL");

const pillStatus: PillStatus = BLOCK_STATE_TO_PILL_STATUS[status];
const failureReasonString: string | undefined = failureReason ? BLOCK_FAILURE_REASON_STRINGS[failureReason] : undefined;

return (
<>
<div className="blocks-tangle-state">
{status && (
<React.Fragment>
<div
className={classNames(
"block-tangle-state",
{
"block-tangle-state__confirmed": status === "confirmed" || "finalized",
},
{
"block-tangle-state__conflicting": status === "rejected" && "failed",
},
{ "block-tangle-state__pending": status === "pending" },
)}
>
{failureReason ? (
<Tooltip tooltipContent={BLOCK_FAILURE_REASON_STRINGS[failureReason]}>
<span className="capitalize-text" style={{ color: "#ca493d" }}>
{status}
</span>
</Tooltip>
) : (
<span className="capitalize-text">{status}</span>
)}
</div>
<StatusPill status={pillStatus} label={status} tooltip={failureReasonString} />
<div className="block-tangle-reference">
<span title={longTimestamp} className="time-reference">
{timeReference}
Expand Down

This file was deleted.

Loading

0 comments on commit c44dbd7

Please sign in to comment.