UNPKG

@ledgerhq/live-common

Version:
268 lines (227 loc) • 10.2 kB
import { genAccount } from "@ledgerhq/ledger-wallet-framework/mocks/account"; import { getCryptoCurrencyById } from "../currencies/index"; import { Account } from "@ledgerhq/types-live"; import type { TokenCurrency } from "@ledgerhq/types-cryptoassets"; import BigNumber from "bignumber.js"; import { getTotalStakeableAssets } from "./getTotalStakeableAssets"; import { setupMockCryptoAssetsStore } from "@ledgerhq/cryptoassets/cal-client/test-helpers"; // Setup mock store for unit tests setupMockCryptoAssetsStore(); const ETH = getCryptoCurrencyById("ethereum"); const BTC = getCryptoCurrencyById("bitcoin"); // Create mock tokens for tests const ZRX_TOKEN: TokenCurrency = { type: "TokenCurrency", id: "ethereum/erc20/0x_project", contractAddress: "0xE41d2489571d322189246DaFA5ebDe1F4699F498", parentCurrency: ETH, tokenType: "erc20", name: "0x Project", ticker: "ZRX", delisted: false, disableCountervalue: false, units: [{ name: "ZRX", code: "ZRX", magnitude: 18 }], }; const REP_TOKEN: TokenCurrency = { type: "TokenCurrency", id: "ethereum/erc20/augur", contractAddress: "0x1985365e9f78359a9B6AD760e32412f4a445E862", parentCurrency: ETH, tokenType: "erc20", name: "Augur", ticker: "REP", delisted: false, disableCountervalue: false, units: [{ name: "REP", code: "REP", magnitude: 18 }], }; const mockedAccounts: Account[] = [ genAccount("mocked-account-1", { currency: ETH, tokensData: [ZRX_TOKEN, REP_TOKEN], }), ]; describe("getTotalStakeableAssets", () => { it("should return empty Set if no accounts", () => { const result = getTotalStakeableAssets([], [], []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(0); expect(result.stakeableAssets).toEqual([]); }); it("should return empty Set if accounts is null", () => { const result = getTotalStakeableAssets(null, [], []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(0); expect(result.stakeableAssets).toEqual([]); }); it("should return empty Set if accounts is undefined", () => { const result = getTotalStakeableAssets(undefined, [], []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(0); expect(result.stakeableAssets).toEqual([]); }); it("should return empty Set if no staking currencies enabled", () => { const result = getTotalStakeableAssets(mockedAccounts, [], []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(0); expect(result.stakeableAssets).toEqual([]); }); it("should return Set with matching currency ID when staking currency is enabled", () => { const account = mockedAccounts[0]; const stakingCurrenciesEnabled = [ETH.id]; // "ethereum" expect(account.balance).toBeTruthy(); expect(account.balance instanceof BigNumber).toBe(true); expect(account.balance.gt(0)).toBe(true); const result = getTotalStakeableAssets([account], stakingCurrenciesEnabled, []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(1); expect(result.combinedIds.has(ETH.id)).toBe(true); expect(result.stakeableAssets.length).toBe(1); expect(result.stakeableAssets[0]).toEqual({ ticker: ETH.ticker, networkName: ETH.name, id: ETH.id, }); }); it("should return Set with matching token IDs when staking tokens are enabled", () => { const account = mockedAccounts[0]; const stakingCurrenciesEnabled = [ZRX_TOKEN.id, REP_TOKEN.id]; expect(account.subAccounts).toBeDefined(); expect(account.subAccounts?.length).toBe(2); const result = getTotalStakeableAssets([account], stakingCurrenciesEnabled, []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(2); expect(result.combinedIds.has(ZRX_TOKEN.id)).toBe(true); expect(result.combinedIds.has(REP_TOKEN.id)).toBe(true); expect(result.stakeableAssets.length).toBe(2); expect(result.stakeableAssets).toEqual( expect.arrayContaining([ expect.objectContaining({ id: ZRX_TOKEN.id, ticker: ZRX_TOKEN.ticker }), expect.objectContaining({ id: REP_TOKEN.id, ticker: REP_TOKEN.ticker }), ]), ); }); it("should return Set with both currency and token IDs when both are enabled", () => { const account = mockedAccounts[0]; const stakingCurrenciesEnabled = [ETH.id, ZRX_TOKEN.id, REP_TOKEN.id]; const result = getTotalStakeableAssets([account], stakingCurrenciesEnabled, []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(3); expect(result.combinedIds.has(ETH.id)).toBe(true); expect(result.combinedIds.has(ZRX_TOKEN.id)).toBe(true); expect(result.combinedIds.has(REP_TOKEN.id)).toBe(true); expect(result.stakeableAssets.length).toBe(3); expect(result.stakeableAssets).toEqual( expect.arrayContaining([ expect.objectContaining({ id: ETH.id, ticker: ETH.ticker }), expect.objectContaining({ id: ZRX_TOKEN.id, ticker: ZRX_TOKEN.ticker }), expect.objectContaining({ id: REP_TOKEN.id, ticker: REP_TOKEN.ticker }), ]), ); }); it("should filter out currencies without funds", () => { const account = mockedAccounts[0]; const accountWithZeroBalance = { ...account, balance: new BigNumber(0) }; const stakingCurrenciesEnabled = [ETH.id]; const result = getTotalStakeableAssets([accountWithZeroBalance], stakingCurrenciesEnabled, []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(0); expect(result.stakeableAssets).toEqual([]); }); it("should filter out tokens without funds", () => { const account = mockedAccounts[0]; const [zrxAccount, repAccount] = account.subAccounts || []; const emptyRepAccount = { ...repAccount, balance: new BigNumber(0) }; const accountWithEmptyToken = { ...account, subAccounts: [zrxAccount, emptyRepAccount] }; const stakingCurrenciesEnabled = [ZRX_TOKEN.id, REP_TOKEN.id]; const result = getTotalStakeableAssets([accountWithEmptyToken], stakingCurrenciesEnabled, []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(1); expect(result.combinedIds.has(ZRX_TOKEN.id)).toBe(true); expect(result.combinedIds.has(REP_TOKEN.id)).toBe(false); expect(result.stakeableAssets.length).toBe(1); expect(result.stakeableAssets[0]).toEqual( expect.objectContaining({ id: ZRX_TOKEN.id, ticker: ZRX_TOKEN.ticker }), ); }); it("should include partner staking currencies enabled", () => { const account = mockedAccounts[0]; const stakingCurrenciesEnabled = [ETH.id]; const partnerStakingCurrenciesEnabled = [ZRX_TOKEN.id]; const result = getTotalStakeableAssets( [account], stakingCurrenciesEnabled, partnerStakingCurrenciesEnabled, ); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(2); expect(result.combinedIds.has(ETH.id)).toBe(true); expect(result.combinedIds.has(ZRX_TOKEN.id)).toBe(true); expect(result.stakeableAssets.length).toBe(2); expect(result.stakeableAssets).toEqual( expect.arrayContaining([ expect.objectContaining({ id: ETH.id, ticker: ETH.ticker }), expect.objectContaining({ id: ZRX_TOKEN.id, ticker: ZRX_TOKEN.ticker }), ]), ); }); it("should deduplicate IDs when same currency appears in both lists", () => { const account = mockedAccounts[0]; const stakingCurrenciesEnabled = [ETH.id]; const partnerStakingCurrenciesEnabled = [ETH.id]; // Same currency const result = getTotalStakeableAssets( [account], stakingCurrenciesEnabled, partnerStakingCurrenciesEnabled, ); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(1); expect(result.combinedIds.has(ETH.id)).toBe(true); expect(result.stakeableAssets.length).toBe(1); expect(result.stakeableAssets[0]).toEqual({ ticker: ETH.ticker, networkName: ETH.name, id: ETH.id, }); }); it("should handle multiple accounts with different currencies", () => { const ethAccount = mockedAccounts[0]; const btcAccount = genAccount("mocked-account-2", { currency: BTC, }); const accounts = [ethAccount, btcAccount]; const stakingCurrenciesEnabled = [ETH.id, BTC.id]; const result = getTotalStakeableAssets(accounts, stakingCurrenciesEnabled, []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(2); expect(result.combinedIds.has(ETH.id)).toBe(true); expect(result.combinedIds.has(BTC.id)).toBe(true); expect(result.stakeableAssets.length).toBe(2); expect(result.stakeableAssets).toEqual( expect.arrayContaining([ expect.objectContaining({ id: ETH.id, ticker: ETH.ticker }), expect.objectContaining({ id: BTC.id, ticker: BTC.ticker }), ]), ); }); it("should only include IDs that match staking currencies enabled", () => { const account = mockedAccounts[0]; const stakingCurrenciesEnabled = [ZRX_TOKEN.id]; // Only ZRX enabled, not ETH or REP const result = getTotalStakeableAssets([account], stakingCurrenciesEnabled, []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(1); expect(result.combinedIds.has(ZRX_TOKEN.id)).toBe(true); expect(result.combinedIds.has(ETH.id)).toBe(false); expect(result.combinedIds.has(REP_TOKEN.id)).toBe(false); expect(result.stakeableAssets.length).toBe(1); expect(result.stakeableAssets[0]).toEqual( expect.objectContaining({ id: ZRX_TOKEN.id, ticker: ZRX_TOKEN.ticker }), ); }); it("should handle empty arrays for staking currencies", () => { const account = mockedAccounts[0]; const result = getTotalStakeableAssets([account], [], []); expect(result.combinedIds).toBeInstanceOf(Set); expect(result.combinedIds.size).toBe(0); expect(result.stakeableAssets).toEqual([]); }); });