diff --git a/.changeset/soft-forks-hope.md b/.changeset/soft-forks-hope.md
deleted file mode 100644
index 69d17cc28..000000000
--- a/.changeset/soft-forks-hope.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@fuels/ui": minor
----
-
-Make the @fuels/ui package public and publishable
diff --git a/contracts/predicate/package.json b/contracts/predicate/package.json
index 2feff0270..d5c791b50 100644
--- a/contracts/predicate/package.json
+++ b/contracts/predicate/package.json
@@ -1,5 +1,6 @@
{
"name": "predicate",
+ "private": true,
"version": "0.0.1",
"description": "Predicate app using Sway",
"scripts": {
diff --git a/docker/erc20-deployer/deployer/package.json b/docker/erc20-deployer/deployer/package.json
index 36f671e30..d0c5a649c 100644
--- a/docker/erc20-deployer/deployer/package.json
+++ b/docker/erc20-deployer/deployer/package.json
@@ -1,5 +1,6 @@
{
"name": "erc20-deployer",
+ "private": true,
"scripts": {
"start": "ts-node ./src/index.ts"
},
diff --git a/helm/fuel-explorer/Chart.yaml b/helm/fuel-explorer/Chart.yaml
index 562f4ac43..0187195f4 100644
--- a/helm/fuel-explorer/Chart.yaml
+++ b/helm/fuel-explorer/Chart.yaml
@@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 0.1.11
+version: 0.1.12
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
diff --git a/helm/fuel-explorer/templates/servicemonitor.yaml b/helm/fuel-explorer/templates/servicemonitor.yaml
new file mode 100644
index 000000000..62f88095a
--- /dev/null
+++ b/helm/fuel-explorer/templates/servicemonitor.yaml
@@ -0,0 +1,15 @@
+{{- if .Values.app.serviceMonitor.enabled }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ include "fuel-explorer.fullname" . }}
+ labels:
+ release: {{ .Values.app.serviceMonitor.prometheusRelease }}
+spec:
+ selector:
+ matchLabels:
+ {{- include "fuel-explorer.labels" . | nindent 4 }}
+ endpoints:
+ - path: /metrics
+ port: http
+{{- end }}
diff --git a/helm/fuel-explorer/values.yaml b/helm/fuel-explorer/values.yaml
index 82263c908..783c0a3e8 100644
--- a/helm/fuel-explorer/values.yaml
+++ b/helm/fuel-explorer/values.yaml
@@ -83,3 +83,8 @@ nodeSelector: {}
tolerations: []
affinity: {}
+
+app:
+ serviceMonitor:
+ enabled: true
+ prometheusRelease: kube-prometheus
diff --git a/packages/app-explorer/src/systems/Core/components/BalanceItem/BalanceItem.tsx b/packages/app-explorer/src/systems/Core/components/BalanceItem/BalanceItem.tsx
index 1cf5d17b5..394c8bcd4 100644
--- a/packages/app-explorer/src/systems/Core/components/BalanceItem/BalanceItem.tsx
+++ b/packages/app-explorer/src/systems/Core/components/BalanceItem/BalanceItem.tsx
@@ -13,7 +13,8 @@ import { AssetItem } from '~/systems/Asset/components/AssetItem/AssetItem';
import type { GQLBalanceItemFragment } from '@fuel-explorer/graphql';
import { Amount } from '../Amount/Amount';
-import type { UtxoItem } from '../Utxos/Utxos';
+
+import { UtxoItemType } from '~/systems/Core/components/Utxos/types';
import { Utxos } from '../Utxos/Utxos';
type BalanceItemProps = BaseProps<{
@@ -56,7 +57,9 @@ export function BalanceItem({ item, isLoading, ...props }: BalanceItemProps) {
- {hasUTXOs && }
+ {hasUTXOs && (
+ } assetId={assetId} />
+ )}
);
}
diff --git a/packages/app-explorer/src/systems/Core/components/UtxoItem/UtxoItem.tsx b/packages/app-explorer/src/systems/Core/components/UtxoItem/UtxoItem.tsx
new file mode 100644
index 000000000..5b9ce823d
--- /dev/null
+++ b/packages/app-explorer/src/systems/Core/components/UtxoItem/UtxoItem.tsx
@@ -0,0 +1,50 @@
+import { Address, Box, useBreakpoints } from '@fuels/ui';
+import { bn, toBytes, toHex } from 'fuels';
+import NextLink from 'next/link';
+import { useMemo } from 'react';
+import { Routes } from '~/routes';
+
+import { Amount } from '../Amount/Amount';
+import { TX_ID_SIZE, UTXO_ID_SIZE } from './constants';
+import { styles } from './styles';
+import { UtxoItemProps } from './types';
+
+export function UtxoItem({ item, style, assetId, index }: UtxoItemProps) {
+ const { isMobile } = useBreakpoints();
+
+ const txId = useMemo(() => {
+ if (!item.utxoId) return null;
+ const bytes = toBytes(item.utxoId, UTXO_ID_SIZE).slice(0, TX_ID_SIZE);
+ return toHex(bytes, TX_ID_SIZE);
+ }, []);
+
+ if (!txId) return null;
+
+ const trim = isMobile ? 8 : 16;
+ const { item: itemStyle } = styles({
+ color: index % 2 !== 0 ? 'odd' : undefined,
+ });
+
+ return (
+
+
+
+
+ );
+}
diff --git a/packages/app-explorer/src/systems/Core/components/UtxoItem/constants.ts b/packages/app-explorer/src/systems/Core/components/UtxoItem/constants.ts
new file mode 100644
index 000000000..ef20df99d
--- /dev/null
+++ b/packages/app-explorer/src/systems/Core/components/UtxoItem/constants.ts
@@ -0,0 +1,2 @@
+export const UTXO_ID_SIZE = 34;
+export const TX_ID_SIZE = 32;
diff --git a/packages/app-explorer/src/systems/Core/components/UtxoItem/styles.ts b/packages/app-explorer/src/systems/Core/components/UtxoItem/styles.ts
new file mode 100644
index 000000000..929e86f38
--- /dev/null
+++ b/packages/app-explorer/src/systems/Core/components/UtxoItem/styles.ts
@@ -0,0 +1,19 @@
+import { tv } from 'tailwind-variants';
+
+export const styles = tv({
+ slots: {
+ item: [
+ 'flex flex-col p-2 px-4 gap-2',
+ 'tablet:flex-row',
+ 'last:rounded-b-sm',
+ 'fuel-[Address]:text-[0.8rem] fuel-[Address]:leading-none',
+ ],
+ },
+ variants: {
+ color: {
+ odd: {
+ item: 'bg-gray-4',
+ },
+ },
+ },
+});
diff --git a/packages/app-explorer/src/systems/Core/components/UtxoItem/types.ts b/packages/app-explorer/src/systems/Core/components/UtxoItem/types.ts
new file mode 100644
index 000000000..53b304ceb
--- /dev/null
+++ b/packages/app-explorer/src/systems/Core/components/UtxoItem/types.ts
@@ -0,0 +1,9 @@
+import type { CSSProperties } from 'react';
+import type { UtxoItemType } from '~/systems/Core/components/Utxos/types';
+
+export type UtxoItemProps = {
+ item: UtxoItemType;
+ assetId?: string;
+ style?: CSSProperties;
+ index: number;
+};
diff --git a/packages/app-explorer/src/systems/Core/components/Utxos/Utxos.tsx b/packages/app-explorer/src/systems/Core/components/Utxos/Utxos.tsx
index 75289978d..4dcd15595 100644
--- a/packages/app-explorer/src/systems/Core/components/Utxos/Utxos.tsx
+++ b/packages/app-explorer/src/systems/Core/components/Utxos/Utxos.tsx
@@ -1,72 +1,9 @@
-import type { GQLUtxoItem as TUtxoItem } from '@fuel-explorer/graphql';
-import { Address, Box, Collapsible, useBreakpoints } from '@fuels/ui';
-import type { BoxProps } from '@fuels/ui';
+import { Collapsible, useBreakpoints } from '@fuels/ui';
import { IconCoins } from '@tabler/icons-react';
-import { bn, toBytes, toHex } from 'fuels';
-import NextLink from 'next/link';
import { FixedSizeList as List } from 'react-window';
-import { tv } from 'tailwind-variants';
-import { Routes } from '~/routes';
-import { useMemo } from 'react';
-import { Amount } from '../Amount/Amount';
-
-export type UtxoItem = Partial>;
-
-type UtxoItemProps = {
- item: UtxoItem;
- assetId?: string;
- style?: React.CSSProperties;
- index: number;
-};
-
-const UTXO_ID_SIZE = 34;
-const TX_ID_SIZE = 32;
-
-function UtxoItem({ item, style, assetId, index }: UtxoItemProps) {
- const { isMobile } = useBreakpoints();
-
- const txId = useMemo(() => {
- if (!item.utxoId) return null;
- const bytes = toBytes(item.utxoId, UTXO_ID_SIZE).slice(0, TX_ID_SIZE);
- return toHex(bytes, TX_ID_SIZE);
- }, []);
-
- if (!txId) return null;
-
- const trim = isMobile ? 8 : 16;
- const { item: itemStyle } = styles({
- color: index % 2 !== 0 ? 'odd' : undefined,
- });
-
- return (
-
-
-
-
- );
-}
-
-type UtxosProps = BoxProps & {
- assetId?: string;
- items?: UtxoItem[] | null;
-};
+import { UtxoItem } from '~/systems/Core/components/UtxoItem/UtxoItem';
+import { UtxosProps } from './types';
function VirtualList({ items, assetId }: UtxosProps) {
const { isMobile } = useBreakpoints();
@@ -110,21 +47,3 @@ export function Utxos({ items, assetId, ...props }: UtxosProps) {
);
}
-
-const styles = tv({
- slots: {
- item: [
- 'flex flex-col p-2 px-4 gap-2',
- 'tablet:flex-row',
- 'last:rounded-b-sm',
- 'fuel-[Address]:text-[0.8rem] fuel-[Address]:leading-none',
- ],
- },
- variants: {
- color: {
- odd: {
- item: 'bg-gray-4',
- },
- },
- },
-});
diff --git a/packages/app-explorer/src/systems/Core/components/Utxos/types.ts b/packages/app-explorer/src/systems/Core/components/Utxos/types.ts
new file mode 100644
index 000000000..d0c8afe39
--- /dev/null
+++ b/packages/app-explorer/src/systems/Core/components/Utxos/types.ts
@@ -0,0 +1,8 @@
+import type { GQLUtxoItem as TUtxoItem } from '@fuel-explorer/graphql/sdk';
+import type { BoxProps } from '@fuels/ui';
+
+export type UtxoItemType = Partial>;
+export type UtxosProps = BoxProps & {
+ assetId?: string;
+ items?: UtxoItemType[] | null;
+};
diff --git a/packages/app-explorer/src/systems/Transaction/__mocks__/tx.ts b/packages/app-explorer/src/systems/Transaction/__mocks__/tx.ts
index 12266031b..6190aca88 100644
--- a/packages/app-explorer/src/systems/Transaction/__mocks__/tx.ts
+++ b/packages/app-explorer/src/systems/Transaction/__mocks__/tx.ts
@@ -1,4 +1,4 @@
-import { GQLInputCoin, mocks } from '@fuel-explorer/graphql';
+import { mocks } from '@fuel-explorer/graphql';
import { dayjs } from '~/systems/Core/utils/dayjs';
const date = dayjs().subtract(1, 'day');
@@ -9,10 +9,22 @@ const status = mocks.aSuccessStatus({
}),
});
-function input(typename: GQLInputCoin['__typename']) {
- return mocks.anInputCoin({ __typename: typename });
+function mockedInputCoinFactory() {
+ return mocks.anInputCoin({ __typename: 'InputCoin' });
}
+function mockedInputMessageFactory() {
+ return mocks.anInputMessage({ __typename: 'InputMessage' });
+}
+
+function mockedInputContractFactory() {
+ return mocks.anInputContract({ __typename: 'InputContract' });
+}
+
+export const MOCKED_COIN = mockedInputCoinFactory();
+export const MOCKED_MESSAGE = mockedInputMessageFactory();
+export const MOCKED_CONTRACT = mockedInputContractFactory();
+
const ADDRS = {
to: '0xf65d6448a273b531ee942c133bb91a6f904c7d7f3104cdaf6b9f7f50d3518871',
owner: '0xf65d6448a273b531ee942c133bb91a6f904c7d7f3104cdaf6b9f7f50d3518871',
@@ -23,18 +35,26 @@ const ADDRS = {
'0x4c6be4ed66b783f55e44a6d36290a73970a616ba33256636cf15ad5cded228d9',
};
-export const GROUPED_INPUT_ASSET = mocks.aGroupedInputCoin({
+const GROUPED_INPUT_ASSET = mocks.aGroupedInputCoin({
...ADDRS,
assetId: '0x0000000000000000000000000000000000000000',
- inputs: [input('InputCoin'), input('InputCoin'), input('InputCoin')],
+ inputs: [
+ mockedInputCoinFactory(),
+ mockedInputCoinFactory(),
+ mockedInputCoinFactory(),
+ ],
});
-export const GROUPED_INPUT_ASSET_UNKNOWN = mocks.aGroupedInputCoin({
+const GROUPED_INPUT_ASSET_UNKNOWN = mocks.aGroupedInputCoin({
...ADDRS,
- inputs: [input('InputCoin'), input('InputCoin'), input('InputCoin')],
+ inputs: [
+ mockedInputCoinFactory(),
+ mockedInputCoinFactory(),
+ mockedInputCoinFactory(),
+ ],
});
-export const GROUPED_INPUT_MESSAGE = mocks.aGroupedInputMessage({
+const GROUPED_INPUT_MESSAGE = mocks.aGroupedInputMessage({
...ADDRS,
});
@@ -65,6 +85,12 @@ export const TX_MOCK = mocks.aTransaction({
GROUPED_INPUT_ASSET,
GROUPED_INPUT_MESSAGE,
],
+ // @TODO: Fix maximum call stack size exceeded and remove override below
+ operations: [
+ mocks.anOperation({
+ receipts: [mocks.anOperationReceipt({ receipts: [] })] ?? [],
+ }),
+ ],
groupedOutputs: [],
outputs: [OUTPUT_ASSET, OUTPUT_ASSET_UNKNOWN, OUTPUT_CONTRACT_CREATED],
});
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInput.stories.tsx b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInput.stories.tsx
index acb0c279f..986c6fdb1 100644
--- a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInput.stories.tsx
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInput.stories.tsx
@@ -2,9 +2,9 @@ import { VStack } from '@fuels/ui';
import type { Meta, StoryObj } from '@storybook/react';
import {
- GROUPED_INPUT_ASSET,
- GROUPED_INPUT_ASSET_UNKNOWN,
- GROUPED_INPUT_MESSAGE,
+ MOCKED_COIN,
+ MOCKED_CONTRACT,
+ MOCKED_MESSAGE,
} from '../../__mocks__/tx';
import { TxInput } from './TxInput';
@@ -17,15 +17,30 @@ const meta: Meta = {
export default meta;
type Story = StoryObj;
-export const Asset: Story = {
+function Wrapper({ children }: { children: React.ReactNode }) {
+ return {children};
+}
+
+export const Coin: Story = {
render: () => (
-
-
-
-
+
+
+
),
};
export const Message: Story = {
- render: () => ,
+ render: () => (
+
+
+
+ ),
+};
+
+export const Contract: Story = {
+ render: () => (
+
+
+
+ ),
};
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInput.tsx b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInput.tsx
index ff6795208..c3575251f 100644
--- a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInput.tsx
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInput.tsx
@@ -1,137 +1,23 @@
-import type {
- GQLGroupedInput,
- GQLGroupedInputCoin,
- GQLGroupedInputMessage,
- GQLInputCoin,
-} from '@fuel-explorer/graphql';
-import type { CardProps } from '@fuels/ui';
-import {
- Address,
- Box,
- Collapsible,
- HStack,
- Text,
- VStack,
- createComponent,
- useBreakpoints,
-} from '@fuels/ui';
-import { bn } from 'fuels';
-import NextLink from 'next/link';
-import { Routes } from '~/routes';
-import { AssetItem } from '~/systems/Asset/components/AssetItem/AssetItem';
-import { Amount } from '~/systems/Core/components/Amount/Amount';
-import type { UtxoItem } from '~/systems/Core/components/Utxos/Utxos';
-import { Utxos } from '~/systems/Core/components/Utxos/Utxos';
-
-import { TxIcon } from '../TxIcon/TxIcon';
-
-export type TxInputProps = CardProps & {
- input: GQLGroupedInput;
-};
-
-export type TxInputCoinProps = TxInputProps & {
- input: GQLGroupedInputCoin;
-};
-
-export type TxInputMessageProps = TxInputProps & {
- input: GQLGroupedInputMessage;
-};
-
-const TxInputCoin = createComponent({
- id: 'TxInputCoin',
- render: (_, { input, ...props }) => {
- if (!input.assetId) return null;
-
- const assetId = input.assetId;
- const amount = input.totalAmount;
- const inputs = input.inputs as GQLInputCoin[];
- const { isMobile } = useBreakpoints();
-
- return (
-
-
-
-
-
- {amount && (
-
-
-
- )}
-
-
-
- );
- },
-});
-
-const TxInputMessage = createComponent(
- {
- id: 'TxInputMessage',
- render: (_, { input, ...props }) => {
- const { sender, recipient, data } = input;
-
- if (!sender || !recipient) return null;
-
- return (
-
-
-
-
- Message
-
-
-
-
-
-
-
- Data
-
- {data}
-
-
-
- );
- },
- },
-);
-
-export function TxInput({ input, ...props }: TxInputProps) {
- if (input.type?.includes('Coin')) {
- return ;
- }
- if (input.type?.includes('Message')) {
- return (
-
- );
+import { memo } from 'react';
+import { TxInputCoin } from '~/systems/Transaction/component/TxInput/TxInputCoin/TxInputCoin';
+import type { InputCoin } from '~/systems/Transaction/component/TxInput/TxInputCoin/types';
+import { TxInputContract } from '~/systems/Transaction/component/TxInput/TxInputContract/TxInputContract';
+import type { InputContract } from '~/systems/Transaction/component/TxInput/TxInputContract/types';
+import { TxInputMessage } from '~/systems/Transaction/component/TxInput/TxInputMessage/TxInputMessage';
+import type { InputMessage } from '~/systems/Transaction/component/TxInput/TxInputMessage/types';
+import { TxInputProps } from './types';
+
+function _TxInput({ input, ...props }: TxInputProps) {
+ switch (input?.__typename) {
+ case 'InputCoin':
+ return ;
+ case 'InputMessage':
+ return ;
+ case 'InputContract':
+ return ;
+ default:
+ return null;
}
}
+
+export const TxInput = memo(_TxInput);
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputCoin/TxInputCoin.tsx b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputCoin/TxInputCoin.tsx
new file mode 100644
index 000000000..fcfe7b1a1
--- /dev/null
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputCoin/TxInputCoin.tsx
@@ -0,0 +1,95 @@
+import {
+ Address,
+ Badge,
+ Box,
+ Collapsible,
+ Flex,
+ createComponent,
+ useBreakpoints,
+} from '@fuels/ui';
+import { IconCoins } from '@tabler/icons-react';
+import { bn } from 'fuels';
+import NextLink from 'next/link';
+
+import { Routes } from '~/routes';
+import { AssetItem } from '~/systems/Asset/components/AssetItem/AssetItem';
+import { Amount } from '~/systems/Core/components/Amount/Amount';
+import { UtxoItem } from '~/systems/Core/components/UtxoItem/UtxoItem';
+import { TxInputCoinProps } from './types';
+
+export const TxInputCoin = createComponent<
+ TxInputCoinProps,
+ typeof Collapsible
+>({
+ id: 'TxInputCoin',
+ render: (_, { input, ...props }) => {
+ if (!input.assetId) return null;
+
+ const assetId = input.assetId;
+ const amount = input.amount;
+ const { isMobile } = useBreakpoints();
+
+ return (
+
+
+
+
+ COIN
+
+
+
+
+
+
+ {amount && (
+
+
+ COIN
+
+
+
+ )}
+
+
+
+
+
+ UTXO
+
+
+
+
+
+
+ );
+ },
+});
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputCoin/types.ts b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputCoin/types.ts
new file mode 100644
index 000000000..56cc56457
--- /dev/null
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputCoin/types.ts
@@ -0,0 +1,11 @@
+import type { GQLTransactionItemFragment } from '@fuel-explorer/graphql/sdk';
+import type { TxInputProps } from '~/systems/Transaction/component/TxInput/types';
+
+export type InputCoin = Extract<
+ NonNullable[number],
+ { __typename: 'InputCoin' }
+>;
+
+export type TxInputCoinProps = TxInputProps & {
+ input: InputCoin;
+};
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/TxInputContract.tsx b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/TxInputContract.tsx
new file mode 100644
index 000000000..1997691d6
--- /dev/null
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/TxInputContract.tsx
@@ -0,0 +1,110 @@
+import {
+ Address,
+ Badge,
+ Collapsible,
+ Flex,
+ HStack,
+ Text,
+ VStack,
+ createComponent,
+ useBreakpoints,
+} from '@fuels/ui';
+import NextLink from 'next/link';
+
+import { IconCode } from '@tabler/icons-react';
+import { Routes } from '~/routes';
+import { TxIcon } from '~/systems/Transaction/component/TxIcon/TxIcon';
+import { styles } from './styles';
+import type { TxInputContractProps } from './types';
+
+export const TxInputContract = createComponent<
+ TxInputContractProps,
+ typeof Collapsible
+>({
+ id: 'TxInputContract',
+ render: (_, { input, ...props }) => {
+ const { utxoId, balanceRoot, txPointer, contractId } = input;
+ const { isMobile } = useBreakpoints();
+ const trim = isMobile ? 8 : 16;
+ const classes = styles();
+
+ return (
+
+
+
+
+ CONTRACT
+
+
+
+
+
+ Contract
+
+
+
+
+
+
+
+
+ Data
+
+
+
+
+
+
+
+
+ Tx Pointer:
+
+
+ {txPointer}
+
+
+
+
+
+
+ );
+ },
+});
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/styles.ts b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/styles.ts
new file mode 100644
index 000000000..f4813a8d2
--- /dev/null
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/styles.ts
@@ -0,0 +1,14 @@
+import { tv } from 'tailwind-variants';
+
+export const styles = tv({
+ slots: {
+ item: [
+ 'flex flex-col p-2 px-4 gap-2',
+ 'tablet:flex-row',
+ 'last:rounded-b-sm',
+ 'fuel-[Address]:text-[0.8rem] fuel-[Address]:leading-none',
+ ],
+ contractAddress:
+ 'flex-col items-start gap-1 flex-1 tablet:flex-row tablet:items-center tablet:gap-4',
+ },
+});
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/types.ts b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/types.ts
new file mode 100644
index 000000000..aa8ff1f52
--- /dev/null
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputContract/types.ts
@@ -0,0 +1,11 @@
+import type { GQLTransactionItemFragment } from '@fuel-explorer/graphql/sdk';
+import type { TxInputProps } from '~/systems/Transaction/component/TxInput/types';
+
+export type InputContract = Extract<
+ NonNullable[number],
+ { __typename: 'InputContract' }
+>;
+
+export type TxInputContractProps = TxInputProps & {
+ input: InputContract;
+};
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputMessage/TxInputMessage.tsx b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputMessage/TxInputMessage.tsx
new file mode 100644
index 000000000..2de5c924e
--- /dev/null
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputMessage/TxInputMessage.tsx
@@ -0,0 +1,83 @@
+import {
+ Address,
+ Badge,
+ Collapsible,
+ Flex,
+ HStack,
+ Text,
+ VStack,
+ createComponent,
+} from '@fuels/ui';
+import NextLink from 'next/link';
+
+import { Routes } from '~/routes';
+import { TxIcon } from '~/systems/Transaction/component/TxIcon/TxIcon';
+import type { TxInputMessageProps } from './types';
+
+export const TxInputMessage = createComponent<
+ TxInputMessageProps,
+ typeof Collapsible
+>({
+ id: 'TxInputMessage',
+ render: (_, { input, ...props }) => {
+ const { sender, recipient, data } = input;
+
+ if (!sender || !recipient) return null;
+
+ return (
+
+
+
+
+ MESSAGE
+
+
+
+
+
+ Message
+
+
+
+
+
+
+ MESSAGE
+
+
+
+
+
+
+
+ Data
+
+ {data}
+
+
+
+ );
+ },
+});
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputMessage/types.ts b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputMessage/types.ts
new file mode 100644
index 000000000..880ca7b11
--- /dev/null
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/TxInputMessage/types.ts
@@ -0,0 +1,11 @@
+import type { GQLTransactionItemFragment } from '@fuel-explorer/graphql/sdk';
+import type { TxInputProps } from '~/systems/Transaction/component/TxInput/types';
+
+export type InputMessage = Extract<
+ NonNullable[number],
+ { __typename: 'InputMessage' }
+>;
+
+export type TxInputMessageProps = TxInputProps & {
+ input: InputMessage;
+};
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxInput/types.ts b/packages/app-explorer/src/systems/Transaction/component/TxInput/types.ts
new file mode 100644
index 000000000..bc8fa6f0e
--- /dev/null
+++ b/packages/app-explorer/src/systems/Transaction/component/TxInput/types.ts
@@ -0,0 +1,6 @@
+import type { GQLTransactionItemFragment } from '@fuel-explorer/graphql/sdk';
+import type { CardProps } from '@fuels/ui';
+
+export type TxInputProps = CardProps & {
+ input: NonNullable[number] | undefined;
+};
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxScreen/TxScreenSimple.tsx b/packages/app-explorer/src/systems/Transaction/component/TxScreen/TxScreenSimple.tsx
index 8fc9a5fac..efc0b226a 100644
--- a/packages/app-explorer/src/systems/Transaction/component/TxScreen/TxScreenSimple.tsx
+++ b/packages/app-explorer/src/systems/Transaction/component/TxScreen/TxScreenSimple.tsx
@@ -1,6 +1,6 @@
'use client';
-import { GQLGroupedInput } from '@fuel-explorer/graphql';
+import type { GQLTransactionItemFragment } from '@fuel-explorer/graphql';
import {
Address,
Badge,
@@ -200,9 +200,18 @@ function ContentMain({
Inputs
- {tx?.groupedInputs?.map((input, i) => (
- // here we use only index as key because this component will not change
-
+ {tx?.inputs?.map((input, i) => (
+ // here we use index as key because this component will not change
+ [number]
+ | undefined
+ }
+ />
))}
>
}
diff --git a/packages/app-explorer/src/systems/Transaction/component/TxScripts/TxOperationHeader.tsx b/packages/app-explorer/src/systems/Transaction/component/TxScripts/TxOperationHeader.tsx
index 31c398af9..210bb1ce9 100644
--- a/packages/app-explorer/src/systems/Transaction/component/TxScripts/TxOperationHeader.tsx
+++ b/packages/app-explorer/src/systems/Transaction/component/TxScripts/TxOperationHeader.tsx
@@ -56,12 +56,15 @@ function _TxOperationHeader({
value={formattedValue}
className="text-xs tablet:text-sm font-mono"
prefix={field.label}
- linkProps={{
- as: NextLink,
- href:
- field?.hrefFactory?.(formattedValue) ??
- `/contract/${formattedValue}/assets`,
- }}
+ linkProps={
+ field.type === ReceiptHeaderOperationDataType.HEX_ADDRESS &&
+ field?.hrefFactory
+ ? {
+ as: NextLink,
+ href: field.hrefFactory(formattedValue),
+ }
+ : undefined
+ }
/>
) : (
`/account/${value}/assets`,
+ fieldFallback: 'to',
+ hrefFactory: Routes.accountAssets,
},
],
[GQLReceiptType.Transfer]: [
- { type: ReceiptHeaderOperationDataType.AMOUNT, field: 'amount' },
+ {
+ label: 'ID:',
+ type: ReceiptHeaderOperationDataType.HEX_ADDRESS,
+ field: 'id',
+ },
{
label: 'To:',
type: ReceiptHeaderOperationDataType.HEX_ADDRESS,
field: 'toAddress',
- hrefFactory: (value: string) => `/account/${value}/assets`,
+ fieldFallback: 'to',
+ hrefFactory: Routes.accountAssets,
},
],
[GQLReceiptType.MessageOut]: [
@@ -67,14 +81,14 @@ export const RECEIPT_FIELDS_MAP: Record<
type: ReceiptHeaderOperationDataType.HEX_ADDRESS,
field: 'sender',
requiredField: 'recipient',
- hrefFactory: (value: string) => `/account/${value}/assets`,
+ hrefFactory: Routes.accountAssets,
},
{
label: 'From:',
type: ReceiptHeaderOperationDataType.HEX_ADDRESS,
field: 'recipient',
requiredField: 'sender',
- hrefFactory: (value: string) => `/account/${value}/assets`,
+ hrefFactory: Routes.accountAssets,
},
],
[GQLReceiptType.Log]: [
@@ -91,6 +105,7 @@ export const RECEIPT_FIELDS_MAP: Record<
label: 'Contract ID:',
type: ReceiptHeaderOperationDataType.HEX_ADDRESS,
field: 'contractId',
+ hrefFactory: Routes.contractAssets,
},
],
[GQLReceiptType.Revert]: [
@@ -99,6 +114,7 @@ export const RECEIPT_FIELDS_MAP: Record<
label: 'Contract ID:',
type: ReceiptHeaderOperationDataType.HEX_ADDRESS,
field: 'contractId',
+ hrefFactory: Routes.contractAssets,
},
],
[GQLReceiptType.ReturnData]: [
diff --git a/packages/app-portal/src/systems/Ecosystem/components/EcosystemHeader/EcosystemHeader.tsx b/packages/app-portal/src/systems/Ecosystem/components/EcosystemHeader/EcosystemHeader.tsx
index 597535c7d..8d8d13ba7 100644
--- a/packages/app-portal/src/systems/Ecosystem/components/EcosystemHeader/EcosystemHeader.tsx
+++ b/packages/app-portal/src/systems/Ecosystem/components/EcosystemHeader/EcosystemHeader.tsx
@@ -1,4 +1,4 @@
-import { Button, Flex, Input, Separator } from '@fuels/ui';
+import { Button, Flex, Input, Separator, Switch, Text } from '@fuels/ui';
import { IconSearch } from '@tabler/icons-react';
import { PageTitle } from 'app-commons';
import { tv } from 'tailwind-variants';
@@ -7,10 +7,14 @@ export function EcosystemHeader({
disabled,
search,
onSearchChange,
+ onBuildingHiddenChange,
+ isBuildingHidden,
}: {
disabled?: boolean;
search?: string;
+ isBuildingHidden?: boolean;
onSearchChange?: (value: string) => void;
+ onBuildingHiddenChange?: (value: boolean) => void;
}) {
const classes = styles();
@@ -39,7 +43,16 @@ export function EcosystemHeader({
-
+
+