Skip to content

Commit

Permalink
fetch tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
yhabib committed Dec 27, 2024
1 parent df80d9a commit 336215a
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { formatNumber } from "$lib/utils/format.utils";
import { isNullish, nonNullish } from "@dfinity/utils";
export let usdAmount: number | undefined = 14500;
export let usdAmount: number | undefined;
export let hasUnpricedTokens: boolean = false;
let hasError: boolean;
Expand Down
118 changes: 118 additions & 0 deletions frontend/src/lib/services/accounts-balances.services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { CKBTC_ADDITIONAL_CANISTERS } from "$lib/constants/ckbtc-additional-canister-ids.constants";
import type { IcrcCanistersStoreData } from "$lib/derived/icrc-canisters.derived";
import type { SnsFullProject } from "$lib/derived/sns/sns-projects.derived";
import type { Universe } from "$lib/types/universe";
import { isArrayEmpty } from "$lib/utils/utils";
import type { CanisterIdString } from "@dfinity/nns";
import { Principal } from "@dfinity/principal";
import { nonNullish } from "@dfinity/utils";
import { updateBalance } from "./ckbtc-minter.services";
import { uncertifiedLoadSnsesAccountsBalances } from "./sns-accounts-balance.services";
import { uncertifiedLoadAccountsBalance } from "./wallet-uncertified-accounts.services";

class BalanceFetchTracker {
private static instance: BalanceFetchTracker;
private loadedBalances: Set<CanisterIdString> = new Set();

public static getInstance(): BalanceFetchTracker {
if (!this.instance) {
this.instance = new BalanceFetchTracker();
}
return this.instance;
}

public getNotLoadedIds(ids: CanisterIdString[]): CanisterIdString[] {
const notLoadedIds = ids.filter((id) => !this.loadedBalances.has(id));
notLoadedIds.forEach((id) => this.loadedBalances.add(id));
return notLoadedIds;
}

public reset(): void {
this.loadedBalances.clear();
}
}

export const balanceLoader = {
reset() {
BalanceFetchTracker.getInstance().reset();
},
async loadAllBalances({
snsProjects,
ckBTCUniverses,
icrcCanisters,
}: {
snsProjects: SnsFullProject[];
ckBTCUniverses: Universe[];
icrcCanisters: IcrcCanistersStoreData;
}) {
await Promise.all([
this.loadSnsAccountsBalances(snsProjects),
this.loadCkBTCAccountsBalances(ckBTCUniverses),
this.loadIcrcTokenAccounts(icrcCanisters),
]);
},

async loadSnsAccountsBalances(projects: SnsFullProject[]) {
if (projects.length === 0) return;

const rootCanisterIds = projects.map(({ rootCanisterId }) =>
rootCanisterId.toText()
);
const notLoadedCanisterIds =
BalanceFetchTracker.getInstance().getNotLoadedIds(rootCanisterIds);

if (notLoadedCanisterIds.length === 0) return;

await uncertifiedLoadSnsesAccountsBalances({
rootCanisterIds: notLoadedCanisterIds.map((id) => Principal.fromText(id)),
excludeRootCanisterIds: [],
});
},

async loadCkBTCAccountsBalances(universes: Universe[]) {
const canisterIds = universes.map((universe) => universe.canisterId);
const notLoadedCanisterIds =
BalanceFetchTracker.getInstance().getNotLoadedIds(canisterIds);

if (notLoadedCanisterIds.length === 0) return;

// Update balance for each universe
universes.forEach((universe) => {
if (!notLoadedCanisterIds.includes(universe.canisterId)) return;

const ckBTCCanisters = CKBTC_ADDITIONAL_CANISTERS[universe.canisterId];
if (nonNullish(ckBTCCanisters.minterCanisterId)) {
updateBalance({
universeId: Principal.fromText(universe.canisterId),
minterCanisterId: ckBTCCanisters.minterCanisterId,
reload: () => this.loadAccountsBalances([universe.canisterId]),
deferReload: false,
uiIndicators: false,
});
}
});

await this.loadAccountsBalances(
universes.map(({ canisterId }) => canisterId)
);
},

async loadIcrcTokenAccounts(icrcCanisters: IcrcCanistersStoreData) {
const ids = Object.keys(icrcCanisters);
const notLoadedCanisterIds =
BalanceFetchTracker.getInstance().getNotLoadedIds(ids);

if (notLoadedCanisterIds.length === 0) return;

await this.loadAccountsBalances(notLoadedCanisterIds);
},

async loadAccountsBalances(universeIds: CanisterIdString[]) {
if (isArrayEmpty(universeIds)) return;

await uncertifiedLoadAccountsBalance({
universeIds,
excludeUniverseIds: [],
});
},
};
22 changes: 22 additions & 0 deletions frontend/src/routes/(app)/(nns)/portfolio/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
<script lang="ts">
import TestIdWrapper from "$lib/components/common/TestIdWrapper.svelte";
import { authSignedInStore } from "$lib/derived/auth.derived";
import { ckBTCUniversesStore } from "$lib/derived/ckbtc-universes.derived";
import { icrcCanistersStore } from "$lib/derived/icrc-canisters.derived";
import { snsProjectsCommittedStore } from "$lib/derived/sns/sns-projects.derived";
import Portfolio from "$lib/pages/Portfolio.svelte";
import { balanceLoader } from "$lib/services/accounts-balances.services";
import { loadCkBTCTokens } from "$lib/services/ckbtc-tokens.services";
import { loadIcpSwapTickers } from "$lib/services/icp-swap.services";
import { onMount } from "svelte";
onMount(() => {
balanceLoader.reset();
loadCkBTCTokens();
loadIcpSwapTickers();
});
$: if ($authSignedInStore) {
balanceLoader.loadAllBalances({
snsProjects: $snsProjectsCommittedStore,
ckBTCUniverses: $ckBTCUniversesStore,
icrcCanisters: $icrcCanistersStore,
});
}
</script>

<TestIdWrapper testId="portfolio-route-component"><Portfolio /></TestIdWrapper>

0 comments on commit 336215a

Please sign in to comment.