Skip to content

Commit

Permalink
fix: resolve conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
brancoder committed Feb 22, 2024
2 parents 8e71f95 + 3d3bb50 commit c26fc8a
Show file tree
Hide file tree
Showing 25 changed files with 598 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/nova-build-temp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
TARGET_COMMIT:
description: "Target Commit Hash for the SDK"
required: false
default: "8f0ff5e1e899a0d960ddfea09237739a88c3bcf1"
default: "fc9f0f56bb5cfc146993e53aa9656ded220734e1"
environment:
type: choice
description: "Select the environment to deploy to"
Expand Down
11 changes: 11 additions & 0 deletions api/src/models/api/nova/ICongestionRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface ICongestionRequest {
/**
* The network to search on.
*/
network: string;

/**
* The account id to get the congestion for.
*/
accountId: string;
}
11 changes: 11 additions & 0 deletions api/src/models/api/nova/ICongestionResponse.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable import/no-unresolved */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import { CongestionResponse } from "@iota/sdk-nova";
import { IResponse } from "./IResponse";

export interface ICongestionResponse extends IResponse {
/**
* The Account Congestion.
*/
congestion?: CongestionResponse;
}
6 changes: 6 additions & 0 deletions api/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ export const routes: IRoute[] = [
folder: "nova/transaction",
func: "get",
},
{
path: "/nova/account/congestion/:network/:accountId",
method: "get",
folder: "nova/account/congestion",
func: "get",
},
{ 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" },
];
30 changes: 30 additions & 0 deletions api/src/routes/nova/account/congestion/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ServiceFactory } from "../../../../factories/serviceFactory";
import { ICongestionRequest } from "../../../../models/api/nova/ICongestionRequest";
import { ICongestionResponse } from "../../../../models/api/nova/ICongestionResponse";
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";

/**
* Get Congestion for Account address
* @param config The configuration.
* @param request The request.
* @returns The response.
*/
export async function get(config: IConfiguration, request: ICongestionRequest): Promise<ICongestionResponse> {
const networkService = ServiceFactory.get<NetworkService>("network");
const networks = networkService.networkNames();
ValidationHelper.oneOf(request.network, networks, "network");
ValidationHelper.string(request.accountId, "accountId");

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

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

const novaApiService = ServiceFactory.get<NovaApiService>(`api-service-${networkConfig.network}`);
return novaApiService.getAccountCongestion(request.accountId);
}
20 changes: 20 additions & 0 deletions api/src/services/nova/novaApiService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { IAddressDetailsResponse } from "../../models/api/nova/IAddressDetailsRe
import { IAnchorDetailsResponse } from "../../models/api/nova/IAnchorDetailsResponse";
import { IBlockDetailsResponse } from "../../models/api/nova/IBlockDetailsResponse";
import { IBlockResponse } from "../../models/api/nova/IBlockResponse";
import { ICongestionResponse } from "../../models/api/nova/ICongestionResponse";
import { INftDetailsResponse } from "../../models/api/nova/INftDetailsResponse";
import { IOutputDetailsResponse } from "../../models/api/nova/IOutputDetailsResponse";
import { IRewardsResponse } from "../../models/api/nova/IRewardsResponse";
Expand Down Expand Up @@ -275,6 +276,25 @@ export class NovaApiService {
};
}

/**
* Get Congestion for Account
* @param accountId The account address to get the congestion for.
* @returns The Congestion.
*/
public async getAccountCongestion(accountId: string): Promise<ICongestionResponse | undefined> {
try {
const response = await this.client.getAccountCongestion(accountId);

if (response) {
return {
congestion: response,
};
}
} catch {
return { message: "Account congestion not found" };
}
}

/**
* Get the output mana rewards.
* @param outputId The outputId to get the rewards for.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { useState } from "react";
import associatedOuputsMessage from "~assets/modals/stardust/address/associated-outputs.json";
import foundriesMessage from "~assets/modals/stardust/alias/foundries.json";
import stateMessage from "~assets/modals/stardust/alias/state.json";
import bicMessage from "~assets/modals/nova/account/bic.json";
import TabbedSection from "../../../hoc/TabbedSection";
import AssociatedOutputs from "./association/AssociatedOutputs";
import nativeTokensMessage from "~assets/modals/stardust/address/assets-in-wallet.json";
Expand All @@ -12,16 +14,23 @@ import AssetsTable from "./native-tokens/AssetsTable";
import { IImplicitAccountCreationAddressState } from "~/helpers/nova/hooks/useImplicitAccountCreationAddressState";
import { AddressType } from "@iota/sdk-wasm-nova/web";
import AccountFoundriesSection from "./account/AccountFoundriesSection";
import AccountBlockIssuanceSection from "./account/AccountBlockIssuanceSection";
import AnchorStateSection from "./anchor/AnchorStateSection";

enum DEFAULT_TABS {
AssocOutputs = "Outputs",
NativeTokens = "Native Tokens",
}

enum ACCOUNT_TABS {
BlockIssuance = "Block Issuance",
Foundries = "Foundries",
}

enum ANCHOR_TABS {
State = "State",
}

const buildDefaultTabsOptions = (tokensCount: number, associatedOutputCount: number) => ({
[DEFAULT_TABS.AssocOutputs]: {
disabled: associatedOutputCount === 0,
Expand All @@ -37,13 +46,33 @@ const buildDefaultTabsOptions = (tokensCount: number, associatedOutputCount: num
},
});

const buildAccountAddressTabsOptions = (foundriesCount: number, isAccountFoundriesLoading: boolean) => ({
const buildAccountAddressTabsOptions = (
isBlockIssuer: boolean,
isCongestionLoading: boolean,
foundriesCount: number,
isAccountFoundriesLoading: boolean,
) => ({
[ACCOUNT_TABS.Foundries]: {
disabled: foundriesCount === 0,
hidden: foundriesCount === 0,
isLoading: isAccountFoundriesLoading,
infoContent: foundriesMessage,
},
[ACCOUNT_TABS.BlockIssuance]: {
disabled: !isBlockIssuer,
hidden: !isBlockIssuer,
isLoading: isCongestionLoading,
infoContent: bicMessage,
},
});

const buildAnchorAddressTabsOptions = (isAnchorStateTabDisabled: boolean, isAnchorDetailsLoading: boolean) => ({
[ANCHOR_TABS.State]: {
disabled: isAnchorStateTabDisabled,
hidden: isAnchorStateTabDisabled,
isLoading: isAnchorDetailsLoading,
infoContent: stateMessage,
},
});

interface IAddressPageTabbedSectionsProps {
Expand Down Expand Up @@ -78,31 +107,59 @@ export const AddressPageTabbedSections: React.FC<IAddressPageTabbedSectionsProps
const accountAddressSections =
addressDetails.type === AddressType.Account
? [
<AccountBlockIssuanceSection
key={`account-block-issuance-${addressDetails.bech32}`}
blockIssuerFeature={(addressState as IAccountAddressState).blockIssuerFeature}
congestion={(addressState as IAccountAddressState).congestion}
/>,
<AccountFoundriesSection
key={`account-foundry-${addressDetails.bech32}`}
foundries={(addressState as IAccountAddressState).foundries}
/>,
]
: null;

const anchorAddressSections =
addressDetails.type === AddressType.Anchor
? [
<AnchorStateSection
key={`anchor-state-${addressDetails.bech32}`}
output={(addressState as IAnchorAddressState).anchorOutput}
/>,
]
: null;

let tabEnums = DEFAULT_TABS;
const defaultTabsOptions = buildDefaultTabsOptions(tokensCount, outputCount);
let tabOptions = defaultTabsOptions;
let tabbedSections = defaultSections;

switch (addressDetails.type) {
case AddressType.Account: {
const accountAddressState = addressState as IAccountAddressState;
tabEnums = { ...DEFAULT_TABS, ...ACCOUNT_TABS };
tabOptions = {
...defaultTabsOptions,
...buildAccountAddressTabsOptions(
(addressState as IAccountAddressState).accountOutput?.foundryCounter ?? 0,
(addressState as IAccountAddressState).isFoundriesLoading,
accountAddressState.blockIssuerFeature !== null,
accountAddressState.isCongestionLoading,
accountAddressState.accountOutput?.foundryCounter ?? 0,
accountAddressState.isFoundriesLoading,
),
};
tabbedSections = [...defaultSections, ...(accountAddressSections ?? [])];
break;
}
case AddressType.Anchor: {
const anchorAddressState = addressState as IAnchorAddressState;
tabEnums = { ...DEFAULT_TABS, ...ANCHOR_TABS };
tabOptions = {
...defaultTabsOptions,
...buildAnchorAddressTabsOptions(anchorAddressState.anchorOutput === null, anchorAddressState.isAnchorDetailsLoading),
};
tabbedSections = [...defaultSections, ...(anchorAddressSections ?? [])];
break;
}
default: {
break;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@import "../../../../../../scss/mixins.scss";

.block-issuance--card {
border: none !important;
margin-bottom: 48px;

.field {
margin-bottom: 8px;

.card--label {
@include font-size(14px, 21px);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from "react";
import { BlockIssuerFeature, CongestionResponse, Ed25519PublicKeyHashBlockIssuerKey } from "@iota/sdk-wasm-nova/web";
import TruncatedId from "~/app/components/stardust/TruncatedId";
import "./AccountBlockIssuanceSection.scss";

interface AccountBlockIssuanceSectionProps {
readonly blockIssuerFeature: BlockIssuerFeature | null;
readonly congestion: CongestionResponse | null;
}

const AccountBlockIssuanceSection: React.FC<AccountBlockIssuanceSectionProps> = ({ blockIssuerFeature, congestion }) => {
return (
<div className="section transaction--section">
<div className="card block-issuance--card">
<div className="field">
<div className="card--label margin-b-t">Current Slot</div>
<div className="card--value">{congestion?.slot}</div>
</div>
<div className="field">
<div className="card--label margin-b-t">Block Issuance Credit</div>
<div className="card--value">{congestion?.blockIssuanceCredits.toString()}</div>
</div>
<div className="field">
<div className="card--label margin-b-t">Referenced Mana Cost</div>
<div className="card--value">{congestion?.referenceManaCost.toString()}</div>
</div>
<div className="field">
<div className="card--label margin-b-t">Expiry Slot</div>
<div className="card--value">{blockIssuerFeature?.expirySlot}</div>
</div>
<div className="field">
{blockIssuerFeature?.blockIssuerKeys.map((key) => (
<React.Fragment key={(key as Ed25519PublicKeyHashBlockIssuerKey).pubKeyHash}>
<span className="card--label margin-b-t">Public Key:</span>
<div className="card--value public-key">
<TruncatedId id={(key as Ed25519PublicKeyHashBlockIssuerKey).pubKeyHash} showCopyButton />
</div>
</React.Fragment>
))}
</div>
</div>
</div>
);
};

export default AccountBlockIssuanceSection;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { AnchorOutput, FeatureType, StateMetadataFeature } from "@iota/sdk-wasm-nova/web";
import React from "react";
import DataToggle from "~/app/components/DataToggle";

interface AnchorStateSectionProps {
/**
* The Anchor Output
*/
readonly output: AnchorOutput | null;
}

const AnchorStateSection: React.FC<AnchorStateSectionProps> = ({ output }) => {
const stateMetadata = output?.features?.find((feature) => feature.type === FeatureType.StateMetadata) as StateMetadataFeature;

return (
<div className="section">
<div className="section--data">
<div>
<div className="label">State Index</div>
<div className="value row middle margin-t-t">
<span className="margin-r-t">{output?.stateIndex}</span>
</div>
</div>
{Object.entries(stateMetadata.entries).map(([key, value], index) => (
<div key={index}>
<div className="label margin-t-m">{key}</div>
<div className="value row middle margin-t-t">
<DataToggle sourceData={value} withSpacedHex={true} />
</div>
</div>
))}
</div>
</div>
);
};

export default AnchorStateSection;
11 changes: 11 additions & 0 deletions client/src/assets/modals/nova/account/bic.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"title": "Block Issuance Credit",
"description": "<p>(BIC) is the form of Mana used as an anti-spam mechanism to the block issuance process.</p>",
"links": [
{
"label": "Read more",
"href": "https://wiki.iota.org/learn/protocols/iota2.0/core-concepts/mana/#block-issuance-credits-bic",
"isExternal": true
}
]
}
Loading

0 comments on commit c26fc8a

Please sign in to comment.