fix(wallet): wire websocket config through module install #163

Merged
padreug merged 1 commit from fix/wallet-websocket-config into dev 2026-09-22 21:06:10 +00:00
2 changed files with 40 additions and 18 deletions
Showing only changes of commit a62af8bd16 - Show all commits

fix(wallet): wire websocket config through module install

Every websocket setting in `app.config.ts` was ignored. The service read
`(window as any).appConfig`, which nothing in the codebase ever assigns,
so the lookup was always undefined and the service silently ran on its
own hardcoded defaults — including `VITE_WEBSOCKET_ENABLED`, which could
not actually disable the websocket.

The config was already being passed correctly: `src/wallet-app/app.ts`
registers the module with `appConfig.modules.wallet`, and the plugin
manager forwards it as `install(app, { config })`. The service just
wasn't reading from there. It now takes the config through its
constructor, merged over an exported `DEFAULT_WEBSOCKET_CONFIG`.

Using install options rather than importing `@/app.config` directly
matters here: the hub config no longer declares a wallet module at all
(the wallet ships only as a standalone PWA), so a direct import would
resolve to a config with no wallet section.

Verified in the built bundle: `maxReconnectAttempts:3` from
`src/wallet-app/app.config.ts` is present alongside the default of 5,
and no `window.appConfig` read remains.
Padreug 2026-09-22 22:44:26 +02:00

View file

@ -2,18 +2,34 @@ import type { App } from 'vue'
import type { ModulePlugin } from '@/core/types' import type { ModulePlugin } from '@/core/types'
import { container, SERVICE_TOKENS } from '@/core/di-container' import { container, SERVICE_TOKENS } from '@/core/di-container'
import WalletService from './services/WalletService' import WalletService from './services/WalletService'
import { WalletWebSocketService } from './services/WalletWebSocketService' import { WalletWebSocketService, type WebSocketConfig } from './services/WalletWebSocketService'
import { WalletPage, SendDialog, ReceiveDialog, WalletTransactions } from './components' import { WalletPage, SendDialog, ReceiveDialog, WalletTransactions } from './components'
export interface WalletModuleConfig {
defaultReceiveAmount?: number
maxReceiveAmount?: number
apiConfig?: { baseUrl?: string }
websocket?: Partial<WebSocketConfig>
}
export const walletModule: ModulePlugin = { export const walletModule: ModulePlugin = {
name: 'wallet', name: 'wallet',
version: '1.0.0', version: '1.0.0',
dependencies: ['base'], dependencies: ['base'],
async install(app: App) { async install(app: App, options?: { config?: WalletModuleConfig }) {
// Create service instances // Create service instances.
//
// The WebSocket config is forwarded from the module registration
// (`pluginManager.register(walletModule, appConfig.modules.wallet)` in
// `src/wallet-app/app.ts`). The service previously tried to read
// `window.appConfig`, which nothing ever assigns, so it silently ran on
// its built-in defaults and every value in `app.config.ts` — including
// `VITE_WEBSOCKET_ENABLED` — was ignored.
const walletService = new WalletService() const walletService = new WalletService()
const walletWebSocketService = new WalletWebSocketService() const walletWebSocketService = new WalletWebSocketService(
options?.config?.websocket ?? {}
)
// Register services in DI container BEFORE initialization // Register services in DI container BEFORE initialization
container.provide(SERVICE_TOKENS.WALLET_SERVICE, walletService) container.provide(SERVICE_TOKENS.WALLET_SERVICE, walletService)

View file

@ -5,7 +5,7 @@ import { eventBus } from '@/core/event-bus'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { ref } from 'vue' import { ref } from 'vue'
interface WebSocketConfig { export interface WebSocketConfig {
enabled: boolean enabled: boolean
reconnectDelay: number reconnectDelay: number
maxReconnectAttempts: number maxReconnectAttempts: number
@ -13,6 +13,14 @@ interface WebSocketConfig {
pollingInterval: number pollingInterval: number
} }
const DEFAULT_WEBSOCKET_CONFIG: WebSocketConfig = {
enabled: true,
reconnectDelay: 1000,
maxReconnectAttempts: 5,
fallbackToPolling: true,
pollingInterval: 10000 // 10 seconds
}
export class WalletWebSocketService extends BaseService { export class WalletWebSocketService extends BaseService {
protected readonly metadata = { protected readonly metadata = {
name: 'WalletWebSocketService', name: 'WalletWebSocketService',
@ -27,12 +35,16 @@ export class WalletWebSocketService extends BaseService {
private stabilityTimer: NodeJS.Timeout | null = null private stabilityTimer: NodeJS.Timeout | null = null
private usingPollingFallback = false private usingPollingFallback = false
private consecutiveFailures = 0 private consecutiveFailures = 0
private config: WebSocketConfig = { private config: WebSocketConfig
enabled: true,
reconnectDelay: 1000, /**
maxReconnectAttempts: 5, * @param config Partial overrides from the wallet module's `app.config.ts`,
fallbackToPolling: true, * forwarded by the module's `install()`. Anything omitted falls back to
pollingInterval: 10000 // 10 seconds * `DEFAULT_WEBSOCKET_CONFIG`.
*/
constructor(config: Partial<WebSocketConfig> = {}) {
super()
this.config = { ...DEFAULT_WEBSOCKET_CONFIG, ...config }
} }
// Service dependencies (auto-injected by BaseService) // Service dependencies (auto-injected by BaseService)
@ -57,13 +69,7 @@ export class WalletWebSocketService extends BaseService {
walletService: !!this.walletService walletService: !!this.walletService
}) })
// Load config from app config if available console.log('WalletWebSocketService: Config', this.config)
const appConfig = (window as any).appConfig
if (appConfig?.modules?.wallet?.config?.websocket) {
this.config = { ...this.config, ...appConfig.modules.wallet.config.websocket }
}
console.log('WalletWebSocketService: Config loaded', this.config)
// Only proceed if WebSocket is enabled // Only proceed if WebSocket is enabled
if (!this.config.enabled) { if (!this.config.enabled) {