diff --git a/apps/dashboard/src/pages/search-pages/transaction/Overview.svelte b/apps/dashboard/src/pages/search-pages/transaction/Overview.svelte index e11a9da79..0c15c6363 100644 --- a/apps/dashboard/src/pages/search-pages/transaction/Overview.svelte +++ b/apps/dashboard/src/pages/search-pages/transaction/Overview.svelte @@ -5,14 +5,39 @@ import AwaitedRow from '@components/info-box/AwaitedRow.svelte' import AddressesList from '@components/_base/address/AddressesList.svelte' import { fullDateFormatter } from '@dashboard/lib/formatters/full-date' + import Accordion from '@components/_base/accordion/Accordion.svelte' + import Address from '@components/_base/address/Address.svelte' + import Row from '@components/info-box/Row.svelte' + import AcceptsStake from '@dashboard/lib/accepts-stake/AcceptsStake.svelte' + export let txId: string export let tx: Promise< | ReturnType< Awaited>['_unsafeUnwrap'] > | undefined > - export let manifest: Promise + + const subintentParentHash = ( + hash: string, + _subintents: NonNullable>>['subintents'] + ) => + _subintents.find(({ child_subintent_hashes }) => + child_subintent_hashes.includes(hash) + )?.subintent_hash ?? txId + + const subintentParentIndex = ( + hash: string, + _subintents: NonNullable>>['subintents'] + ) => + _subintents.findIndex(({ child_subintent_hashes }) => + child_subintent_hashes.includes(hash) + ) + + const subintentIndex = ( + hash: string, + _subintents: NonNullable>>['subintents'] + ) => _subintents.findIndex(({ subintent_hash }) => subintent_hash === hash)
@@ -84,16 +109,112 @@ {/if} - - + + {@const subintents = data?.subintents} + {@const rootChildIntents = data?.child_subintents} + +
+
+ +
+ + +
+ + + + + + {data?.message ?? 'N/A'} + + + + + + + + + + {#if subintents && rootChildIntents && rootChildIntents.length > 0} + +
+ {#each rootChildIntents as hash} + {@const index = subintentIndex(hash, subintents)} +
+
+ {`INDEX ${index}`} +
+
+ {/each} +
+
+ {/if} +
+
+
+
+ + {#if subintents && subintents.length > 0} + {#each subintents as { subintent_hash, manifest_instructions, child_subintent_hashes, message }, i} + {@const parent = subintentParentIndex(subintent_hash, subintents)} +
+
+ +
+ + +
+ + + + + + {message ?? 'N/A'} + + + + +
+
+ {parent >= 0 + ? `SUBINTENT INDEX ${parent}` + : 'ROOT INTENT'} +
+
+
+ + + + + + + + {#if child_subintent_hashes.length > 0} + +
+ {#each child_subintent_hashes as hash} + {@const index = subintentIndex(hash, subintents)} +
+
+ {index >= 0 ? `INDEX ${index}` : 'ROOT'} +
+
+ {/each} +
+
+ {/if} +
+
+
+
+ {/each} + {/if}
+ + diff --git a/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+layout.svelte b/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+layout.svelte new file mode 100644 index 000000000..537a05250 --- /dev/null +++ b/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+layout.svelte @@ -0,0 +1,15 @@ + + + + + diff --git a/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+layout.ts b/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+layout.ts new file mode 100644 index 000000000..4da01b9c4 --- /dev/null +++ b/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+layout.ts @@ -0,0 +1,21 @@ +import { gatewayApi } from '@api/gateway' +import type { LayoutLoad } from './$types' + +export const load: LayoutLoad = ({ params }) => { + const subintent = gatewayApi.transaction.innerClient + .transactionSubintentStatus({ + transactionSubintentStatusRequest: { + subintent_hash: params.subintent + } + }) + .then((response) => ({ + status: response.subintent_status, + description: response.subintent_status_description, + finalizedAt: response.finalized_at_transaction_intent_hash + })) + + return { + id: params.subintent, + subintent + } +} diff --git a/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+page.svelte b/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+page.svelte new file mode 100644 index 000000000..65a0ad328 --- /dev/null +++ b/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/+page.svelte @@ -0,0 +1,8 @@ + diff --git a/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/summary/+page.svelte b/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/summary/+page.svelte new file mode 100644 index 000000000..c6ef6377e --- /dev/null +++ b/apps/dashboard/src/routes/(search-pages)/subintent/[subintent]/summary/+page.svelte @@ -0,0 +1,96 @@ + + +
+
+
+
+ {#await data.subintent} + + {:then { status }} + {#if status === 'CommittedSuccess'} +

Finalized at:

+ {/if} + {/await} +
+ {#await data.subintent} + + {:then { status }} +
+
+ {#if status === 'CommittedSuccess'} + + {/if} + {status === 'CommittedSuccess' ? 'Success' : 'Unknown Status'} +
+
+ {/await} +
+
+ + {#await data.subintent then { finalizedAt }} + {#if finalizedAt} + + {/if} + {/await} +
+ + diff --git a/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/+layout.server.ts b/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/+layout.server.ts deleted file mode 100644 index dc9497650..000000000 --- a/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/+layout.server.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { getTransactionDetailsNew } from '@api/_deprecated/gateway' -import { CURRENT_NETWORK } from '../../../../../../../packages/ui/src/network' -import type { LayoutServerLoad } from './$types' -import { RadixEngineToolkit } from '@common/ret' - -export const load: LayoutServerLoad = ({ params }) => { - const details = getTransactionDetailsNew(params.transaction) - - let resolveManifest: (value?: string) => void - let manifest = new Promise( - (resolve) => (resolveManifest = resolve) - ) - - details.then((result) => { - if (result.isErr()) return undefined - - const tx = result.value - - tx.encodedManifest - ? RadixEngineToolkit.NotarizedTransaction.decompile( - Buffer.from(tx.encodedManifest, 'hex') - ) - .then((notarizedTx) => - RadixEngineToolkit.Instructions.convert( - notarizedTx.signedIntent.intent.manifest.instructions, - CURRENT_NETWORK.id, - 'String' - ) - ) - .then((instructions) => { - resolveManifest(instructions.value as string) - }) - : resolveManifest('') - }) - - return { - promises: { - manifest - } - } -} diff --git a/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/+layout.ts b/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/+layout.ts index ba2344d3c..047b9437a 100644 --- a/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/+layout.ts +++ b/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/+layout.ts @@ -13,7 +13,7 @@ import { getNftData } from '@api/_deprecated/utils/nft-data' import { pipe } from 'ramda' import { handleGatewayResult } from '../../../../utils' -export const load: LayoutLoad = ({ params, data }) => { +export const load: LayoutLoad = ({ params }) => { const details = getTransactionDetailsNew(params.transaction).unwrapOr( undefined ) @@ -204,8 +204,7 @@ export const load: LayoutLoad = ({ params, data }) => { promises: { tx: details, status, - balanceChanges, - manifest: data.promises.manifest + balanceChanges } } } diff --git a/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/details/+page.svelte b/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/details/+page.svelte index 5453ebe41..c4a023e6a 100644 --- a/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/details/+page.svelte +++ b/apps/dashboard/src/routes/(search-pages)/transaction/[transaction]/details/+page.svelte @@ -12,4 +12,4 @@ }) - + diff --git a/package-lock.json b/package-lock.json index adb5fbf1d..0445729fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8896,9 +8896,9 @@ "integrity": "sha512-BORxmE7j7jn+glNErr/d6n/focPGxYwie0a7G/0OUjjjUE/IlRjgnS5u2vh8mW3Sln7BiCg+UvXGoM1pV7fIsg==" }, "node_modules/@radixdlt/babylon-gateway-api-sdk": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@radixdlt/babylon-gateway-api-sdk/-/babylon-gateway-api-sdk-1.7.3.tgz", - "integrity": "sha512-wmdWX0AWCRSfKf6C3euiksJx9fpiGDN/8Hvmnw7PrHAY82k+CLaewWOL9P8pVD/s0mVXmReuOk9s3wJ5i+Nrxw==" + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@radixdlt/babylon-gateway-api-sdk/-/babylon-gateway-api-sdk-1.8.1.tgz", + "integrity": "sha512-MJHxl9zs2yOegnJsZLYFF04Iino6zbC//ms/rWNKadl9Ps3/nw+ceRmlEa7AJUIXcmIlm5jmKwkSvk791uJoEA==" }, "node_modules/@radixdlt/dapps-dropdown": { "version": "1.0.2", @@ -32224,7 +32224,7 @@ "dependencies": { "@floating-ui/dom": "^1.5.3", "@radixdlt/babylon-core-api-sdk": "^1.2.3", - "@radixdlt/babylon-gateway-api-sdk": "^1.7.3", + "@radixdlt/babylon-gateway-api-sdk": "^1.8.1", "@radixdlt/radix-dapp-toolkit": "^2.1.1", "@radixdlt/radix-engine-toolkit": "^1.0.5", "@radixdlt/rola": "^2.0.0", diff --git a/packages/common/package.json b/packages/common/package.json index 099539746..1dad50d6c 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -6,7 +6,7 @@ "dependencies": { "@floating-ui/dom": "^1.5.3", "@radixdlt/babylon-core-api-sdk": "^1.2.3", - "@radixdlt/babylon-gateway-api-sdk": "^1.7.3", + "@radixdlt/babylon-gateway-api-sdk": "^1.8.1", "@radixdlt/radix-dapp-toolkit": "^2.1.1", "@radixdlt/radix-engine-toolkit": "^1.0.5", "@radixdlt/rola": "^2.0.0", diff --git a/packages/ui/src/api/_deprecated/gateway.ts b/packages/ui/src/api/_deprecated/gateway.ts index c09ce5a4c..8d4bbbc30 100644 --- a/packages/ui/src/api/_deprecated/gateway.ts +++ b/packages/ui/src/api/_deprecated/gateway.ts @@ -12,7 +12,7 @@ import { StreamTransactionsRequestEventFilterItemEventEnum } from '@common/gateway-sdk' -const gatewayApi = GatewayApiClient.initialize({ +export const gatewayApi = GatewayApiClient.initialize({ applicationName: 'Radix Dashboard', basePath: CURRENT_NETWORK?.url }) @@ -233,26 +233,37 @@ export const getTransactionDetailsNew = ( intentHashHex: string, optIns?: Parameters[1] ) => { - return callApi('getCommittedDetails', intentHashHex, optIns).map((res) => ({ - epoch: res.transaction.epoch, - round: res.transaction.round, - status: res.transaction.transaction_status, - date: res.transaction.confirmed_at, - fee: res.transaction.fee_paid, - message: (res.transaction.message as any)?.content?.value, - encodedManifest: res.transaction.raw_hex, - receipt: res.transaction.receipt, - manifestClass: getMostRelevantManifestClass( - res.transaction.manifest_classes - ), - events: JSON.stringify(res.transaction.receipt?.events || '', null, 2), - affectedEntities: res.transaction.affected_global_entities || [], - createdEntities: - ((res.transaction.receipt?.state_updates as any) - ?.new_global_entities as any[]) || [], - stateVersion: res.transaction.state_version, - balanceChanges: res.transaction.balance_changes - })) + return callApi('getCommittedDetails', intentHashHex, optIns).map((res) => { + return { + epoch: res.transaction.epoch, + round: res.transaction.round, + status: res.transaction.transaction_status, + date: res.transaction.confirmed_at, + fee: res.transaction.fee_paid, + message: (res.transaction.message as any)?.content?.value, + encodedManifest: res.transaction.raw_hex, + receipt: res.transaction.receipt, + manifestClass: getMostRelevantManifestClass( + res.transaction.manifest_classes + ), + manifest: res.transaction.manifest_instructions, + subintents: (res.transaction as any).subintent_details as { + subintent_hash: string + manifest_instructions: string + child_subintent_hashes: string[] + message?: string + }[], + child_subintents: (res.transaction as any) + .child_subintent_hashes as string[], + events: JSON.stringify(res.transaction.receipt?.events || '', null, 2), + affectedEntities: res.transaction.affected_global_entities || [], + createdEntities: + ((res.transaction.receipt?.state_updates as any) + ?.new_global_entities as any[]) || [], + stateVersion: res.transaction.state_version, + balanceChanges: res.transaction.balance_changes + } + }) } export const getNetworkConfiguration = () => diff --git a/packages/ui/src/api/gateway.ts b/packages/ui/src/api/gateway.ts index 4bfd8e90c..408637c15 100644 --- a/packages/ui/src/api/gateway.ts +++ b/packages/ui/src/api/gateway.ts @@ -3,7 +3,7 @@ import { CURRENT_NETWORK } from '../../src/network' import { GatewayApiClient, type ErrorResponse } from '@common/gateway-sdk' import { cache } from './cache' -const gatewayApi = GatewayApiClient.initialize({ +export const gatewayApi = GatewayApiClient.initialize({ applicationName: 'Radix Dashboard', basePath: CURRENT_NETWORK?.url }) diff --git a/packages/ui/src/components/info-box/Row.svelte b/packages/ui/src/components/info-box/Row.svelte index cae831924..d43fb8b0e 100644 --- a/packages/ui/src/components/info-box/Row.svelte +++ b/packages/ui/src/components/info-box/Row.svelte @@ -48,18 +48,18 @@ justify-content: space-between; } - &.label-full { - flex-wrap: wrap; - .label { - width: 100%; - margin-bottom: 1rem; - } - } - &.no-capitalize { .label { text-transform: none; } } } + + .label-full { + flex-wrap: wrap; + .label { + width: 100%; + margin-bottom: 1rem; + } + } diff --git a/packages/ui/src/utils/index.ts b/packages/ui/src/utils/index.ts index 4a29f95c0..64a3efc62 100644 --- a/packages/ui/src/utils/index.ts +++ b/packages/ui/src/utils/index.ts @@ -112,7 +112,8 @@ export const addressToRoute = async (address: string) => txid: `/transaction/${encodeURIComponent(address)}`, validator: `/validator/${encodeURIComponent(address)}`, identity: `/identity/${encodeURIComponent(address)}`, - pool: `/pool/${encodeURIComponent(address)}` + pool: `/pool/${encodeURIComponent(address)}`, + subtxid: `/subintent/${encodeURIComponent(address)}` }[getAddressPrefix(address)] ?? `/component/${encodeURIComponent(address)}`) export const useContext = <