diff --git a/src/RadixDlt.CoreApiSdk/Model/CreatedSubstate.cs b/src/RadixDlt.CoreApiSdk/Model/CreatedSubstate.cs new file mode 100644 index 000000000..e60a0aada --- /dev/null +++ b/src/RadixDlt.CoreApiSdk/Model/CreatedSubstate.cs @@ -0,0 +1,72 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +using System.Diagnostics.CodeAnalysis; + +namespace RadixDlt.CoreApiSdk.Model; + +public partial class CreatedSubstate : IUpsertedSubstate +{ + public SubstateValue PreviousValue => null; +} diff --git a/src/RadixDlt.CoreApiSdk/Model/Interfaces.cs b/src/RadixDlt.CoreApiSdk/Model/Interfaces.cs index f0802b240..8ad89be58 100644 --- a/src/RadixDlt.CoreApiSdk/Model/Interfaces.cs +++ b/src/RadixDlt.CoreApiSdk/Model/Interfaces.cs @@ -81,3 +81,18 @@ public interface IEntityAddressPointer { public IEnumerable GetEntityAddresses(); } + +public interface IUpsertedSubstate +{ + public SubstateId SubstateId { get; } + + public SubstateValue Value { get; } + + public SubstateValue PreviousValue { get; } + + [MemberNotNullWhen(true, nameof(Value))] + public bool HasValue => Value != null; + + [MemberNotNullWhen(true, nameof(PreviousValue))] + public bool HasPreviousValue => PreviousValue != null; +} diff --git a/src/RadixDlt.CoreApiSdk/Model/StateUpdates.cs b/src/RadixDlt.CoreApiSdk/Model/StateUpdates.cs new file mode 100644 index 000000000..970bbdfc4 --- /dev/null +++ b/src/RadixDlt.CoreApiSdk/Model/StateUpdates.cs @@ -0,0 +1,73 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +using System.Collections.Generic; +using System.Linq; + +namespace RadixDlt.CoreApiSdk.Model; + +public partial class StateUpdates +{ + public List UpsertedSubstates => CreatedSubstates.ToList().Concat(UpdatedSubstates.ToList()).ToList(); +} diff --git a/src/RadixDlt.CoreApiSdk/Model/UpdatedSubstate.cs b/src/RadixDlt.CoreApiSdk/Model/UpdatedSubstate.cs new file mode 100644 index 000000000..e16680974 --- /dev/null +++ b/src/RadixDlt.CoreApiSdk/Model/UpdatedSubstate.cs @@ -0,0 +1,70 @@ +/* Copyright 2021 Radix Publishing Ltd incorporated in Jersey (Channel Islands). + * + * Licensed under the Radix License, Version 1.0 (the "License"); you may not use this + * file except in compliance with the License. You may obtain a copy of the License at: + * + * radixfoundation.org/licenses/LICENSE-v1 + * + * The Licensor hereby grants permission for the Canonical version of the Work to be + * published, distributed and used under or by reference to the Licensor’s trademark + * Radix ® and use of any unregistered trade names, logos or get-up. + * + * The Licensor provides the Work (and each Contributor provides its Contributions) on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, + * including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, + * MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. + * + * Whilst the Work is capable of being deployed, used and adopted (instantiated) to create + * a distributed ledger it is your responsibility to test and validate the code, together + * with all logic and performance of that code under all foreseeable scenarios. + * + * The Licensor does not make or purport to make and hereby excludes liability for all + * and any representation, warranty or undertaking in any form whatsoever, whether express + * or implied, to any entity or person, including any representation, warranty or + * undertaking, as to the functionality security use, value or other characteristics of + * any distributed ledger nor in respect the functioning or value of any tokens which may + * be created stored or transferred using the Work. The Licensor does not warrant that the + * Work or any use of the Work complies with any law or regulation in any territory where + * it may be implemented or used or that it will be appropriate for any specific purpose. + * + * Neither the licensor nor any current or former employees, officers, directors, partners, + * trustees, representatives, agents, advisors, contractors, or volunteers of the Licensor + * shall be liable for any direct or indirect, special, incidental, consequential or other + * losses of any kind, in tort, contract or otherwise (including but not limited to loss + * of revenue, income or profits, or loss of use or data, or loss of reputation, or loss + * of any economic or other opportunity of whatsoever nature or howsoever arising), arising + * out of or in connection with (without limitation of any use, misuse, of any ledger system + * or use made or its functionality or any performance or operation of any code or protocol + * caused by bugs or programming or logic errors or otherwise); + * + * A. any offer, purchase, holding, use, sale, exchange or transmission of any + * cryptographic keys, tokens or assets created, exchanged, stored or arising from any + * interaction with the Work; + * + * B. any failure in a transmission or loss of any token or assets keys or other digital + * artefacts due to errors in transmission; + * + * C. bugs, hacks, logic errors or faults in the Work or any communication; + * + * D. system software or apparatus including but not limited to losses caused by errors + * in holding or transmitting tokens by any third-party; + * + * E. breaches or failure of security including hacker attacks, loss or disclosure of + * password, loss of private key, unauthorised use or misuse of such passwords or keys; + * + * F. any losses including loss of anticipated savings or other benefits resulting from + * use of the Work or any changes to the Work (however implemented). + * + * You are solely responsible for; testing, validating and evaluation of all operation + * logic, functionality, security and appropriateness of using the Work for any commercial + * or non-commercial purpose and for any reproduction or redistribution by You of the + * Work. You assume all risks associated with Your use of the Work and the exercise of + * permissions under this License. + */ + +namespace RadixDlt.CoreApiSdk.Model; + +public partial class UpdatedSubstate : IUpsertedSubstate +{ + public SubstateValue Value => NewValue; +} diff --git a/src/RadixDlt.NetworkGateway.Abstractions/Numerics/TokenAmount.cs b/src/RadixDlt.NetworkGateway.Abstractions/Numerics/TokenAmount.cs index 01e7d0ecb..5cf52f2b3 100644 --- a/src/RadixDlt.NetworkGateway.Abstractions/Numerics/TokenAmount.cs +++ b/src/RadixDlt.NetworkGateway.Abstractions/Numerics/TokenAmount.cs @@ -79,7 +79,6 @@ namespace RadixDlt.NetworkGateway.Abstractions.Numerics; public static readonly TokenAmount Zero; public static readonly TokenAmount NaN; public static readonly TokenAmount OneFullUnit; - public static readonly TokenAmount MinusOne; static TokenAmount() { @@ -88,7 +87,6 @@ static TokenAmount() Zero = new TokenAmount(0); NaN = new TokenAmount(true); OneFullUnit = new TokenAmount(_divisor); - MinusOne = new TokenAmount(-1); } private readonly BigInteger _subUnits; diff --git a/src/RadixDlt.NetworkGateway.DataAggregator/NodeServices/ApiReaders/TransactionStreamReader.cs b/src/RadixDlt.NetworkGateway.DataAggregator/NodeServices/ApiReaders/TransactionStreamReader.cs index d6aa1f42c..51373346c 100644 --- a/src/RadixDlt.NetworkGateway.DataAggregator/NodeServices/ApiReaders/TransactionStreamReader.cs +++ b/src/RadixDlt.NetworkGateway.DataAggregator/NodeServices/ApiReaders/TransactionStreamReader.cs @@ -116,7 +116,7 @@ public TransactionStreamReader( Hash = false, Raw = false, Typed = true, - Previous = false, + Previous = true, }, sborFormatOptions: new CoreModel.SborFormatOptions { diff --git a/src/RadixDlt.NetworkGateway.PostgresIntegration/LedgerExtension/PostgresLedgerExtenderService.cs b/src/RadixDlt.NetworkGateway.PostgresIntegration/LedgerExtension/PostgresLedgerExtenderService.cs index d4463e811..ab6d90425 100644 --- a/src/RadixDlt.NetworkGateway.PostgresIntegration/LedgerExtension/PostgresLedgerExtenderService.cs +++ b/src/RadixDlt.NetworkGateway.PostgresIntegration/LedgerExtension/PostgresLedgerExtenderService.cs @@ -351,10 +351,7 @@ private async Task ProcessTransactions(ReadWriteDbContext db }); } - foreach (var substate in stateUpdates - .CreatedSubstates - .Select(x => new { x.SubstateId, x.Value }) - .Concat(stateUpdates.UpdatedSubstates.Select(x => new { x.SubstateId, Value = x.NewValue }))) + foreach (var substate in stateUpdates.UpsertedSubstates) { var substateId = substate.SubstateId; var substateData = substate.Value.SubstateData; @@ -761,10 +758,7 @@ private async Task ProcessTransactions(ReadWriteDbContext db try { - foreach (var substate in stateUpdates - .CreatedSubstates - .Select(x => new { x.SubstateId, x.Value }) - .Concat(stateUpdates.UpdatedSubstates.Select(x => new { x.SubstateId, Value = x.NewValue }))) + foreach (var substate in stateUpdates.UpsertedSubstates) { var substateId = substate.SubstateId; var substateData = substate.Value.SubstateData; @@ -782,15 +776,53 @@ private async Task ProcessTransactions(ReadWriteDbContext db if (substateData is CoreModel.FungibleVaultFieldBalanceSubstate fungibleVaultFieldBalanceSubstate) { + var vaultEntity = referencedEntity.GetDatabaseEntity(); + var resourceEntity = referencedEntities.GetByDatabaseId(vaultEntity.ResourceEntityId); var amount = TokenAmount.FromDecimalString(fungibleVaultFieldBalanceSubstate.Value.Amount); - var resourceEntity = referencedEntities.GetByDatabaseId(referencedEntity.GetDatabaseEntity().ResourceEntityId); fungibleVaultChanges.Add(new FungibleVaultChange(referencedEntity, resourceEntity, amount, stateVersion)); + + if (!vaultEntity.IsRoyaltyVault) + { + var previousAmountRaw = (substate.PreviousValue?.SubstateData as CoreModel.FungibleVaultFieldBalanceSubstate)?.Value.Amount; + var previousAmount = previousAmountRaw == null ? TokenAmount.Zero : TokenAmount.FromDecimalString(previousAmountRaw); + var delta = amount - previousAmount; + + entityFungibleResourceBalanceChangeEvents.Add(new EntityFungibleResourceBalanceChangeEvent(referencedEntity.DatabaseGlobalAncestorId, resourceEntity.DatabaseId, + delta, stateVersion)); + + if (referencedEntity.DatabaseGlobalAncestorId != referencedEntity.DatabaseOwnerAncestorId) + { + entityFungibleResourceBalanceChangeEvents.Add(new EntityFungibleResourceBalanceChangeEvent(referencedEntity.DatabaseOwnerAncestorId, resourceEntity.DatabaseId, + delta, stateVersion)); + } + } + } + + if (substateData is CoreModel.NonFungibleVaultFieldBalanceSubstate nonFungibleVaultFieldBalanceSubstate) + { + var vaultEntity = referencedEntity.GetDatabaseEntity(); + var resourceEntity = referencedEntities.GetByDatabaseId(vaultEntity.ResourceEntityId); + var amount = long.Parse(nonFungibleVaultFieldBalanceSubstate.Value.Amount); + + var previousAmountRaw = (substate.PreviousValue?.SubstateData as CoreModel.NonFungibleVaultFieldBalanceSubstate)?.Value.Amount; + var previousAmount = previousAmountRaw == null ? 0 : long.Parse(previousAmountRaw); + var delta = amount - previousAmount; + + entityNonFungibleResourceBalanceChangeEvents.Add(new EntityNonFungibleResourceBalanceChangeEvent(referencedEntity.DatabaseGlobalAncestorId, resourceEntity.DatabaseId, + delta, stateVersion)); + + if (referencedEntity.DatabaseGlobalAncestorId != referencedEntity.DatabaseOwnerAncestorId) + { + entityNonFungibleResourceBalanceChangeEvents.Add(new EntityNonFungibleResourceBalanceChangeEvent(referencedEntity.DatabaseOwnerAncestorId, resourceEntity.DatabaseId, + delta, stateVersion)); + } } if (substateData is CoreModel.NonFungibleVaultContentsIndexEntrySubstate nonFungibleVaultContentsIndexEntrySubstate) { - var resourceEntity = referencedEntities.GetByDatabaseId(referencedEntity.GetDatabaseEntity().ResourceEntityId); + var vaultEntity = referencedEntity.GetDatabaseEntity(); + var resourceEntity = referencedEntities.GetByDatabaseId(vaultEntity.ResourceEntityId); nonFungibleVaultChanges.Add(new NonFungibleVaultChange( referencedEntity, @@ -1181,109 +1213,51 @@ private async Task ProcessTransactions(ReadWriteDbContext db } else if (EventDecoder.TryGetFungibleVaultWithdrawalEvent(decodedEvent, out var fungibleVaultWithdrawalEvent)) { - var value = TokenAmount.FromDecimalString(fungibleVaultWithdrawalEvent.AsStr()); - var vaultEntity = eventEmitterEntity.GetDatabaseEntity(); - var resourceEntityId = vaultEntity.ResourceEntityId; - ledgerTransactionMarkersToAdd.Add(new EventLedgerTransactionMarker { Id = sequences.LedgerTransactionMarkerSequence++, StateVersion = stateVersion, EventType = LedgerTransactionMarkerEventType.Withdrawal, EntityId = eventEmitterEntity.DatabaseGlobalAncestorId, - ResourceEntityId = resourceEntityId, - Quantity = value, + ResourceEntityId = eventEmitterEntity.GetDatabaseEntity().ResourceEntityId, + Quantity = TokenAmount.FromDecimalString(fungibleVaultWithdrawalEvent.AsStr()), }); - - if (!vaultEntity.IsRoyaltyVault) - { - entityFungibleResourceBalanceChangeEvents.Add(new EntityFungibleResourceBalanceChangeEvent(eventEmitterEntity.DatabaseGlobalAncestorId, resourceEntityId, - value * TokenAmount.MinusOne, stateVersion)); - - if (eventEmitterEntity.DatabaseGlobalAncestorId != eventEmitterEntity.DatabaseOwnerAncestorId) - { - entityFungibleResourceBalanceChangeEvents.Add(new EntityFungibleResourceBalanceChangeEvent(eventEmitterEntity.DatabaseOwnerAncestorId, resourceEntityId, - value * TokenAmount.MinusOne, stateVersion)); - } - } } else if (EventDecoder.TryGetFungibleVaultDepositEvent(decodedEvent, out var fungibleVaultDepositEvent)) { - var value = TokenAmount.FromDecimalString(fungibleVaultDepositEvent.AsStr()); - var vaultEntity = eventEmitterEntity.GetDatabaseEntity(); - var resourceEntityId = vaultEntity.ResourceEntityId; - ledgerTransactionMarkersToAdd.Add(new EventLedgerTransactionMarker { Id = sequences.LedgerTransactionMarkerSequence++, StateVersion = stateVersion, EventType = LedgerTransactionMarkerEventType.Deposit, EntityId = eventEmitterEntity.DatabaseGlobalAncestorId, - ResourceEntityId = resourceEntityId, - Quantity = value, + ResourceEntityId = eventEmitterEntity.GetDatabaseEntity().ResourceEntityId, + Quantity = TokenAmount.FromDecimalString(fungibleVaultDepositEvent.AsStr()), }); - - if (!vaultEntity.IsRoyaltyVault) - { - entityFungibleResourceBalanceChangeEvents.Add(new EntityFungibleResourceBalanceChangeEvent(eventEmitterEntity.DatabaseGlobalAncestorId, resourceEntityId, value, - stateVersion)); - - if (eventEmitterEntity.DatabaseGlobalAncestorId != eventEmitterEntity.DatabaseOwnerAncestorId) - { - entityFungibleResourceBalanceChangeEvents.Add(new EntityFungibleResourceBalanceChangeEvent(eventEmitterEntity.DatabaseOwnerAncestorId, resourceEntityId, value, - stateVersion)); - } - } } else if (EventDecoder.TryGetNonFungibleVaultWithdrawalEvent(decodedEvent, out var nonFungibleVaultWithdrawalEvent)) { - var value = nonFungibleVaultWithdrawalEvent.Count.ToString(); - var vaultEntity = eventEmitterEntity.GetDatabaseEntity(); - var resourceEntityId = vaultEntity.ResourceEntityId; - ledgerTransactionMarkersToAdd.Add(new EventLedgerTransactionMarker { Id = sequences.LedgerTransactionMarkerSequence++, StateVersion = stateVersion, EventType = LedgerTransactionMarkerEventType.Withdrawal, EntityId = eventEmitterEntity.DatabaseGlobalAncestorId, - ResourceEntityId = resourceEntityId, - Quantity = TokenAmount.FromDecimalString(value), + ResourceEntityId = eventEmitterEntity.GetDatabaseEntity().ResourceEntityId, + Quantity = TokenAmount.FromDecimalString(nonFungibleVaultWithdrawalEvent.Count.ToString()), }); - - entityNonFungibleResourceBalanceChangeEvents.Add(new EntityNonFungibleResourceBalanceChangeEvent(eventEmitterEntity.DatabaseGlobalAncestorId, resourceEntityId, - long.Parse(value) * -1, stateVersion)); - - if (eventEmitterEntity.DatabaseGlobalAncestorId != eventEmitterEntity.DatabaseOwnerAncestorId) - { - entityNonFungibleResourceBalanceChangeEvents.Add(new EntityNonFungibleResourceBalanceChangeEvent(eventEmitterEntity.DatabaseOwnerAncestorId, resourceEntityId, - long.Parse(value) * -1, stateVersion)); - } } else if (EventDecoder.TryGetNonFungibleVaultDepositEvent(decodedEvent, out var nonFungibleVaultDepositEvent)) { - var value = nonFungibleVaultDepositEvent.Count.ToString(); - var vaultEntity = eventEmitterEntity.GetDatabaseEntity(); - var resourceEntityId = vaultEntity.ResourceEntityId; - ledgerTransactionMarkersToAdd.Add(new EventLedgerTransactionMarker { Id = sequences.LedgerTransactionMarkerSequence++, StateVersion = stateVersion, EventType = LedgerTransactionMarkerEventType.Deposit, EntityId = eventEmitterEntity.DatabaseGlobalAncestorId, - ResourceEntityId = resourceEntityId, - Quantity = TokenAmount.FromDecimalString(value), + ResourceEntityId = eventEmitterEntity.GetDatabaseEntity().ResourceEntityId, + Quantity = TokenAmount.FromDecimalString(nonFungibleVaultDepositEvent.Count.ToString()), }); - - entityNonFungibleResourceBalanceChangeEvents.Add(new EntityNonFungibleResourceBalanceChangeEvent(eventEmitterEntity.DatabaseGlobalAncestorId, resourceEntityId, - long.Parse(value), stateVersion)); - - if (eventEmitterEntity.DatabaseGlobalAncestorId != eventEmitterEntity.DatabaseOwnerAncestorId) - { - entityNonFungibleResourceBalanceChangeEvents.Add(new EntityNonFungibleResourceBalanceChangeEvent(eventEmitterEntity.DatabaseOwnerAncestorId, resourceEntityId, - long.Parse(value), stateVersion)); - } } else if (EventDecoder.TryGetFungibleResourceMintedEvent(decodedEvent, out var fungibleResourceMintedEvent)) {