Problem
Transaction signing is duplicated and stubbed across the app instead of
living in one service. Vouch.tsx signs a fake placeholder XDR (#55),
Vouch.handleDecline simulates the call with setTimeout (#66), and sponsor
onboarding step 4 has no real deposit flow (#56). Every feature reinvents —
and fakes — the build → sign → submit → poll sequence, so no real contract
transaction is ever completed from the web app.
Before Starting
Read ALL of these before writing any code:
- context/architecture-context.md
- context/code-standards.md
What To Build
A single transaction service that owns the full lifecycle behind a wallet
adapter:
- Request the unsigned XDR from the API services layer (never build
contract calls in components).
- Sign via a pluggable wallet adapter (Freighter / Albedo /
StellarWalletsKit) resolved from wallet.store.
- Submit and poll transaction status to resolution, returning a typed
result with discriminated error states (rejected, expired, failed,
insufficient funds).
- Surface a shared
useTransaction hook driving pending / signing /
submitted / confirmed / error UI, and replace the fake flows in Vouch and
Sponsors with it.
Files To Touch
- src/services/transaction.service.ts (new)
- src/hooks/useTransaction.ts (extend existing)
- src/stores/wallet.store.ts
- src/pages/Vouch.tsx, src/pages/Sponsors.tsx (replace stubs)
Acceptance Criteria
Mandatory Checks Before Opening PR
Problem
Transaction signing is duplicated and stubbed across the app instead of
living in one service. Vouch.tsx signs a fake placeholder XDR (#55),
Vouch.handleDeclinesimulates the call withsetTimeout(#66), and sponsoronboarding step 4 has no real deposit flow (#56). Every feature reinvents —
and fakes — the build → sign → submit → poll sequence, so no real contract
transaction is ever completed from the web app.
Before Starting
Read ALL of these before writing any code:
What To Build
A single transaction service that owns the full lifecycle behind a wallet
adapter:
contract calls in components).
StellarWalletsKit) resolved from
wallet.store.result with discriminated error states (rejected, expired, failed,
insufficient funds).
useTransactionhook driving pending / signing /submitted / confirmed / error UI, and replace the fake flows in Vouch and
Sponsors with it.
Files To Touch
Acceptance Criteria
Mandatory Checks Before Opening PR