From 044170aded67502184dd6bf2a21538e714507af4 Mon Sep 17 00:00:00 2001 From: Daniele Ricci Date: Fri, 3 Oct 2025 18:28:56 +0200 Subject: [PATCH] feat: add FF_OVERRIDE env variable to locally override feature flags --- apps/browser-extension-wallet/.env.example | 3 +++ .../client/PostHogClient.ts | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/apps/browser-extension-wallet/.env.example b/apps/browser-extension-wallet/.env.example index 309631fcf8..17dca29b50 100644 --- a/apps/browser-extension-wallet/.env.example +++ b/apps/browser-extension-wallet/.env.example @@ -120,3 +120,6 @@ SESSION_TIMEOUT=300000 # mempool.space api MEMPOOLSPACE_URL=https://mempool.lw.iog.io + +# Local feature flags override +FF_OVERRIDE='{"notifications-center": false}' diff --git a/apps/browser-extension-wallet/src/providers/PostHogClientProvider/client/PostHogClient.ts b/apps/browser-extension-wallet/src/providers/PostHogClientProvider/client/PostHogClient.ts index 3ede63af00..5ea9b12359 100644 --- a/apps/browser-extension-wallet/src/providers/PostHogClientProvider/client/PostHogClient.ts +++ b/apps/browser-extension-wallet/src/providers/PostHogClientProvider/client/PostHogClient.ts @@ -45,6 +45,10 @@ const isNetworkOfExpectedSchema = (n: string): n is NetworksEnumSchema => networ const logger = contextLogger(commonLogger, 'PostHogClient'); +const FALSY_VALUES = ['false', 'False', 'FALSE', 'f', 'F', '0', 0, false]; +const TRUTHY_VALUES = ['true', 'True', 'TRUE', 't', 'T', '1', 1, true]; +const VALID_VALUES = new Set([...FALSY_VALUES, ...TRUTHY_VALUES]); + /** * PostHog API reference: * https://posthog.com/docs/libraries/js @@ -56,6 +60,7 @@ export class PostHogClient { hasPostHogInitialized$ = new BehaviorSubject(false); featureFlagsByNetwork: FeatureFlagsByNetwork = featureFlagsByNetworkInitialValue; featureFlagPayloads: FeatureFlagPayloads = featureFlagPayloadsInitialValue; + private ffOverride: Record = {}; constructor( private chain: Wallet.Cardano.ChainId, @@ -66,6 +71,18 @@ export class PostHogClient { ) { if (!this.postHogHost) throw new Error('POSTHOG_HOST url has not been provided'); void this.initialize(); + + if (typeof process.env.FF_OVERRIDE === 'string') + try { + const ffOverride = JSON.parse(process.env.FF_OVERRIDE) as Record; + + for (const [key, value] of Object.entries(ffOverride)) { + if (VALID_VALUES.has(value)) this.ffOverride[key] = TRUTHY_VALUES.includes(value); + else commonLogger.error(`Invalid value for FF_OVERRIDE[${key}]: "${value}"`); + } + } catch (error) { + commonLogger.error('While parsing FF_OVERRIDE', error); + } } private async initialize() { @@ -224,6 +241,8 @@ export class PostHogClient { } isFeatureFlagEnabled(feature: FeatureFlag): boolean { + if (feature in this.ffOverride) return this.ffOverride[feature]; + const currentNetworkFeatureFlags = this.featureFlagsByNetwork[this.chain.networkMagic as Wallet.Cardano.NetworkMagics]; return currentNetworkFeatureFlags[feature] || false;