NFT Transfers
-
-
@@ -60,7 +58,7 @@
@@ -95,9 +93,6 @@
-
-
-
None
diff --git a/src/components/transfer_graphs/RewardTransferGraph.vue b/src/components/transfer_graphs/RewardTransferGraph.vue
new file mode 100644
index 000000000..57c31d554
--- /dev/null
+++ b/src/components/transfer_graphs/RewardTransferGraph.vue
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+
+
Staking Rewards
+
+
+
+
+ Reward Account
+
+ Account
+ Amount Rewarded
+
+
+
+
+ Account
+
+ Account
+ Amount Rewarded
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/transfer_graphs/TokenTransferGraphC.vue b/src/components/transfer_graphs/TokenTransferGraphC.vue
index 934994862..46811cac2 100644
--- a/src/components/transfer_graphs/TokenTransferGraphC.vue
+++ b/src/components/transfer_graphs/TokenTransferGraphC.vue
@@ -24,9 +24,7 @@
-
-
-
+
@@ -54,7 +52,7 @@
@@ -83,8 +81,6 @@
-
-
diff --git a/src/components/transfer_graphs/TokenTransferGraphF.vue b/src/components/transfer_graphs/TokenTransferGraphF.vue
index c1e5bb3eb..85636606e 100644
--- a/src/components/transfer_graphs/TokenTransferGraphF.vue
+++ b/src/components/transfer_graphs/TokenTransferGraphF.vue
@@ -24,11 +24,9 @@
-
+
Token Transfers
-
-
@@ -64,14 +62,14 @@
+ v-bind:token-id="tokenTransferLayout[s-1].tokenId ?? undefined"/>
@@ -97,7 +95,7 @@
+ v-bind:token-id="tokenTransferLayout[s-1].tokenId ?? undefined"/>
@@ -105,7 +103,7 @@
@@ -123,10 +121,6 @@
-
-
-
-
None
diff --git a/src/components/transfer_graphs/TransferGraphSection.vue b/src/components/transfer_graphs/TransferGraphSection.vue
index 2b12fa8e9..6d28dc360 100644
--- a/src/components/transfer_graphs/TransferGraphSection.vue
+++ b/src/components/transfer_graphs/TransferGraphSection.vue
@@ -24,42 +24,38 @@
-
-
+
-
-
-
+
-
-
-
-
+
@@ -77,10 +73,12 @@ import NftTransferGraph from "@/components/transfer_graphs/NftTransferGraph.vue"
import TokenTransferGraphC from "@/components/transfer_graphs/TokenTransferGraphC.vue";
import TokenTransferGraphF from "@/components/transfer_graphs/TokenTransferGraphF.vue";
import {computeNetAmount} from "@/utils/TransactionTools";
+import RewardTransferGraph from "@/components/transfer_graphs/RewardTransferGraph.vue";
export default defineComponent({
name: "TransferGraphSection",
components: {
+ RewardTransferGraph,
NftTransferGraph,
TokenTransferGraphC,
TokenTransferGraphF,
@@ -97,11 +95,18 @@ export default defineComponent({
setup(props) {
const netAmount = computed(() => {
- return props.transaction ? computeNetAmount(props.transaction) : 0
+ return props.transaction ? computeNetAmount(props.transaction.transfers, props.transaction.charged_tx_fee) : 0
})
+ const displayRewardTransfers = computed(() => props.transaction?.staking_reward_transfers && props.transaction?.staking_reward_transfers.length >= 1)
+ const displayNftTransfers = computed(() => props.transaction?.nft_transfers && props.transaction?.nft_transfers.length >= 1)
+ const displayTokenTransfers = computed(() => props.transaction?.token_transfers && props.transaction?.token_transfers.length >= 1)
+
return {
netAmount,
+ displayRewardTransfers,
+ displayNftTransfers,
+ displayTokenTransfers
}
}
})
diff --git a/src/components/transfer_graphs/layout/HbarTransferLayout.ts b/src/components/transfer_graphs/layout/HbarTransferLayout.ts
index 9fd97a2a3..88b6d6044 100644
--- a/src/components/transfer_graphs/layout/HbarTransferLayout.ts
+++ b/src/components/transfer_graphs/layout/HbarTransferLayout.ts
@@ -20,7 +20,7 @@
import {compareTransferByAccount, NetworkNode, Transaction, Transfer} from "@/schemas/HederaSchemas";
import {isFeeTransfer, makeOperatorDescription} from "@/schemas/HederaUtils";
-import {computeNetAmount} from "@/utils/TransactionTools";
+import {computeNetAmount, makeNetOfRewards} from "@/utils/TransactionTools";
export class HbarTransferLayout {
@@ -39,11 +39,14 @@ export class HbarTransferLayout {
this.transaction = transaction
this.nodes = nodes
+ let transfersNetOfRewards = Array()
if (this.transaction?.transfers) {
+ transfersNetOfRewards = makeNetOfRewards(this.transaction.transfers, this.transaction.staking_reward_transfers)
+
const negativeTransfers = new Array()
const positiveTransfers = new Array()
- for (const t of this.transaction.transfers) {
+ for (const t of transfersNetOfRewards) {
if (t.amount < 0) {
negativeTransfers.push(t)
} else {
@@ -59,13 +62,13 @@ export class HbarTransferLayout {
}
for (const t of positiveTransfers) {
const isFee = isFeeTransfer(t, this.nodes)
- const operator = t.account ? makeOperatorDescription(t.account, this.nodes) : null
+ const operator = t.account ? makeOperatorDescription(t.account, this.nodes, isFee) : null
this.destinations.push(new HbarTransferRow(t, operator ?? "Transfer", !isFee))
}
}
// Makes sure net amount is distributed across payload transfers
- let remaining = this.transaction ? computeNetAmount(this.transaction) : 0
+ let remaining = this.transaction ? computeNetAmount(transfersNetOfRewards, this.transaction.charged_tx_fee) : 0
// First we remove amount from payload transfers
for (const r of this.destinations) {
if (r.payload) {
@@ -85,7 +88,11 @@ export class HbarTransferLayout {
this.destinations.splice(i, 1)
// Inserts two new transfers
const payloadTransfer = { ... r.transfer } ; payloadTransfer.amount = payloadAmount
- const payloadRow = new HbarTransferRow(payloadTransfer, replacedTransfer.description, true)
+ const payloadRow =
+ new HbarTransferRow(
+ payloadTransfer,
+ makeOperatorDescription(replacedTransfer.transfer.account ?? "", this.nodes, false),
+ true)
this.destinations.splice(i, 0, payloadRow)
if (feeAmount > 0) {
const feeTransfer = { ... r.transfer } ; feeTransfer.amount = feeAmount
diff --git a/src/components/transfer_graphs/layout/RewardTransferLayout.ts b/src/components/transfer_graphs/layout/RewardTransferLayout.ts
new file mode 100644
index 000000000..c645a05a6
--- /dev/null
+++ b/src/components/transfer_graphs/layout/RewardTransferLayout.ts
@@ -0,0 +1,50 @@
+/*-
+ *
+ * Hedera Mirror Node Explorer
+ *
+ * Copyright (C) 2021 - 2023 Hedera Hashgraph, LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import {
+ compareTransferByAccount,
+ StakingRewardTransfer,
+ Transaction,
+} from "@/schemas/HederaSchemas";
+
+export class RewardTransferLayout {
+
+ public readonly transaction: Transaction|undefined
+ public readonly destinations = Array()
+ public readonly rewardAmount: number
+
+ //
+ // Public
+ //
+
+ public constructor(transaction: Transaction|undefined) {
+
+ this.transaction = transaction
+ this.rewardAmount = 0
+
+ if (this.transaction?.staking_reward_transfers) {
+ for (const t of this.transaction.staking_reward_transfers) {
+ this.destinations.push(t)
+ this.rewardAmount += t.amount
+ }
+ this.destinations.sort(compareTransferByAccount)
+ }
+ }
+}
diff --git a/src/pages/TransactionDetails.vue b/src/pages/TransactionDetails.vue
index 6f7a485a3..02e1cb723 100644
--- a/src/pages/TransactionDetails.vue
+++ b/src/pages/TransactionDetails.vue
@@ -211,7 +211,7 @@
-
+
Transfers
@@ -324,6 +324,11 @@ export default defineComponent({
return transactionGroupAnalyzer.childTransactions.value.length > MAX_INLINE_CHILDREN
})
+ const displayTransfers = computed(() =>
+ (transactionDetail.value?.transfers && transactionDetail.value.transfers.length > 0)
+ || (transactionDetail.value?.token_transfers && transactionDetail.value.token_transfers.length > 0)
+ || (transactionDetail.value?.nft_transfers && transactionDetail.value.nft_transfers.length > 0)
+ )
const routeName = computed(() => {
return transactionAnalyzer.entityDescriptor.value?.routeName
@@ -436,6 +441,7 @@ export default defineComponent({
makeOperatorAccountLabel,
routeToAllTransactions,
displayAllChildrenLinks,
+ displayTransfers,
topicMessage: topicMessageLookup.entity,
isTokenAssociation: transactionAnalyzer.isTokenAssociation,
associatedTokens: transactionAnalyzer.tokens
diff --git a/src/schemas/HederaSchemas.ts b/src/schemas/HederaSchemas.ts
index c03c5310a..7e7632064 100644
--- a/src/schemas/HederaSchemas.ts
+++ b/src/schemas/HederaSchemas.ts
@@ -149,7 +149,7 @@ export interface Transaction {
parent_consensus_timestamp: string | null | undefined
result: string | undefined
scheduled: boolean | undefined
- // staking_reward_transfers: ...
+ staking_reward_transfers: StakingRewardTransfer[] | undefined
token_transfers: TokenTransfer[] | undefined
transaction_hash: string | undefined
transaction_id: string | undefined
@@ -203,6 +203,11 @@ export interface TokenTransfer extends Transfer {
token_id: string | null // Network entity ID in the format of shard.realm.num
}
+export interface StakingRewardTransfer {
+ account: string | null // Network entity ID in the format of shard.realm.num
+ amount: number
+}
+
export interface CustomFee {
amount: number | undefined
collector_account_id: string | undefined // Network entity ID in the format of shard.realm.num
@@ -263,7 +268,7 @@ export enum TransactionResult {
FAILURE = "fail"
}
-export function compareTransferByAccount(t1: Transfer, t2: Transfer): number {
+export function compareTransferByAccount(t1: Transfer | StakingRewardTransfer, t2: Transfer | StakingRewardTransfer): number {
let result: number
const account1 = t1.account
const account2 = t2.account
diff --git a/src/schemas/HederaUtils.ts b/src/schemas/HederaUtils.ts
index 1aef9e8e0..623c17ed9 100644
--- a/src/schemas/HederaUtils.ts
+++ b/src/schemas/HederaUtils.ts
@@ -85,7 +85,7 @@ export function makeNodeDescriptionPrefix(node: NetworkNode): string {
return result
}
-export function makeNodeOwnerDescription(node: NetworkNode): string {
+export function makeNodeOwnerDescription(node: NetworkNode, short= false): string {
const description = makeNodeDescription(node)
let result: string
if (description?.slice(0, 9).toLowerCase() === "hosted by") {
@@ -95,20 +95,24 @@ export function makeNodeOwnerDescription(node: NetworkNode): string {
} else {
result = description
}
- return result
+ return short ? result.split('|')[0].trimEnd() : result
}
export function makeDefaultNodeDescription(nodeId: number | null): string {
return "Node " + nodeId ?? "?"
}
-export function makeOperatorDescription(accountId: string, nodes: NetworkNode[]): string | null {
+export function makeOperatorDescription(accountId: string, nodes: NetworkNode[], isFee=false): string | null {
let result: string|null
if (accountId === "0.0.98") {
result = "Hedera fee collection account"
+ } else if(accountId === "0.0.800") {
+ result = isFee ? "Staking reward account fee" : "Staking reward account"
} else {
const node = lookupNodeByAccountId(accountId, nodes)
- result = node !== null ? makeNodeDescription(node) : null
+ result = node !== null
+ ? isFee ? `Node fee (${makeNodeOwnerDescription(node, true)})` : makeNodeDescription(node)
+ : null
}
return result
}
diff --git a/src/utils/EntityID.ts b/src/utils/EntityID.ts
index 350d6aae4..9fff5c839 100644
--- a/src/utils/EntityID.ts
+++ b/src/utils/EntityID.ts
@@ -124,10 +124,10 @@ export class EntityID {
result = compareNumber(this.realm, that.realm)
}
if (result == 0) {
- if (this.num < 100 && that.num >= 100) {
+ if ((this.num < 100 || this.num === 800) && (that.num >= 100 && that.num !== 800)) {
// We put this.num at the end
result = +1
- } else if (that.num < 100 && this.num >= 100) {
+ } else if ((that.num < 100 || that.num === 800) && (this.num >= 100 && this.num != 800)) {
// We put that.num at the end
result = -1
} else {
diff --git a/src/utils/TransactionTools.ts b/src/utils/TransactionTools.ts
index 12746e074..c32faef64 100644
--- a/src/utils/TransactionTools.ts
+++ b/src/utils/TransactionTools.ts
@@ -18,7 +18,7 @@
*
*/
-import {Transaction, TransactionType} from "@/schemas/HederaSchemas";
+import {StakingRewardTransfer, Transaction, TransactionType, Transfer} from "@/schemas/HederaSchemas";
import {TransactionID} from "@/utils/TransactionID";
export function makeSummaryLabel(row: Transaction): string {
@@ -27,7 +27,7 @@ export function makeSummaryLabel(row: Transaction): string {
switch (row.name) {
case TransactionType.CRYPTOTRANSFER:
- netAmount = computeNetAmount(row);
+ netAmount = computeNetAmount(row.transfers, row.charged_tx_fee);
result = makeTransferLabel(row, netAmount)
break
case TransactionType.CONSENSUSCREATETOPIC:
@@ -136,7 +136,7 @@ function makeTransferLabel(row: Transaction, netAmount: number): string {
export function showPositiveNetAmount(row: Transaction): boolean {
let result: boolean
- const netAmount = computeNetAmount(row)
+ const netAmount = computeNetAmount(row.transfers, row.charged_tx_fee)
switch (row.name) {
case TransactionType.CRYPTOTRANSFER:
result = true
@@ -327,15 +327,53 @@ function formatMemo(memo64: string): string {
return result
}
-export function computeNetAmount(row: Transaction): number {
+export function computeNetAmount(transfers: Transfer[] | undefined, transactionFee: number | undefined): number {
let result = 0
- if (row.transfers !== undefined) {
- for (const t of row.transfers) {
+ if (transfers !== undefined) {
+ for (const t of transfers) {
if (t.amount > 0) {
result += t.amount
}
}
}
- result -= row.charged_tx_fee ?? 0
+ result -= transactionFee ?? 0
+ return result
+}
+
+export function makeNetOfRewards(transfers: Transfer[] | undefined, rewards: StakingRewardTransfer[] | undefined): Transfer[] {
+ let result = Array()
+ let totalRewardAmount = 0
+
+ if (transfers && rewards && transfers.length > 0 && rewards.length > 0) {
+ for (const r of rewards) {
+ totalRewardAmount += r.amount
+ }
+ let netAmount: number
+ for (const t of transfers) {
+ if (t.account === "0.0.800") {
+ netAmount = t.amount + totalRewardAmount
+ } else {
+ netAmount = t.amount
+ for (const r of rewards) {
+ if (t.account == r.account) {
+ if (t.amount < 0) {
+ netAmount = t.amount + r.amount
+ } else {
+ netAmount = t.amount - r.amount
+ }
+ break
+ }
+ }
+ }
+ result.push({
+ amount: netAmount,
+ account: t.account,
+ is_approval: t.is_approval
+ })
+ }
+ } else {
+ result = transfers ?? []
+ }
+
return result
}
diff --git a/tests/e2e/specs/TransferGraphs.cy.ts b/tests/e2e/specs/TransferGraphs.cy.ts
index 14a8c517b..f4044eea7 100644
--- a/tests/e2e/specs/TransferGraphs.cy.ts
+++ b/tests/e2e/specs/TransferGraphs.cy.ts
@@ -122,7 +122,7 @@ describe('Transfer Graphs Navigation', () => {
.then(($account) => {
cy.wrap($account)
.find('a')
- .click()
+ .click({force: true})
cy.url().should('include', '/mainnet/account/' + $account.text())
cy.contains('Account ID:' + $account.text())
})
@@ -135,7 +135,7 @@ describe('Transfer Graphs Navigation', () => {
.then(($token) => {
cy.wrap($token)
.find('a')
- .click()
+ .click({force: true})
.then(($name) => {
cy.url().should('include', '/mainnet/token/')
cy.contains('Token ')
@@ -151,7 +151,7 @@ describe('Transfer Graphs Navigation', () => {
.then(($token) => {
cy.wrap($token)
.find('a')
- .click()
+ .click({force: true})
.then(($name) => {
cy.url().should('include', '/mainnet/token/')
cy.contains('Token ')
@@ -166,7 +166,7 @@ describe('Transfer Graphs Navigation', () => {
.then(($account) => {
cy.wrap($account)
.find('a')
- .click()
+ .click({force: true})
cy.url().should('include', '/mainnet/account/' + $account.text())
cy.contains('Account ID:' + $account.text())
})
diff --git a/tests/unit/Mocks.ts b/tests/unit/Mocks.ts
index d916c3afa..b024dfb25 100644
--- a/tests/unit/Mocks.ts
+++ b/tests/unit/Mocks.ts
@@ -693,6 +693,74 @@ export const SAMPLE_SYSTEM_CONTRACT_CALL_TRANSACTIONS = {
]
}
+export const SAMPLE_CRYPTO_TRANSFER_WITH_ONLY_FEE = {
+ "bytes": null,
+ "charged_tx_fee": 26494683,
+ "consensus_timestamp": "1687197609.495612761",
+ "entity_id": "0.0.3005010",
+ "max_fee": "200000000",
+ "memo_base64": "",
+ "name": "CONSENSUSCREATETOPIC",
+ "node": "0.0.25",
+ "nonce": 0,
+ "parent_consensus_timestamp": null,
+ "result": "SUCCESS",
+ "scheduled": false,
+ "transaction_hash": "c2sSCuCRNOI6gvCYs5KFxe7Z60TV8vJXxuOWNEtH4doYj0MnruIi3NLFXIX6e8s1",
+ "transaction_id": "0.0.1786365-1687197599-390469131",
+ "transfers": [{"account": "0.0.25", "amount": 1190235, "is_approval": false}, {
+ "account": "0.0.98",
+ "amount": 22774004,
+ "is_approval": false
+ }, {"account": "0.0.800", "amount": 2530444, "is_approval": false}, {
+ "account": "0.0.1786365",
+ "amount": -26494683,
+ "is_approval": false
+ }],
+ "valid_duration_seconds": "120",
+ "valid_start_timestamp": "1687197599.390469131"
+}
+
+export const SAMPLE_CRYPTO_TRANSFER_WITH_REWARDS = {
+ "bytes": null,
+ "charged_tx_fee": 5351935,
+ "consensus_timestamp": "1687133236.139653690",
+ "entity_id": null,
+ "max_fee": "100000000",
+ "memo_base64": "KDAuMC4yOTk4NTU1KUNvbmZpcm0gcHVyY2hhc2Ugb2YgTkZUOiAwLjAuMjE3Mzg5OSB3aXRoIHNlcmlhbCBudW1iZXIgMTYxMiBmb3IgMjUgSEJBUg==",
+ "name": "CRYPTOTRANSFER",
+ "node": "0.0.4",
+ "nonce": 0,
+ "parent_consensus_timestamp": null,
+ "result": "SUCCESS",
+ "scheduled": false,
+ "staking_reward_transfers": [{"account": "0.0.788887", "amount": 210704256}, {
+ "account": "0.0.2254995",
+ "amount": 2289378672
+ }],
+ "transaction_hash": "9s/JADOEqzUy4yzZA0StoTfumGL0bAALPs9tKbE/ELX0AY6gkbTl4potlyd3XHeU",
+ "transaction_id": "0.0.690356-1687133220-052118241",
+ "transfers": [{"account": "0.0.4", "amount": 206713, "is_approval": false}, {
+ "account": "0.0.98",
+ "amount": 4630700,
+ "is_approval": false
+ }, {"account": "0.0.800", "amount": -2499568406, "is_approval": false}, {
+ "account": "0.0.690356",
+ "amount": -5351935,
+ "is_approval": false
+ }, {"account": "0.0.755188", "amount": 2280000000, "is_approval": false}, {
+ "account": "0.0.788887",
+ "amount": 330704256,
+ "is_approval": false
+ }, {"account": "0.0.2254995", "amount": 2389378672, "is_approval": false}, {
+ "account": "0.0.2998555",
+ "amount": -2500000000,
+ "is_approval": false
+ }],
+ "valid_duration_seconds": "120",
+ "valid_start_timestamp": "1687133220.052118241"
+}
+
export const SAMPLE_TOKEN_CALL_TRANSACTIONS = {
"transactions": [{
"bytes": null,
diff --git a/tests/unit/transaction/TransactionDetails.spec.ts b/tests/unit/transaction/TransactionDetails.spec.ts
index 0087449ed..2994a6dc9 100644
--- a/tests/unit/transaction/TransactionDetails.spec.ts
+++ b/tests/unit/transaction/TransactionDetails.spec.ts
@@ -78,7 +78,7 @@ describe("TransactionDetails.vue", () => {
const matcher3 = "api/v1/network/nodes"
mock.onGet(matcher3).reply(200, SAMPLE_NETWORK_NODES);
- it("Should display transaction details with token transfers and fee transfers", async () => {
+ it("Should display transaction details with token transfers and hbar transfers", async () => {
await router.push("/") // To avoid "missing required param 'network'" error
@@ -131,16 +131,15 @@ describe("TransactionDetails.vue", () => {
expect(wrapper.findComponent(NftTransferGraph).exists()).toBe(true)
expect(wrapper.findComponent(HbarTransferGraphF).text()).toBe(
- "Fee TransfersAccountHbar AmountAccountHbar Amount0.0.29624024-0.00470065-$0.00116\n\n" +
- "0.0.40.00022028$0.00005Hosted by Hedera | East Coast, USA\n\n" +
+ "Hbar TransfersAccountHbar AmountAccountHbar Amount0.0.29624024-0.00470065-$0.00116\n\n" +
+ "0.0.40.00022028$0.00005Node fee (Hedera)\n\n" +
"0.0.980.00448037$0.00110Hedera fee collection account")
expect(wrapper.findComponent(TokenTransferGraph).text()).toBe(
"Token TransfersAccountToken AmountAccountToken Amount0.0.29624024-123423\n\n" +
"0.0.29693911123423Transfer")
- expect(wrapper.findComponent(NftTransferGraph).text()).toBe(
- "NFT TransfersNone")
+ expect(wrapper.findComponent(NftTransferGraph).text()).toBe("")
wrapper.unmount()
await flushPromises()
@@ -337,7 +336,7 @@ describe("TransactionDetails.vue", () => {
expect(wrapper.findComponent(HbarTransferGraphF).exists()).toBe(true)
expect(wrapper.findComponent(TokenTransferGraph).exists()).toBe(true)
- expect(wrapper.findComponent(NftTransferGraph).text()).toContain("NFT TransfersNone")
+ expect(wrapper.findComponent(NftTransferGraph).text()).toBe("")
const transaction = SAMPLE_CONTRACTCALL_TRANSACTIONS.transactions[0]
matcher1 = "/api/v1/transactions"
@@ -369,8 +368,8 @@ describe("TransactionDetails.vue", () => {
expect(wrapper.get('#entityIdValue').text()).toBe(entityId)
expect(wrapper.findComponent(HbarTransferGraphF).exists()).toBe(true)
- expect(wrapper.findComponent(TokenTransferGraph).text()).toContain("Token TransfersNone")
- expect(wrapper.findComponent(NftTransferGraph).text()).toContain("NFT TransfersNone")
+ expect(wrapper.findComponent(TokenTransferGraph).text()).toBe("")
+ expect(wrapper.findComponent(NftTransferGraph).text()).toBe("")
wrapper.unmount()
await flushPromises()
@@ -745,11 +744,11 @@ describe("TransactionDetails.vue", () => {
expect(wrapper.findComponent(TokenTransferGraph).exists()).toBe(true)
expect(wrapper.findComponent(NftTransferGraph).exists()).toBe(true)
- expect(wrapper.findComponent(HbarTransferGraphF).text()).toBe("Fee TransfersAccountHbar AmountAccountHbar Amount0.0.642949-1.15905210-$0.28517\n\n" +
- "0.0.30.05805847$0.01428Hosted by Hedera | East Coast, USA\n\n" +
+ expect(wrapper.findComponent(HbarTransferGraphF).text()).toBe("Hbar TransfersAccountHbar AmountAccountHbar Amount0.0.642949-1.15905210-$0.28517\n\n" +
+ "0.0.30.05805847$0.01428Node fee (Hedera)\n\n" +
"0.0.981.10099363$0.27088Hedera fee collection account")
- expect(wrapper.findComponent(TokenTransferGraph).text()).toBe("Token TransfersNone")
- expect(wrapper.findComponent(NftTransferGraph).text()).toBe("NFT TransfersNone")
+ expect(wrapper.findComponent(TokenTransferGraph).text()).toBe("")
+ expect(wrapper.findComponent(NftTransferGraph).text()).toBe("")
wrapper.unmount()
await flushPromises()
diff --git a/tests/unit/transfer_graphs/NftTransferGraph.spec.ts b/tests/unit/transfer_graphs/NftTransferGraph.spec.ts
index 4125ab2c9..2b0fd0bce 100644
--- a/tests/unit/transfer_graphs/NftTransferGraph.spec.ts
+++ b/tests/unit/transfer_graphs/NftTransferGraph.spec.ts
@@ -51,7 +51,7 @@ describe("NftTransferGraph.vue", () => {
// console.log(wrapper.html())
// console.log(wrapper.text())
- expect(wrapper.text()).toBe("NFT TransfersNone")
+ expect(wrapper.text()).toBe("")
wrapper.unmount()
await flushPromises()
diff --git a/tests/unit/transfer_graphs/RewardTransferGraph.spec.ts b/tests/unit/transfer_graphs/RewardTransferGraph.spec.ts
new file mode 100644
index 000000000..f7152fedc
--- /dev/null
+++ b/tests/unit/transfer_graphs/RewardTransferGraph.spec.ts
@@ -0,0 +1,112 @@
+/*-
+ *
+ * Hedera Mirror Node Explorer
+ *
+ * Copyright (C) 2021 - 2023 Hedera Hashgraph, LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import router from "@/router";
+import {flushPromises, mount} from "@vue/test-utils";
+import {Transaction, TransactionDetail} from "@/schemas/HederaSchemas";
+import RewardTransferGraph from "@/components/transfer_graphs/RewardTransferGraph.vue";
+import {SAMPLE_CRYPTO_TRANSFER_WITH_ONLY_FEE, SAMPLE_CRYPTO_TRANSFER_WITH_REWARDS} from "../Mocks";
+
+describe("RewardTransferGraph.vue", () => {
+
+ test("Without transaction prop", async () => {
+
+ await router.push("/") // To avoid "missing required param 'network'" error
+
+ const wrapper = mount(RewardTransferGraph, {
+ global: {
+ plugins: [router]
+ },
+ props: {
+ },
+ })
+
+ await flushPromises()
+
+ // console.log(wrapper.html())
+ // console.log(wrapper.text())
+
+ expect(wrapper.text()).toBe("")
+
+ wrapper.unmount()
+ await flushPromises()
+ })
+
+ test("with transfers and no rewards", async () => {
+
+ await router.push("/") // To avoid "missing required param 'network'" error
+
+ const wrapper = mount(RewardTransferGraph, {
+ global: {
+ plugins: [router]
+ },
+ props: {
+ transaction: SAMPLE_CRYPTO_TRANSFER_WITH_ONLY_FEE as Transaction,
+ },
+ })
+
+ await flushPromises()
+
+ // console.log(wrapper.html())
+ // console.log(wrapper.text())
+
+ expect(wrapper.text()).toBe("")
+
+ wrapper.unmount()
+ })
+
+ test("with multiple transfers and rewards", async () => {
+
+ await router.push("/") // To avoid "missing required param 'network'" error
+
+ const wrapper = mount(RewardTransferGraph, {
+ global: {
+ plugins: [router]
+ },
+ props: {
+ transaction: SAMPLE_CRYPTO_TRANSFER_WITH_REWARDS as TransactionDetail,
+
+ },
+ })
+
+ await flushPromises()
+
+ // console.log(wrapper.html())
+ // console.log(wrapper.text())
+
+ /*
+ 0.0.800 -> 0.0.788887 2.10704256
+ -> 0.0.2254995 22.89378672
+ */
+
+ expect(wrapper.text()).toBe(
+ "Staking Rewards" +
+ "Reward AccountAccountAmount Rewarded" +
+ "0.0.800\n\n" +
+ "0.0.788887" +
+ "2.10704256\n\n" +
+ "0.0.2254995" +
+ "22.89378672")
+
+ wrapper.unmount()
+ })
+
+})
+
diff --git a/tests/unit/transfer_graphs/TokenTransferGraphF.spec.ts b/tests/unit/transfer_graphs/TokenTransferGraphF.spec.ts
index b62ae8d6a..75d4ffba1 100644
--- a/tests/unit/transfer_graphs/TokenTransferGraphF.spec.ts
+++ b/tests/unit/transfer_graphs/TokenTransferGraphF.spec.ts
@@ -52,7 +52,7 @@ describe("TokenTransferGraphF.vue", () => {
// console.log(wrapper.html())
// console.log(wrapper.text())
- expect(wrapper.text()).toBe("Token TransfersNone")
+ expect(wrapper.text()).toBe("")
wrapper.unmount()
await flushPromises()
diff --git a/tests/unit/transfer_graphs/layout/HbarTransferLayout.spec.ts b/tests/unit/transfer_graphs/layout/HbarTransferLayout.spec.ts
index bf7209cc6..e4cc9178e 100644
--- a/tests/unit/transfer_graphs/layout/HbarTransferLayout.spec.ts
+++ b/tests/unit/transfer_graphs/layout/HbarTransferLayout.spec.ts
@@ -69,7 +69,7 @@ describe("HbarTransferLayout.vue", () => {
const d0 = fullLayout.destinations[0]
expect(d0.transfer.account).toBe("0.0.5")
expect(d0.transfer.amount).toBe(+3)
- expect(d0.description).toBe("Hosted by Hedera | Central, USA")
+ expect(d0.description).toBe("Node fee (Hedera)")
expect(d0.payload).toBe(false)
const d1 = fullLayout.destinations[1]
@@ -131,7 +131,7 @@ describe("HbarTransferLayout.vue", () => {
const fd1 = fullLayout.destinations[1]
expect(fd1.transfer.account).toBe("0.0.5")
expect(fd1.transfer.amount).toBe(+3)
- expect(fd1.description).toBe("Hosted by Hedera | Central, USA")
+ expect(fd1.description).toBe("Node fee (Hedera)")
expect(fd1.payload).toBe(false)
const fd2 = fullLayout.destinations[2]
@@ -211,7 +211,7 @@ describe("HbarTransferLayout.vue", () => {
const d2 = fullLayout.destinations[2]
expect(d2.transfer.account).toBe("0.0.5")
expect(d2.transfer.amount).toBe(+3)
- expect(d2.description).toBe("Hosted by Hedera | Central, USA")
+ expect(d2.description).toBe("Node fee (Hedera)")
expect(d2.payload).toBe(false)
const d3 = fullLayout.destinations[3]
@@ -295,7 +295,7 @@ describe("HbarTransferLayout.vue", () => {
const d0 = fullLayout.destinations[0]
expect(d0.transfer.account).toBe("0.0.5")
expect(d0.transfer.amount).toBe(+3)
- expect(d0.description).toBe("Hosted by Hedera | Central, USA")
+ expect(d0.description).toBe("Node fee (Hedera)")
expect(d0.payload).toBe(false)
const d1 = fullLayout.destinations[1]
@@ -365,7 +365,7 @@ describe("HbarTransferLayout.vue", () => {
const d1 = fullLayout.destinations[1]
expect(d1.transfer.account).toBe("0.0.5")
expect(d1.transfer.amount).toBe(+3)
- expect(d1.description).toBe("Hosted by Hedera | Central, USA")
+ expect(d1.description).toBe("Node fee (Hedera)")
expect(d1.payload).toBe(false)
const d2 = fullLayout.destinations[2]
@@ -458,7 +458,7 @@ describe("HbarTransferLayout.vue", () => {
const d2 = fullLayout.destinations[2]
expect(d2.transfer.account).toBe("0.0.5")
expect(d2.transfer.amount).toBe(+3)
- expect(d2.description).toBe("Hosted by Hedera | Central, USA")
+ expect(d2.description).toBe("Node fee (Hedera)")
expect(d2.payload).toBe(false)
const d3 = fullLayout.destinations[3]
@@ -547,7 +547,7 @@ describe("HbarTransferLayout.vue", () => {
const d1 = fullLayout.destinations[1]
expect(d1.transfer.account).toBe("0.0.5")
expect(d1.transfer.amount).toBe(+1)
- expect(d1.description).toBe("Hosted by Hedera | Central, USA")
+ expect(d1.description).toBe("Node fee (Hedera)")
expect(d1.payload).toBe(false)
const d2 = fullLayout.destinations[2]