Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into NNS1-3480/get-all-tra…
Browse files Browse the repository at this point in the history
…nsactions
  • Loading branch information
yhabib committed Nov 28, 2024
2 parents 5500309 + 6fbfbe4 commit 4e83871
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 9 deletions.
8 changes: 6 additions & 2 deletions frontend/src/lib/services/icp-transactions.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { icpTransactionsStore } from "$lib/stores/icp-transactions.store";
import { toastsError } from "$lib/stores/toasts.store";
import { toToastError } from "$lib/utils/error.utils";
import { sortTransactionsByIdDescendingOrder } from "$lib/utils/icp-transactions.utils";
import { nonNullish } from "@dfinity/utils";
import { isNullish, nonNullish } from "@dfinity/utils";
import { get } from "svelte/store";
import { getCurrentIdentity } from "./auth.services";

Expand All @@ -27,7 +27,11 @@ export const loadIcpAccountTransactions = async ({
start,
});

const completed = transactions.some(({ id }) => id === oldestTxId);
// We consider it complete if we find the oldestTxId in the list of transactions or if oldestTxId is null.
// The latter condition is necessary if the list of transactions is empty, which would otherwise return false.
const completed =
isNullish(oldestTxId) || transactions.some(({ id }) => id === oldestTxId);

icpTransactionsStore.addTransactions({
accountIdentifier,
transactions,
Expand Down
17 changes: 10 additions & 7 deletions frontend/src/lib/utils/neuron.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1186,16 +1186,19 @@ const getVotingPowerRefreshedTimestampSeconds = ({
// to avoid unnecessary notifications.
fullNeuron?.votingPowerRefreshedTimestampSeconds ?? BigInt(nowInSeconds());

export const secondsUntilLosingRewards = (neuron: NeuronInfo): number => {
const rewardLossStart =
Number(getVotingPowerRefreshedTimestampSeconds(neuron)) +
START_REDUCING_VOTING_POWER_AFTER_SECONDS;
return rewardLossStart - nowInSeconds();
};

export const isNeuronLosingRewards = (neuron: NeuronInfo): boolean =>
nowInSeconds() >=
getVotingPowerRefreshedTimestampSeconds(neuron) +
BigInt(START_REDUCING_VOTING_POWER_AFTER_SECONDS);
secondsUntilLosingRewards(neuron) <= 0;

// e.g. "Neuron will start losing rewards in 30 days"
export const shouldDisplayRewardLossNotification = (
neuron: NeuronInfo
): boolean =>
nowInSeconds() >=
getVotingPowerRefreshedTimestampSeconds(neuron) +
BigInt(START_REDUCING_VOTING_POWER_AFTER_SECONDS) -
BigInt(daysToSeconds(NOTIFICATION_PERIOD_BEFORE_REWARD_LOSS_STARTS_DAYS));
secondsUntilLosingRewards(neuron) <=
daysToSeconds(NOTIFICATION_PERIOD_BEFORE_REWARD_LOSS_STARTS_DAYS);
18 changes: 18 additions & 0 deletions frontend/src/tests/lib/services/icp-transactions.services.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,24 @@ describe("icp-transactions services", () => {
expect(get(icpTransactionsStore)[accountIdentifier].completed).toBe(true);
});

it("sets complete to true when empty array", async () => {
const oldestTxId = null;
const transactions = [];

vi.spyOn(indexApi, "getTransactions").mockResolvedValue({
oldestTxId,
transactions: transactions,
balance: 200_000_000n,
});

await loadIcpAccountTransactions({
accountIdentifier,
start: undefined,
});

expect(get(icpTransactionsStore)[accountIdentifier].completed).toBe(true);
});

it("toasts error if api fails", async () => {
vi.spyOn(indexApi, "getTransactions").mockRejectedValue(
new Error("Something happened")
Expand Down
29 changes: 29 additions & 0 deletions frontend/src/tests/lib/utils/neuron.utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import {
neuronStakedMaturity,
neuronVotingPower,
neuronsVotingPower,
secondsUntilLosingRewards,
shouldDisplayRewardLossNotification,
sortNeuronsByStake,
sortNeuronsByVotingPowerRefreshedTimeout,
Expand Down Expand Up @@ -3294,6 +3295,34 @@ describe("neuron-utils", () => {
const losingRewardsPeriod = SECONDS_IN_HALF_YEAR;
const notificationPeriod = 30 * SECONDS_IN_DAY;

describe("secondsUntilLosingRewards", () => {
it("should return future date when no fullNeuron", () => {
expect(
secondsUntilLosingRewards({
...mockNeuron,
fullNeuron: undefined,
})
).toEqual(SECONDS_IN_HALF_YEAR);
});

it("should return seconds until losing rewards", () => {
expect(
secondsUntilLosingRewards(
neuronWithRefreshedTimestamp({
votingPowerRefreshedTimestampAgeSecs: 0,
})
)
).toBe(SECONDS_IN_HALF_YEAR);
expect(
secondsUntilLosingRewards(
neuronWithRefreshedTimestamp({
votingPowerRefreshedTimestampAgeSecs: losingRewardsPeriod,
})
)
).toBe(0);
});
});

describe("isNeuronLosingRewards", () => {
it("should return false by default", () => {
expect(
Expand Down

0 comments on commit 4e83871

Please sign in to comment.