Browse Source

Merge branch 'main' into next

pull/6766/merge
Thomas Kaul 16 hours ago
parent
commit
2abba414b0
  1. 18
      CHANGELOG.md
  2. 5
      apps/api/src/app/access/access.controller.ts
  3. 3
      apps/api/src/app/endpoints/public/public.controller.ts
  4. 12
      apps/api/src/app/portfolio/portfolio.controller.ts
  5. 7
      apps/api/src/app/user/user.service.ts
  6. 109
      apps/api/src/assets/cryptocurrencies/cryptocurrencies.json
  7. 7
      apps/api/src/services/data-provider/data-provider.service.ts
  8. 7
      apps/client/src/app/components/admin-overview/admin-overview.component.ts
  9. 5
      apps/client/src/app/pages/portfolio/fire/fire-page.component.ts
  10. 3
      apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts
  11. 7
      apps/client/src/assets/oss-friends.json
  12. 3707
      package-lock.json
  13. 42
      package.json

18
CHANGELOG.md

@ -16,7 +16,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Breaking Change**: The `sslmode=prefer` parameter in `DATABASE_URL` is no longer supported. Please update your environment variables (see `.env`) to use `sslmode=require` if _SSL_ is enabled or remove the `sslmode` parameter entirely if _SSL_ is not used. - **Breaking Change**: The `sslmode=prefer` parameter in `DATABASE_URL` is no longer supported. Please update your environment variables (see `.env`) to use `sslmode=require` if _SSL_ is enabled or remove the `sslmode` parameter entirely if _SSL_ is not used.
## 2.255.0 - 2026-03-20 ## Unreleased
### Changed
- Refreshed the cryptocurrencies list
- Upgraded `countup.js` from version `2.9.0` to `2.10.0`
- Upgraded `jsonpath` from version `1.2.1` to `1.3.0`
- Upgraded `nestjs` from version `11.1.14` to `11.1.19`
- Upgraded `Nx` from version `22.6.4` to `22.6.5`
## 2.255.0 - 2026-04-20
### Changed ### Changed
@ -33,7 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed the missing value column of the accounts table component on mobile - Fixed the missing value column of the accounts table component on mobile
## 2.254.0 - 2026-03-10 ## 2.254.0 - 2026-04-10
### Added ### Added
@ -51,7 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the style of the activity type component - Improved the style of the activity type component
## 2.253.0 - 2026-03-06 ## 2.253.0 - 2026-04-06
### Added ### Added
@ -71,7 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed the allocations by ETF provider chart on the allocations page in the _Presenter View_ - Fixed the allocations by ETF provider chart on the allocations page in the _Presenter View_
- Fixed the allocations by platform chart on the allocations page in the _Presenter View_ - Fixed the allocations by platform chart on the allocations page in the _Presenter View_
## 2.252.0 - 2026-03-02 ## 2.252.0 - 2026-04-02
### Added ### Added

5
apps/api/src/app/access/access.controller.ts

@ -2,6 +2,7 @@ import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorat
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { CreateAccessDto, UpdateAccessDto } from '@ghostfolio/common/dtos'; import { CreateAccessDto, UpdateAccessDto } from '@ghostfolio/common/dtos';
import { SubscriptionType } from '@ghostfolio/common/enums';
import { Access } from '@ghostfolio/common/interfaces'; import { Access } from '@ghostfolio/common/interfaces';
import { permissions } from '@ghostfolio/common/permissions'; import { permissions } from '@ghostfolio/common/permissions';
import type { RequestWithUser } from '@ghostfolio/common/types'; import type { RequestWithUser } from '@ghostfolio/common/types';
@ -75,7 +76,7 @@ export class AccessController {
): Promise<AccessModel> { ): Promise<AccessModel> {
if ( if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
this.request.user.subscription.type === 'Basic' this.request.user.subscription.type === SubscriptionType.Basic
) { ) {
throw new HttpException( throw new HttpException(
getReasonPhrase(StatusCodes.FORBIDDEN), getReasonPhrase(StatusCodes.FORBIDDEN),
@ -130,7 +131,7 @@ export class AccessController {
): Promise<AccessModel> { ): Promise<AccessModel> {
if ( if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
this.request.user.subscription.type === 'Basic' this.request.user.subscription.type === SubscriptionType.Basic
) { ) {
throw new HttpException( throw new HttpException(
getReasonPhrase(StatusCodes.FORBIDDEN), getReasonPhrase(StatusCodes.FORBIDDEN),

3
apps/api/src/app/endpoints/public/public.controller.ts

@ -7,6 +7,7 @@ import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interc
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { SubscriptionType } from '@ghostfolio/common/enums';
import { getSum } from '@ghostfolio/common/helper'; import { getSum } from '@ghostfolio/common/helper';
import { PublicPortfolioResponse } from '@ghostfolio/common/interfaces'; import { PublicPortfolioResponse } from '@ghostfolio/common/interfaces';
import type { RequestWithUser } from '@ghostfolio/common/types'; import type { RequestWithUser } from '@ghostfolio/common/types';
@ -58,7 +59,7 @@ export class PublicController {
}); });
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
hasDetails = user.subscription.type === 'Premium'; hasDetails = user.subscription.type === SubscriptionType.Premium;
} }
const [ const [

12
apps/api/src/app/portfolio/portfolio.controller.ts

@ -17,6 +17,7 @@ import {
HEADER_KEY_IMPERSONATION, HEADER_KEY_IMPERSONATION,
UNKNOWN_KEY UNKNOWN_KEY
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { SubscriptionType } from '@ghostfolio/common/enums';
import { import {
PortfolioDetails, PortfolioDetails,
PortfolioDividendsResponse, PortfolioDividendsResponse,
@ -92,7 +93,8 @@ export class PortfolioController {
let hasError = false; let hasError = false;
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
hasDetails = this.request.user.subscription.type === 'Premium'; hasDetails =
this.request.user.subscription.type === SubscriptionType.Premium;
} }
const filters = this.apiService.buildFiltersFromQueryParams({ const filters = this.apiService.buildFiltersFromQueryParams({
@ -356,7 +358,7 @@ export class PortfolioController {
if ( if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
this.request.user.subscription.type === 'Basic' this.request.user.subscription.type === SubscriptionType.Basic
) { ) {
dividends = dividends.map((item) => { dividends = dividends.map((item) => {
return nullifyValuesInObject(item, ['investment']); return nullifyValuesInObject(item, ['investment']);
@ -484,7 +486,7 @@ export class PortfolioController {
if ( if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
this.request.user.subscription.type === 'Basic' this.request.user.subscription.type === SubscriptionType.Basic
) { ) {
investments = investments.map((item) => { investments = investments.map((item) => {
return nullifyValuesInObject(item, ['investment']); return nullifyValuesInObject(item, ['investment']);
@ -596,7 +598,7 @@ export class PortfolioController {
if ( if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
this.request.user.subscription.type === 'Basic' this.request.user.subscription.type === SubscriptionType.Basic
) { ) {
performanceInformation.chart = performanceInformation.chart.map( performanceInformation.chart = performanceInformation.chart.map(
(item) => { (item) => {
@ -624,7 +626,7 @@ export class PortfolioController {
if ( if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
this.request.user.subscription.type === 'Basic' this.request.user.subscription.type === SubscriptionType.Basic
) { ) {
for (const category of report.xRay.categories) { for (const category of report.xRay.categories) {
category.rules = null; category.rules = null;

7
apps/api/src/app/user/user.service.ts

@ -32,6 +32,7 @@ import {
TAG_ID_EXCLUDE_FROM_ANALYSIS, TAG_ID_EXCLUDE_FROM_ANALYSIS,
locale as defaultLocale locale as defaultLocale
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { SubscriptionType } from '@ghostfolio/common/enums';
import { import {
User as IUser, User as IUser,
SystemMessage, SystemMessage,
@ -156,7 +157,7 @@ export class UserService {
if ( if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
subscription.type === 'Basic' subscription.type === SubscriptionType.Basic
) { ) {
tags = []; tags = [];
} }
@ -443,7 +444,7 @@ export class UserService {
createdAt: user.createdAt createdAt: user.createdAt
}); });
if (user.subscription?.type === 'Basic') { if (user.subscription?.type === SubscriptionType.Basic) {
const daysSinceRegistration = differenceInDays( const daysSinceRegistration = differenceInDays(
new Date(), new Date(),
user.createdAt user.createdAt
@ -485,7 +486,7 @@ export class UserService {
// Reset holdings view mode // Reset holdings view mode
user.settings.settings.holdingsViewMode = undefined; user.settings.settings.holdingsViewMode = undefined;
} else if (user.subscription?.type === 'Premium') { } else if (user.subscription?.type === SubscriptionType.Premium) {
if (!hasRole(user, Role.DEMO)) { if (!hasRole(user, Role.DEMO)) {
currentPermissions.push(permissions.createApiKey); currentPermissions.push(permissions.createApiKey);
currentPermissions.push(permissions.enableDataProviderGhostfolio); currentPermissions.push(permissions.enableDataProviderGhostfolio);

109
apps/api/src/assets/cryptocurrencies/cryptocurrencies.json

@ -40,6 +40,7 @@
"0NE": "Stone", "0NE": "Stone",
"0X0": "0x0.ai", "0X0": "0x0.ai",
"0X1": "0x1.tools: AI Multi-tool Plaform", "0X1": "0x1.tools: AI Multi-tool Plaform",
"0X63SPIKE": "Spike",
"0XBTC": "0xBitcoin", "0XBTC": "0xBitcoin",
"0XCOCO": "0xCoco", "0XCOCO": "0xCoco",
"0XDEV": "DEVAI", "0XDEV": "DEVAI",
@ -773,7 +774,7 @@
"ANALY": "Analysoor", "ANALY": "Analysoor",
"ANARCHISTS": "Anarchists Prime", "ANARCHISTS": "Anarchists Prime",
"ANAT": "Anatolia Token", "ANAT": "Anatolia Token",
"ANB": "Angryb", "ANB": "Ant BlockChain",
"ANC": "Anchor Protocol", "ANC": "Anchor Protocol",
"ANCHOR": "AnchorSwap", "ANCHOR": "AnchorSwap",
"ANCIENTKING": "Ancient Kingdom", "ANCIENTKING": "Ancient Kingdom",
@ -798,6 +799,7 @@
"ANGLE": "ANGLE", "ANGLE": "ANGLE",
"ANGO": "Aureus Nummus Gold", "ANGO": "Aureus Nummus Gold",
"ANGRYSLERF": "ANGRYSLERF", "ANGRYSLERF": "ANGRYSLERF",
"ANGRYTOKEN": "Angryb",
"ANI": "Ani Grok Companion (anicompanion.net)", "ANI": "Ani Grok Companion (anicompanion.net)",
"ANIM": "Animalia", "ANIM": "Animalia",
"ANIMA": "Realm Anima", "ANIMA": "Realm Anima",
@ -1047,6 +1049,7 @@
"ARTDRAW": "ArtDraw", "ARTDRAW": "ArtDraw",
"ARTE": "Artemine", "ARTE": "Artemine",
"ARTEM": "Artem", "ARTEM": "Artem",
"ARTEMIS": "OFFICIAL ARTEMIS",
"ARTEON": "Arteon", "ARTEON": "Arteon",
"ARTEQ": "artèQ", "ARTEQ": "artèQ",
"ARTEX": "Artex", "ARTEX": "Artex",
@ -1120,6 +1123,10 @@
"ASTA": "ASTA", "ASTA": "ASTA",
"ASTER": "Aster", "ASTER": "Aster",
"ASTERINU": "Aster INU", "ASTERINU": "Aster INU",
"ASTEROID": "ASTEROID",
"ASTEROIDBOT": "Asteroid Bot",
"ASTEROIDCOIN": "ASTEROID",
"ASTEROIDETH": "Asteroid",
"ASTHERUSUSDF": "Astherus USDF", "ASTHERUSUSDF": "Astherus USDF",
"ASTO": "Altered State Token", "ASTO": "Altered State Token",
"ASTON": "Aston", "ASTON": "Aston",
@ -1564,6 +1571,7 @@
"BANANO": "Banano", "BANANO": "Banano",
"BANC": "Babes and Nerds", "BANC": "Babes and Nerds",
"BANCA": "BANCA", "BANCA": "BANCA",
"BANCORUSD": "USD Bancor",
"BAND": "Band Protocol", "BAND": "Band Protocol",
"BANDEX": "Banana Index", "BANDEX": "Banana Index",
"BANDIT": "Bandit on Base", "BANDIT": "Bandit on Base",
@ -1602,11 +1610,12 @@
"BART": "BarterTrade", "BART": "BarterTrade",
"BARTKRC": "BART Token", "BARTKRC": "BART Token",
"BARY": "Bary", "BARY": "Bary",
"BAS": "BNB Attestation Service",
"BASEAI": "BaseAI", "BASEAI": "BaseAI",
"BASEBEAR": "BBQ", "BASEBEAR": "BBQ",
"BASECAT": "BASE CAT", "BASECAT": "BASE CAT",
"BASECOIN": "BASECOIN", "BASECOIN": "BASECOIN",
"BASED": "Based Money", "BASED": "Based Token",
"BASEDAI": "BasedAI", "BASEDAI": "BasedAI",
"BASEDALF": "Based Alf", "BASEDALF": "Based Alf",
"BASEDB": "Based Bonk", "BASEDB": "Based Bonk",
@ -1614,12 +1623,13 @@
"BASEDCOPE": "COPE", "BASEDCOPE": "COPE",
"BASEDFINANCE": "Based", "BASEDFINANCE": "Based",
"BASEDHOPPY": "Based Hoppy (basedhoppy.vip)", "BASEDHOPPY": "Based Hoppy (basedhoppy.vip)",
"BASEDMONEY": "Based Money",
"BASEDMONEYV1": "Based Money v1",
"BASEDP": "Based Pepe", "BASEDP": "Based Pepe",
"BASEDR": "Based Rabbit", "BASEDR": "Based Rabbit",
"BASEDS": "BasedSwap", "BASEDS": "BasedSwap",
"BASEDSB": "Based Street Bets", "BASEDSB": "Based Street Bets",
"BASEDTURBO": "Based Turbo", "BASEDTURBO": "Based Turbo",
"BASEDV1": "Based Money v1",
"BASEHEROES": "Baseheroes", "BASEHEROES": "Baseheroes",
"BASEPROTOCOL": "Base Protocol", "BASEPROTOCOL": "Base Protocol",
"BASESWAPX": "BaseX", "BASESWAPX": "BaseX",
@ -1637,6 +1647,7 @@
"BASISSHAREV2": "Basis Share", "BASISSHAREV2": "Basis Share",
"BASK": "BasketDAO", "BASK": "BasketDAO",
"BAST": "Bast", "BAST": "Bast",
"BASTEROID": "BABY ASTEROID",
"BASTET": "Bastet Goddess", "BASTET": "Bastet Goddess",
"BAT": "Basic Attention Token", "BAT": "Basic Attention Token",
"BATCH": "BATCH Token", "BATCH": "BATCH Token",
@ -2584,7 +2595,7 @@
"BOZO": "BOZO", "BOZO": "BOZO",
"BOZOH": "bozo Hybrid", "BOZOH": "bozo Hybrid",
"BOZY": "Book of Crazy", "BOZY": "Book of Crazy",
"BP": "BunnyPark", "BP": "Backpack",
"BPAD": "BlokPad", "BPAD": "BlokPad",
"BPADA": "Binance-Peg Cardano (Binance Bridge)", "BPADA": "Binance-Peg Cardano (Binance Bridge)",
"BPAVAX": "Binance-Peg Avalanche (Binance Bridge)", "BPAVAX": "Binance-Peg Avalanche (Binance Bridge)",
@ -2650,6 +2661,7 @@
"BREAD": "Breadchain Cooperative", "BREAD": "Breadchain Cooperative",
"BREE": "CBDAO", "BREE": "CBDAO",
"BREED": "BreederDAO", "BREED": "BreederDAO",
"BRENT": "Brent Crude",
"BREPE": "BREPE", "BREPE": "BREPE",
"BRETARDIO": "Bretardio", "BRETARDIO": "Bretardio",
"BRETT": "Brett Base", "BRETT": "Brett Base",
@ -2965,6 +2977,7 @@
"BULLA": "BULLA", "BULLA": "BULLA",
"BULLBEAR": "BullBear AI", "BULLBEAR": "BullBear AI",
"BULLC": "BuySell", "BULLC": "BuySell",
"BULLDOG": "BullDog Coin",
"BULLF": "BULL FINANCE", "BULLF": "BULL FINANCE",
"BULLGOD": "Bull God", "BULLGOD": "Bull God",
"BULLI": "Bullish On Ethereum", "BULLI": "Bullish On Ethereum",
@ -2997,6 +3010,7 @@
"BUNNY": "Pancake Bunny", "BUNNY": "Pancake Bunny",
"BUNNYINU": "Bunny Inu", "BUNNYINU": "Bunny Inu",
"BUNNYM": "BUNNY MEV BOT", "BUNNYM": "BUNNY MEV BOT",
"BUNNYP": "BunnyPark",
"BUNNYROCKET": "BunnyRocket", "BUNNYROCKET": "BunnyRocket",
"BURG": "Burger", "BURG": "Burger",
"BURGER": "Burger Swap", "BURGER": "Burger Swap",
@ -3207,7 +3221,8 @@
"CARTIER": "Cartier", "CARTIER": "Cartier",
"CARV": "CARV", "CARV": "CARV",
"CAS": "Cashaa", "CAS": "Cashaa",
"CASH": "CashCoin", "CASH": "CASH",
"CASHCOIN": "CashCoin",
"CASHIO": "Cashio Dollar", "CASHIO": "Cashio Dollar",
"CASHLY": "Cashly", "CASHLY": "Cashly",
"CASHT": "Cash Tech", "CASHT": "Cash Tech",
@ -3232,7 +3247,7 @@
"CATCEO": "CATCEO", "CATCEO": "CATCEO",
"CATCH": "SpaceCatch", "CATCH": "SpaceCatch",
"CATCO": "CatCoin", "CATCO": "CatCoin",
"CATCOIN": "CatCoin", "CATCOINCASH": "CatCoin",
"CATCOINETH": "Catcoin", "CATCOINETH": "Catcoin",
"CATCOINIO": "Catcoin", "CATCOINIO": "Catcoin",
"CATCOINOFSOL": "Cat Coin", "CATCOINOFSOL": "Cat Coin",
@ -3488,7 +3503,7 @@
"CHARTIQ": "ChartIQ", "CHARTIQ": "ChartIQ",
"CHAS": "Chasm", "CHAS": "Chasm",
"CHASH": "CleverHash", "CHASH": "CleverHash",
"CHAT": "Solchat", "CHAT": "OpenChat",
"CHATAI": "ChatAI Token", "CHATAI": "ChatAI Token",
"CHATGPT": "AI Dragon", "CHATGPT": "AI Dragon",
"CHATOSHI": "chAtoshI", "CHATOSHI": "chAtoshI",
@ -3826,7 +3841,8 @@
"COFIX": "CoFIX", "COFIX": "CoFIX",
"COFOUNDIT": "Cofound.it", "COFOUNDIT": "Cofound.it",
"COG": "Cognitio", "COG": "Cognitio",
"COGE": "Cogecoin", "COGE": "Copper Doge",
"COGECOIN": "Cogecoin",
"COGEN": "Cogenero", "COGEN": "Cogenero",
"COGI": "COGI", "COGI": "COGI",
"COGS": "Cogmento", "COGS": "Cogmento",
@ -4350,6 +4366,7 @@
"CWR": "Cowrium", "CWR": "Cowrium",
"CWS": "Crowns", "CWS": "Crowns",
"CWT": "CrossWallet", "CWT": "CrossWallet",
"CWU": "Commonwealth",
"CWV": "CryptoWave", "CWV": "CryptoWave",
"CWX": "Crypto-X", "CWX": "Crypto-X",
"CWXT": "CryptoWorldXToken", "CWXT": "CryptoWorldXToken",
@ -4673,6 +4690,7 @@
"DEFIK": "DeFi Kingdoms JADE", "DEFIK": "DeFi Kingdoms JADE",
"DEFIL": "DeFIL", "DEFIL": "DeFIL",
"DEFILAB": "Defi", "DEFILAB": "Defi",
"DEFINITIVE": "Edge",
"DEFISCALE": "DeFiScale", "DEFISCALE": "DeFiScale",
"DEFISSI": "DEFI.ssi", "DEFISSI": "DEFI.ssi",
"DEFIT": "Digital Fitness", "DEFIT": "Digital Fitness",
@ -5343,7 +5361,8 @@
"DTV": "DraperTV", "DTV": "DraperTV",
"DTX": "DataBroker DAO", "DTX": "DataBroker DAO",
"DUA": "Brillion", "DUA": "Brillion",
"DUAL": "Dual Finance", "DUAL": "DUAL",
"DUALDAOTOKEN": "Dual Finance",
"DUB": "DubCoin", "DUB": "DubCoin",
"DUBAICAT": "Dubai Cat", "DUBAICAT": "Dubai Cat",
"DUBBZ": "Dubbz", "DUBBZ": "Dubbz",
@ -5487,6 +5506,7 @@
"EARTH": "Earth Token", "EARTH": "Earth Token",
"EARTHCOIN": "EarthCoin", "EARTHCOIN": "EarthCoin",
"EARTHM": "Earthmeta", "EARTHM": "Earthmeta",
"EARTHY": "Little Earth Buddy",
"EASY": "EASY", "EASY": "EASY",
"EASYF": "EasyFeedback", "EASYF": "EasyFeedback",
"EASYMINE": "EasyMine", "EASYMINE": "EasyMine",
@ -5566,7 +5586,7 @@
"EDEXA": "edeXa Security Token", "EDEXA": "edeXa Security Token",
"EDFI": "EdFi", "EDFI": "EdFi",
"EDG": "Edgeless", "EDG": "Edgeless",
"EDGE": "Definitive", "EDGE": "edgeX",
"EDGEACTIVITY": "EDGE Activity Token", "EDGEACTIVITY": "EDGE Activity Token",
"EDGEAI": "EdgeAI", "EDGEAI": "EdgeAI",
"EDGEN": "LayerEdge", "EDGEN": "LayerEdge",
@ -5650,6 +5670,7 @@
"EIGENP": "Eigenpie", "EIGENP": "Eigenpie",
"EIM": "Expert Infra", "EIM": "Expert Infra",
"EIQT": "IQ Prediction", "EIQT": "IQ Prediction",
"EITHER": "Eitherway",
"EJAC": "EJA Coin", "EJAC": "EJA Coin",
"EJS": "Enjinstarter", "EJS": "Enjinstarter",
"EKG": "Ekon Gold", "EKG": "Ekon Gold",
@ -5765,6 +5786,7 @@
"EML": "EML Protocol", "EML": "EML Protocol",
"EMMM": "emmm", "EMMM": "emmm",
"EMN.CUR": "Eastman Chemical", "EMN.CUR": "Eastman Chemical",
"EMOGINETWORK": "EMOGI Network",
"EMOJI": "MOMOJI", "EMOJI": "MOMOJI",
"EMON": "Ethermon", "EMON": "Ethermon",
"EMONEYEUR": "e-Money EUR", "EMONEYEUR": "e-Money EUR",
@ -6063,10 +6085,11 @@
"EUSX": "eUSX", "EUSX": "eUSX",
"EUT": "EarnUp Token", "EUT": "EarnUp Token",
"EUTBL": "Spiko EU T-Bills Money Market Fund", "EUTBL": "Spiko EU T-Bills Money Market Fund",
"EV": "EVAI", "EV": "Everything",
"EVA": "Evadore", "EVA": "Evadore",
"EVAA": "EVAA Protocol", "EVAA": "EVAA Protocol",
"EVAI": "EVA Intelligence", "EVAI": "EVA Intelligence",
"EVAIIO": "EVAI",
"EVAL": "Chromia's EVAL by Virtuals", "EVAL": "Chromia's EVAL by Virtuals",
"EVAN": "Evanesco Network", "EVAN": "Evanesco Network",
"EVAULT": "EthereumVault", "EVAULT": "EthereumVault",
@ -7101,6 +7124,7 @@
"GENIESWAP": "GenieSwap", "GENIESWAP": "GenieSwap",
"GENIESWAPV1": "GenieSwap v1", "GENIESWAPV1": "GenieSwap v1",
"GENIFYART": "Genify ART", "GENIFYART": "Genify ART",
"GENIUS": "Genius",
"GENIX": "Genix", "GENIX": "Genix",
"GENO": "GenomeFi", "GENO": "GenomeFi",
"GENOME": "GenomesDao", "GENOME": "GenomesDao",
@ -7740,6 +7764,7 @@
"HACHIK": "Hachiko", "HACHIK": "Hachiko",
"HACHIKO": "Hachiko Inu Token", "HACHIKO": "Hachiko Inu Token",
"HACHIKOINU": "Hachiko Inu", "HACHIKOINU": "Hachiko Inu",
"HACHIKOTOKEN": "Hachiko",
"HACHIONB": "Hachi On Base", "HACHIONB": "Hachi On Base",
"HACHITOKEN": "Hachi", "HACHITOKEN": "Hachi",
"HACK": "HACK", "HACK": "HACK",
@ -7747,6 +7772,7 @@
"HAEDAL": "Haedal Protocol", "HAEDAL": "Haedal Protocol",
"HAGGIS": "New Born Haggis Pygmy Hippo", "HAGGIS": "New Born Haggis Pygmy Hippo",
"HAHA": "Hasaki", "HAHA": "Hasaki",
"HAHAYESRIZO": "Haha Yes Hedgehog",
"HAI": "Hacken Token", "HAI": "Hacken Token",
"HAIO": "HAiO", "HAIO": "HAiO",
"HAIR": " HairDAO", "HAIR": " HairDAO",
@ -7776,6 +7802,7 @@
"HANACOIN": "Hanacoin", "HANACOIN": "Hanacoin",
"HANAETH": "Hana", "HANAETH": "Hana",
"HANAETHCTO": "HANA", "HANAETHCTO": "HANA",
"HANC": "OddHanc",
"HAND": "ShowHand", "HAND": "ShowHand",
"HANDY": "Handy", "HANDY": "Handy",
"HANK": "Hank", "HANK": "Hank",
@ -7806,6 +7833,7 @@
"HASBIK": "Hasbulla", "HASBIK": "Hasbulla",
"HASH": "Provenance Blockchain", "HASH": "Provenance Blockchain",
"HASHAI": "HashAI", "HASHAI": "HashAI",
"HASHCOIN": "HASH Coin",
"HASHNET": "HashNet BitEco", "HASHNET": "HashNet BitEco",
"HASHT": "HASH Token", "HASHT": "HASH Token",
"HASUI": "Haedal", "HASUI": "Haedal",
@ -8411,6 +8439,7 @@
"IG": "IG Token ", "IG": "IG Token ",
"IGCH": "IG-Crypto Holding", "IGCH": "IG-Crypto Holding",
"IGG": "IG Gold", "IGG": "IG Gold",
"IGGT": "The Invincible Game Token",
"IGI": "Igi", "IGI": "Igi",
"IGNIS": "Ignis", "IGNIS": "Ignis",
"IGT": "Infinitar", "IGT": "Infinitar",
@ -8526,7 +8555,8 @@
"INNBC": "Innovative Bioresearch Coin", "INNBC": "Innovative Bioresearch Coin",
"INNOU": "Innou", "INNOU": "Innou",
"INNOVAMINEX": "InnovaMinex", "INNOVAMINEX": "InnovaMinex",
"INO": "Ino Coin", "INO": "InoAi",
"INOCOIN": "Ino Coin",
"INOVAI": "INOVAI", "INOVAI": "INOVAI",
"INP": "Ionic Pocket Token", "INP": "Ionic Pocket Token",
"INRT": "INRToken", "INRT": "INRToken",
@ -8709,6 +8739,7 @@
"IVY": "IvyKoin", "IVY": "IvyKoin",
"IVZ": "InvisibleCoin", "IVZ": "InvisibleCoin",
"IW": "iWallet", "IW": "iWallet",
"IWC": "IWC",
"IWFT": "İstanbul Wild Cats", "IWFT": "İstanbul Wild Cats",
"IWMON": "iShares Russell 2000 ETF (Ondo Tokenized)", "IWMON": "iShares Russell 2000 ETF (Ondo Tokenized)",
"IWT": "IwToken", "IWT": "IwToken",
@ -9382,6 +9413,7 @@
"KRD": "Krypton DAO", "KRD": "Krypton DAO",
"KREDS": "KREDS", "KREDS": "KREDS",
"KREST": "krest Network", "KREST": "krest Network",
"KRGN": "Kerrigan Network",
"KRIDA": "KridaFans", "KRIDA": "KridaFans",
"KRIPTO": "Kripto", "KRIPTO": "Kripto",
"KRL": "Kryll", "KRL": "Kryll",
@ -9897,7 +9929,7 @@
"LOKA": "League of Kingdoms", "LOKA": "League of Kingdoms",
"LOKR": "Polkalokr", "LOKR": "Polkalokr",
"LOKY": "Loky by Virtuals", "LOKY": "Loky by Virtuals",
"LOL": "EMOGI Network", "LOL": "LOL",
"LOLA": "Lola", "LOLA": "Lola",
"LOLATHECAT": "Lola", "LOLATHECAT": "Lola",
"LOLC": "LOL Coin", "LOLC": "LOL Coin",
@ -9907,9 +9939,11 @@
"LOLO": "Lolo", "LOLO": "Lolo",
"LOLONBSC": "LOL", "LOLONBSC": "LOL",
"LON": "Tokenlon", "LON": "Tokenlon",
"LONG": "Longdrink Finance", "LONG": "LONG",
"LONGDRINK": "Longdrink Finance",
"LONGEVITY": "longevity", "LONGEVITY": "longevity",
"LONGFU": "LONGFU", "LONGFU": "LONGFU",
"LONGFUN": "Long",
"LONGM": "Long Mao", "LONGM": "Long Mao",
"LONGSHINE": "LongShine", "LONGSHINE": "LongShine",
"LOOBY": "Looby by Stephen Bliss", "LOOBY": "Looby by Stephen Bliss",
@ -10360,6 +10394,7 @@
"MAXL": "Maxi protocol", "MAXL": "Maxi protocol",
"MAXR": "Max Revive", "MAXR": "Max Revive",
"MAXX": "MAXX Finance", "MAXX": "MAXX Finance",
"MAXXING": "Maxxing",
"MAY": "Mayflower", "MAY": "Mayflower",
"MAYA": "Maya", "MAYA": "Maya",
"MAYACOIN": "MayaCoin", "MAYACOIN": "MayaCoin",
@ -10667,6 +10702,8 @@
"MEXC": "MEXC Token", "MEXC": "MEXC Token",
"MEXP": "MOJI Experience Points", "MEXP": "MOJI Experience Points",
"MEY": "Mey Network", "MEY": "Mey Network",
"MEZO": "MEZO",
"MEZOUSD": "Mezo USD",
"MEZZ": "MEZZ Token", "MEZZ": "MEZZ Token",
"MF": "Moonwalk Fitness", "MF": "Moonwalk Fitness",
"MF1": "Meta Finance", "MF1": "Meta Finance",
@ -10713,7 +10750,8 @@
"MHT": "Mouse Haunt", "MHT": "Mouse Haunt",
"MHUNT": "MetaShooter", "MHUNT": "MetaShooter",
"MI": "XiaoMiCoin", "MI": "XiaoMiCoin",
"MIA": "MiamiCoin", "MIA": "MIA",
"MIAMICOIN": "MiamiCoin",
"MIAO": "MIAOCoin", "MIAO": "MIAOCoin",
"MIB": "Mobile Integrated Blockchain", "MIB": "Mobile Integrated Blockchain",
"MIBO": "miBoodle", "MIBO": "miBoodle",
@ -11034,7 +11072,7 @@
"MOLO": "MOLO CHAIN", "MOLO": "MOLO CHAIN",
"MOLT": "Moltbook", "MOLT": "Moltbook",
"MOLTID": "MoltID", "MOLTID": "MoltID",
"MOM": "Mother of Memes", "MOM": "MOM",
"MOMA": "Mochi Market", "MOMA": "Mochi Market",
"MOMIJI": "MAGA Momiji", "MOMIJI": "MAGA Momiji",
"MOMO": "Momo", "MOMO": "Momo",
@ -11120,6 +11158,7 @@
"MOONEY": "Moon DAO", "MOONEY": "Moon DAO",
"MOONI": "MOON INU", "MOONI": "MOON INU",
"MOONION": "Moonions", "MOONION": "Moonions",
"MOONKIN": "MOONKIN",
"MOONKIZE": "MoonKize", "MOONKIZE": "MoonKize",
"MOONLIGHT": "Moonlight Token", "MOONLIGHT": "Moonlight Token",
"MOONPIG": "Moonpig", "MOONPIG": "Moonpig",
@ -11156,6 +11195,7 @@
"MOTG": "MetaOctagon", "MOTG": "MetaOctagon",
"MOTH": "MOTH", "MOTH": "MOTH",
"MOTHER": "Mother Iggy", "MOTHER": "Mother Iggy",
"MOTHEROFMEMES": "Mother of Memes",
"MOTI": "Motion", "MOTI": "Motion",
"MOTION": "motion", "MOTION": "motion",
"MOTIONCOIN": "Motion", "MOTIONCOIN": "Motion",
@ -12140,7 +12180,7 @@
"OEX": "OEX", "OEX": "OEX",
"OF": "OFCOIN", "OF": "OFCOIN",
"OFBC": "OneFinBank Coin", "OFBC": "OneFinBank Coin",
"OFC": "$OFC Coin", "OFC": "OneFootball Club",
"OFCR": "CryptoPolice", "OFCR": "CryptoPolice",
"OFE": "Ofero", "OFE": "Ofero",
"OFF": "BlastOff", "OFF": "BlastOff",
@ -12278,6 +12318,7 @@
"ONLINE": "Onlinebase", "ONLINE": "Onlinebase",
"ONLY": "OnlyCam", "ONLY": "OnlyCam",
"ONLYCUMIES": "OnlyCumies", "ONLYCUMIES": "OnlyCumies",
"ONLYFANSCOINS": "$OFC Coin",
"ONNO": "Onno Vault", "ONNO": "Onno Vault",
"ONOMY": "Onomy Protocol", "ONOMY": "Onomy Protocol",
"ONOT": "ONO", "ONOT": "ONO",
@ -12506,6 +12547,7 @@
"OXY2": "Cryptoxygen", "OXY2": "Cryptoxygen",
"OXYC": "Oxycoin", "OXYC": "Oxycoin",
"OYS": "Oyster Platform", "OYS": "Oyster Platform",
"OYSTERPEARL": "Oyster Pearl",
"OZG": "Ozagold", "OZG": "Ozagold",
"OZK": "OrdiZK", "OZK": "OrdiZK",
"OZMPC": "Ozempic", "OZMPC": "Ozempic",
@ -13021,7 +13063,6 @@
"PINMO": "Pinmo", "PINMO": "Pinmo",
"PINO": "Pinocchu", "PINO": "Pinocchu",
"PINS": "PINs Network Token", "PINS": "PINs Network Token",
"PINU": "Piccolo Inu",
"PINU100X": "Pi INU 100x", "PINU100X": "Pi INU 100x",
"PIO": "Pioneershares", "PIO": "Pioneershares",
"PIP": "Pip", "PIP": "Pip",
@ -13412,7 +13453,7 @@
"PRISMA": "Prisma Finance", "PRISMA": "Prisma Finance",
"PRIVIX": "Privix", "PRIVIX": "Privix",
"PRIX": "Privatix", "PRIX": "Privatix",
"PRL": "Oyster Pearl", "PRL": "Perle",
"PRM": "PrismChain", "PRM": "PrismChain",
"PRMX": "PREMA", "PRMX": "PREMA",
"PRNT": "Prime Numbers", "PRNT": "Prime Numbers",
@ -13442,6 +13483,7 @@
"PROTEO": "Proteo DeFi", "PROTEO": "Proteo DeFi",
"PROTO": "Protocon", "PROTO": "Protocon",
"PROTOCOLZ": "Protocol Zero", "PROTOCOLZ": "Protocol Zero",
"PROTOKEN": "Pro Token",
"PROTON": "Proton", "PROTON": "Proton",
"PROUD": "PROUD Money", "PROUD": "PROUD Money",
"PROVE": "Succinct", "PROVE": "Succinct",
@ -13540,6 +13582,7 @@
"PUMPB": "Pump", "PUMPB": "Pump",
"PUMPBTC": "pumpBTC", "PUMPBTC": "pumpBTC",
"PUMPBTCXYZ": "PumpBTC", "PUMPBTCXYZ": "PumpBTC",
"PUMPCADE": "PUMPCADE",
"PUMPFUNBAN": "Pump Fun Ban", "PUMPFUNBAN": "Pump Fun Ban",
"PUMPIT": "BOGDANOFF", "PUMPIT": "BOGDANOFF",
"PUMPTRUMP": "PUMP TRUMP", "PUMPTRUMP": "PUMP TRUMP",
@ -14058,6 +14101,7 @@
"RETSA": "Retsa Coin", "RETSA": "Retsa Coin",
"REU": "REUCOIN", "REU": "REUCOIN",
"REUNI": "Reunit Wallet", "REUNI": "Reunit Wallet",
"REUR": "Royal Euro",
"REUSDC": "Relend USDC", "REUSDC": "Relend USDC",
"REV": "Revain", "REV": "Revain",
"REV3L": "REV3AL", "REV3L": "REV3AL",
@ -14159,6 +14203,7 @@
"RIPTO": "RiptoBuX", "RIPTO": "RiptoBuX",
"RIS": "Riser", "RIS": "Riser",
"RISE": "EverRise", "RISE": "EverRise",
"RISECOIN": "Rise coin",
"RISEP": "Rise Protocol", "RISEP": "Rise Protocol",
"RISEVISION": "Rise", "RISEVISION": "Rise",
"RISITA": "Risitas", "RISITA": "Risitas",
@ -14166,6 +14211,7 @@
"RITE": "ritestream", "RITE": "ritestream",
"RITO": "Ritocoin", "RITO": "Ritocoin",
"RITZ": "Ritz.Game", "RITZ": "Ritz.Game",
"RIV": "RIV Coin",
"RIVER": "River", "RIVER": "River",
"RIVERPTS": "River Point Reward Token", "RIVERPTS": "River Point Reward Token",
"RIVUS": "RivusDAO", "RIVUS": "RivusDAO",
@ -14602,7 +14648,7 @@
"SBCH": "Smart Bitcoin Cash", "SBCH": "Smart Bitcoin Cash",
"SBE": "Sombe", "SBE": "Sombe",
"SBEFE": "BEFE", "SBEFE": "BEFE",
"SBET": "SBET", "SBET": "Sports Bet",
"SBF": "SBF In Jail", "SBF": "SBF In Jail",
"SBGO": "Bingo Share", "SBGO": "Bingo Share",
"SBIO": "Vector Space Biosciences, Inc.", "SBIO": "Vector Space Biosciences, Inc.",
@ -15410,6 +15456,7 @@
"SOLCAT": "CatSolHat", "SOLCAT": "CatSolHat",
"SOLCATMEME": "SOLCAT", "SOLCATMEME": "SOLCAT",
"SOLCEX": "SolCex", "SOLCEX": "SolCex",
"SOLCHAT": "Solchat",
"SOLCHICKSSHARDS": "SolChicks Shards", "SOLCHICKSSHARDS": "SolChicks Shards",
"SOLE": "SoleCoin", "SOLE": "SoleCoin",
"SOLER": "Solerium", "SOLER": "Solerium",
@ -15420,6 +15467,7 @@
"SOLFUN": "SolFun", "SOLFUN": "SolFun",
"SOLGOAT": "SOLGOAT", "SOLGOAT": "SOLGOAT",
"SOLGUN": "Solgun", "SOLGUN": "Solgun",
"SOLIB": "Solitaire Blossom",
"SOLIC": "Solice", "SOLIC": "Solice",
"SOLID": "Solidified", "SOLID": "Solidified",
"SOLIDSEX": "SOLIDsex: Tokenized veSOLID", "SOLIDSEX": "SOLIDsex: Tokenized veSOLID",
@ -15583,7 +15631,11 @@
"SPIDER": "Spider Man", "SPIDER": "Spider Man",
"SPIDERMAN": "SPIDERMAN BITCOIN", "SPIDERMAN": "SPIDERMAN BITCOIN",
"SPIDEY": "Spidey", "SPIDEY": "Spidey",
"SPIK": "Spike",
"SPIKE": "Spiking", "SPIKE": "Spiking",
"SPIKE1984": "Spike 1984",
"SPIKECOIN": "SPIKE",
"SPIKEFURIE": "SPIKE",
"SPILLWAYS": "SpillWays", "SPILLWAYS": "SpillWays",
"SPIN": "SPIN Protocol", "SPIN": "SPIN Protocol",
"SPINT": "Spintria", "SPINT": "Spintria",
@ -15591,6 +15643,7 @@
"SPITT": "Hawk Ttuuaahh", "SPITT": "Hawk Ttuuaahh",
"SPIZ": "SPACE-iZ", "SPIZ": "SPACE-iZ",
"SPK": "Spark", "SPK": "Spark",
"SPKI": "SPIKE INU",
"SPKL": "SpokLottery", "SPKL": "SpokLottery",
"SPKTR": "Ghost Coin", "SPKTR": "Ghost Coin",
"SPKY": "GhostyCash", "SPKY": "GhostyCash",
@ -15612,6 +15665,7 @@
"SPOOL": "Spool DAO Token", "SPOOL": "Spool DAO Token",
"SPORE": "Spore", "SPORE": "Spore",
"SPORT": "SportsCoin", "SPORT": "SportsCoin",
"SPORTBET": "SBET",
"SPORTFUN": "Sport.fun", "SPORTFUN": "Sport.fun",
"SPORTS": "ZenSports", "SPORTS": "ZenSports",
"SPORTSFIX": "SportsFix", "SPORTSFIX": "SportsFix",
@ -16571,6 +16625,7 @@
"TKX": "Tokenize Xchange", "TKX": "Tokenize Xchange",
"TKY": "THEKEY Token", "TKY": "THEKEY Token",
"TLC": "Trillioner", "TLC": "Trillioner",
"TLF": "Tradeleaf",
"TLM": "Alien Worlds", "TLM": "Alien Worlds",
"TLN": "Trustlines Network", "TLN": "Trustlines Network",
"TLOS": "Telos", "TLOS": "Telos",
@ -17075,6 +17130,7 @@
"UBQ": "Ubiq", "UBQ": "Ubiq",
"UBT": "UniBright", "UBT": "UniBright",
"UBTC": "UnitedBitcoin", "UBTC": "UnitedBitcoin",
"UBU": "UBU",
"UBX": "UBIX Network", "UBX": "UBIX Network",
"UBXN": "UpBots Token", "UBXN": "UpBots Token",
"UBXS": "UBXS", "UBXS": "UBXS",
@ -17169,6 +17225,7 @@
"UNBNK": "Unbanked", "UNBNK": "Unbanked",
"UNBREAKABLE": "UnbreakableCoin", "UNBREAKABLE": "UnbreakableCoin",
"UNC": "UnCoin", "UNC": "UnCoin",
"UNCEROID": "unc asteroid",
"UNCL": "UNCL", "UNCL": "UNCL",
"UNCN": "Unseen", "UNCN": "Unseen",
"UNCOMMONGOODS": "UNCOMMON•GOODS", "UNCOMMONGOODS": "UNCOMMON•GOODS",
@ -17241,6 +17298,7 @@
"UNRC": "UniversalRoyalCoin", "UNRC": "UniversalRoyalCoin",
"UNS": "UNS TOKEN", "UNS": "UNS TOKEN",
"UNSHETH": "unshETH Ether", "UNSHETH": "unshETH Ether",
"UNT": "Uni Token",
"UNW": "UniWorld", "UNW": "UniWorld",
"UOP": "Utopia Genesis Foundation", "UOP": "Utopia Genesis Foundation",
"UOS": "UOS", "UOS": "UOS",
@ -17296,7 +17354,7 @@
"USDAI": "USDai", "USDAI": "USDai",
"USDAP": "Bond Appetite USD", "USDAP": "Bond Appetite USD",
"USDAVALON": "USDa", "USDAVALON": "USDa",
"USDB": "USD Bancor", "USDB": "Blynex USD",
"USDBC": "Bridged USDC", "USDBC": "Bridged USDC",
"USDBLAST": "USDB Blast", "USDBLAST": "USDB Blast",
"USDC": "USD Coin", "USDC": "USD Coin",
@ -17412,13 +17470,14 @@
"UTNP": "Universa", "UTNP": "Universa",
"UTON": "uTON", "UTON": "uTON",
"UTOPIA": "Utopia", "UTOPIA": "Utopia",
"UTOPIAUSD": "Utopia USD",
"UTT": "uTrade", "UTT": "uTrade",
"UTU": "UTU Protocol", "UTU": "UTU Protocol",
"UTX": "UTIX", "UTX": "UTIX",
"UTYA": "Utya", "UTYA": "Utya",
"UTYAB": "Utya Black", "UTYAB": "Utya Black",
"UUC": "USA Unity Coin", "UUC": "USA Unity Coin",
"UUSD": "Utopia USD", "UUSD": "Unity USD",
"UUU": "U Network", "UUU": "U Network",
"UVT": "UvToken", "UVT": "UvToken",
"UW3S": "Utility Web3Shot", "UW3S": "Utility Web3Shot",
@ -17621,7 +17680,8 @@
"VIKKY": "VikkyToken", "VIKKY": "VikkyToken",
"VILADY": "Vitalik Milady", "VILADY": "Vitalik Milady",
"VIM": "VicMove", "VIM": "VicMove",
"VIN": "VinChain", "VIN": "VulgarTycoon",
"VINCHAIN": "VinChain",
"VINCI": "VINCI", "VINCI": "VINCI",
"VINE": "Vine Coin", "VINE": "Vine Coin",
"VINU": "Vita Inu", "VINU": "Vita Inu",
@ -17716,6 +17776,7 @@
"VOL": "Volume Network", "VOL": "Volume Network",
"VOLBOOST": "VolBoost", "VOLBOOST": "VolBoost",
"VOLLAR": "Vollar", "VOLLAR": "Vollar",
"VOLM": "VOLM",
"VOLR": "Volare Network", "VOLR": "Volare Network",
"VOLT": "Volt Inu", "VOLT": "Volt Inu",
"VOLTA": "Volta Club", "VOLTA": "Volta Club",
@ -18488,6 +18549,7 @@
"XCG": "Xchange", "XCG": "Xchange",
"XCH": "Chia", "XCH": "Chia",
"XCHAT": "XChat", "XCHAT": "XChat",
"XCHATSOL": "XChat",
"XCHF": "CryptoFranc", "XCHF": "CryptoFranc",
"XCHNG": "Chainge Finance", "XCHNG": "Chainge Finance",
"XCI": "Cannabis Industry Coin", "XCI": "Cannabis Industry Coin",
@ -18543,6 +18605,7 @@
"XENOVERSE": "Xenoverse", "XENOVERSE": "Xenoverse",
"XEP": "Electra Protocol", "XEP": "Electra Protocol",
"XERA": "XERA", "XERA": "XERA",
"XERO": "XERO",
"XERS": "X Project", "XERS": "X Project",
"XES": "Proxeus", "XES": "Proxeus",
"XET": "Xfinite Entertainment Token", "XET": "Xfinite Entertainment Token",

7
apps/api/src/services/data-provider/data-provider.service.ts

@ -12,6 +12,7 @@ import {
PROPERTY_DATA_SOURCE_MAPPING PROPERTY_DATA_SOURCE_MAPPING
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { CreateOrderDto } from '@ghostfolio/common/dtos'; import { CreateOrderDto } from '@ghostfolio/common/dtos';
import { SubscriptionType } from '@ghostfolio/common/enums';
import { import {
DATE_FORMAT, DATE_FORMAT,
getAssetProfileIdentifier, getAssetProfileIdentifier,
@ -227,7 +228,7 @@ export class DataProviderService implements OnModuleInit {
if ( if (
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
user.subscription.type === 'Basic' user.subscription.type === SubscriptionType.Basic
) { ) {
const dataProvider = this.getDataProvider(DataSource[dataSource]); const dataProvider = this.getDataProvider(DataSource[dataSource]);
@ -591,7 +592,7 @@ export class DataProviderService implements OnModuleInit {
} else if ( } else if (
dataProvider.getDataProviderInfo().isPremium && dataProvider.getDataProviderInfo().isPremium &&
this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') && this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION') &&
user?.subscription.type === 'Basic' user?.subscription.type === SubscriptionType.Basic
) { ) {
// Skip symbols of Premium data providers for users without subscription // Skip symbols of Premium data providers for users without subscription
return false; return false;
@ -780,7 +781,7 @@ export class DataProviderService implements OnModuleInit {
}) })
.map((lookupItem) => { .map((lookupItem) => {
if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) {
if (user.subscription.type === 'Premium') { if (user.subscription.type === SubscriptionType.Premium) {
lookupItem.dataProviderInfo.isPremium = false; lookupItem.dataProviderInfo.isPremium = false;
} }

7
apps/client/src/app/components/admin-overview/admin-overview.component.ts

@ -8,7 +8,10 @@ import {
PROPERTY_SYSTEM_MESSAGE, PROPERTY_SYSTEM_MESSAGE,
ghostfolioPrefix ghostfolioPrefix
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import {
ConfirmationDialogType,
SubscriptionType
} from '@ghostfolio/common/enums';
import { getDateFnsLocale } from '@ghostfolio/common/helper'; import { getDateFnsLocale } from '@ghostfolio/common/helper';
import { import {
Coupon, Coupon,
@ -255,7 +258,7 @@ export class GfAdminOverviewComponent implements OnInit {
this.systemMessage ?? this.systemMessage ??
({ ({
message: '⚒️ Scheduled maintenance in progress...', message: '⚒️ Scheduled maintenance in progress...',
targetGroups: ['Basic', 'Premium'] targetGroups: [SubscriptionType.Basic, SubscriptionType.Premium]
} as SystemMessage) } as SystemMessage)
) )
); );

5
apps/client/src/app/pages/portfolio/fire/fire-page.component.ts

@ -1,5 +1,6 @@
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service'; import { UserService } from '@ghostfolio/client/services/user/user.service';
import { SubscriptionType } from '@ghostfolio/common/enums';
import { import {
FireCalculationCompleteEvent, FireCalculationCompleteEvent,
FireWealth, FireWealth,
@ -80,7 +81,7 @@ export class GfFirePageComponent implements OnInit {
: 0 : 0
} }
}; };
if (this.user.subscription?.type === 'Basic') { if (this.user.subscription?.type === SubscriptionType.Basic) {
this.fireWealth = { this.fireWealth = {
today: { today: {
valueInBaseCurrency: 10000 valueInBaseCurrency: 10000
@ -113,7 +114,7 @@ export class GfFirePageComponent implements OnInit {
this.user = state.user; this.user = state.user;
this.hasPermissionToUpdateUserSettings = this.hasPermissionToUpdateUserSettings =
this.user.subscription?.type === 'Basic' this.user.subscription?.type === SubscriptionType.Basic
? false ? false
: hasPermission( : hasPermission(
this.user.permissions, this.user.permissions,

3
apps/client/src/app/pages/portfolio/x-ray/x-ray-page.component.ts

@ -2,6 +2,7 @@ import { GfRulesComponent } from '@ghostfolio/client/components/rules/rules.comp
import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service'; import { UserService } from '@ghostfolio/client/services/user/user.service';
import { UpdateUserSettingDto } from '@ghostfolio/common/dtos'; import { UpdateUserSettingDto } from '@ghostfolio/common/dtos';
import { SubscriptionType } from '@ghostfolio/common/enums';
import { import {
PortfolioReportResponse, PortfolioReportResponse,
PortfolioReportRule PortfolioReportRule
@ -73,7 +74,7 @@ export class GfXRayPageComponent {
this.user = state.user; this.user = state.user;
this.hasPermissionToUpdateUserSettings = this.hasPermissionToUpdateUserSettings =
this.user.subscription?.type === 'Basic' this.user.subscription?.type === SubscriptionType.Basic
? false ? false
: hasPermission( : hasPermission(
this.user.permissions, this.user.permissions,

7
apps/client/src/assets/oss-friends.json

@ -1,5 +1,5 @@
{ {
"createdAt": "2025-12-08T00:00:00.000Z", "createdAt": "2026-04-21T00:00:00.000Z",
"data": [ "data": [
{ {
"name": "Activepieces", "name": "Activepieces",
@ -21,11 +21,6 @@
"description": "Fastest LLM gateway with adaptive load balancer, cluster mode, guardrails, 1000+ models support & <100 µs overhead at 5k RPS.", "description": "Fastest LLM gateway with adaptive load balancer, cluster mode, guardrails, 1000+ models support & <100 µs overhead at 5k RPS.",
"href": "https://www.getmaxim.ai/bifrost" "href": "https://www.getmaxim.ai/bifrost"
}, },
{
"name": "Cal.com",
"description": "Cal.com is a scheduling tool that helps you schedule meetings without the back-and-forth emails.",
"href": "https://cal.com"
},
{ {
"name": "Cap", "name": "Cap",
"description": "Cap is the open source alternative to Loom. Lightweight, powerful, and cross-platform. Record and share securely in seconds.", "description": "Cap is the open source alternative to Loom. Lightweight, powerful, and cross-platform. Record and share securely in seconds.",

3707
package-lock.json

File diff suppressed because it is too large

42
package.json

@ -76,15 +76,15 @@
"@keyv/redis": "4.4.0", "@keyv/redis": "4.4.0",
"@nestjs/bull": "11.0.4", "@nestjs/bull": "11.0.4",
"@nestjs/cache-manager": "3.1.0", "@nestjs/cache-manager": "3.1.0",
"@nestjs/common": "11.1.14", "@nestjs/common": "11.1.19",
"@nestjs/config": "4.0.3", "@nestjs/config": "4.0.4",
"@nestjs/core": "11.1.14", "@nestjs/core": "11.1.19",
"@nestjs/event-emitter": "3.0.1", "@nestjs/event-emitter": "3.0.1",
"@nestjs/jwt": "11.0.2", "@nestjs/jwt": "11.0.2",
"@nestjs/passport": "11.0.5", "@nestjs/passport": "11.0.5",
"@nestjs/platform-express": "11.1.14", "@nestjs/platform-express": "11.1.19",
"@nestjs/schedule": "6.1.1", "@nestjs/schedule": "6.1.3",
"@nestjs/serve-static": "5.0.4", "@nestjs/serve-static": "5.0.5",
"@openrouter/ai-sdk-provider": "0.7.2", "@openrouter/ai-sdk-provider": "0.7.2",
"@prisma/adapter-pg": "7.7.0", "@prisma/adapter-pg": "7.7.0",
"@prisma/client": "7.7.0", "@prisma/client": "7.7.0",
@ -107,7 +107,7 @@
"cookie-parser": "1.4.7", "cookie-parser": "1.4.7",
"countries-and-timezones": "3.8.0", "countries-and-timezones": "3.8.0",
"countries-list": "3.3.0", "countries-list": "3.3.0",
"countup.js": "2.9.0", "countup.js": "2.10.0",
"date-fns": "4.1.0", "date-fns": "4.1.0",
"dotenv": "17.2.3", "dotenv": "17.2.3",
"dotenv-expand": "12.0.3", "dotenv-expand": "12.0.3",
@ -118,7 +118,7 @@
"helmet": "7.0.0", "helmet": "7.0.0",
"http-status-codes": "2.3.0", "http-status-codes": "2.3.0",
"ionicons": "8.0.13", "ionicons": "8.0.13",
"jsonpath": "1.2.1", "jsonpath": "1.3.0",
"lodash": "4.18.1", "lodash": "4.18.1",
"marked": "17.0.2", "marked": "17.0.2",
"ms": "3.0.0-canary.1", "ms": "3.0.0-canary.1",
@ -156,18 +156,18 @@
"@angular/pwa": "21.2.6", "@angular/pwa": "21.2.6",
"@eslint/eslintrc": "3.3.1", "@eslint/eslintrc": "3.3.1",
"@eslint/js": "9.35.0", "@eslint/js": "9.35.0",
"@nestjs/schematics": "11.0.9", "@nestjs/schematics": "11.1.0",
"@nestjs/testing": "11.1.14", "@nestjs/testing": "11.1.19",
"@nx/angular": "22.6.4", "@nx/angular": "22.6.5",
"@nx/eslint-plugin": "22.6.4", "@nx/eslint-plugin": "22.6.5",
"@nx/jest": "22.6.4", "@nx/jest": "22.6.5",
"@nx/js": "22.6.4", "@nx/js": "22.6.5",
"@nx/module-federation": "22.6.4", "@nx/module-federation": "22.6.5",
"@nx/nest": "22.6.4", "@nx/nest": "22.6.5",
"@nx/node": "22.6.4", "@nx/node": "22.6.5",
"@nx/storybook": "22.6.4", "@nx/storybook": "22.6.5",
"@nx/web": "22.6.4", "@nx/web": "22.6.5",
"@nx/workspace": "22.6.4", "@nx/workspace": "22.6.5",
"@schematics/angular": "21.2.6", "@schematics/angular": "21.2.6",
"@storybook/addon-docs": "10.1.10", "@storybook/addon-docs": "10.1.10",
"@storybook/angular": "10.1.10", "@storybook/angular": "10.1.10",
@ -193,7 +193,7 @@
"jest": "30.2.0", "jest": "30.2.0",
"jest-environment-jsdom": "30.2.0", "jest-environment-jsdom": "30.2.0",
"jest-preset-angular": "16.0.0", "jest-preset-angular": "16.0.0",
"nx": "22.6.4", "nx": "22.6.5",
"prettier": "3.8.2", "prettier": "3.8.2",
"prettier-plugin-organize-attributes": "1.0.0", "prettier-plugin-organize-attributes": "1.0.0",
"prisma": "7.7.0", "prisma": "7.7.0",

Loading…
Cancel
Save