Skip to content

### [FRONTEND-01] Replace Raw window.freighter Calls with a Typed Freighter Service Abstraction #428

Description

@orunganiekan

Points: 200
Labels: frontend, architecture, freighter, typescript, dx
Background: window.freighter is accessed directly throughout useWallet.ts using a hand-rolled declare global interface that was last updated to match an older Freighter API. The @stellar/freighter-api package (the official typed wrapper) is not used. This means: (1) the TypeScript types are manually maintained and drift silently from the actual extension API, (2) there is no single injection point where Freighter calls can be mocked in tests — every test that touches useWallet must patch window.freighter directly, (3) there is no handling for the @freighter-api/v2 manifest format that newer Freighter versions expose. The useWallet.ts tests at frontend/src/__tests__/useFreighterAvailable.test.tsx already mock window.freighter in an ad-hoc way, confirming the fragility.

Task: Create frontend/src/services/freighter.ts exporting a FreighterService class with typed methods: isConnected(): Promise<boolean>, getPublicKey(): Promise<string>, getNetwork(): Promise<{ network: string; networkPassphrase: string }>, signTransaction(xdr: string, opts: { networkPassphrase: string }): Promise<string>. Internally wrap window.freighter calls with runtime presence checks and throw a typed FreighterNotAvailableError (a custom Error subclass) rather than returning raw strings. Update useWallet.ts to consume FreighterService exclusively — remove the declare global block. Update useNetworkCheck.ts and useFreighterAvailable.ts to use FreighterService. Export a singleton freighterService instance as the default import.

Key files: - frontend/src/services/freighter.ts — new file; FreighterService class + FreighterNotAvailableError

  • frontend/src/hooks/useWallet.ts — remove declare global; use freighterService
  • frontend/src/hooks/useNetworkCheck.ts — replace window.freighter calls
  • frontend/src/hooks/useFreighterAvailable.ts — replace window.freighter calls
  • frontend/src/__tests__/useFreighterAvailable.test.tsx — update mocks to use vi.mock('../services/freighter')

Acceptance criteria: - [ ] FreighterService class with all 4 methods, fully typed with no any

  • FreighterNotAvailableError extends Error with a name: 'FreighterNotAvailableError' property
  • Zero window.freighter references outside services/freighter.ts
  • Zero declare global blocks in hook files
  • All existing tests in useFreighterAvailable.test.tsx pass after mock update
  • npm run typecheck passes with no errors

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions