This document defines the architecture of the Heliobond investor application and maps each user surface to its corresponding Stellar / Soroban smart contract dependencies, data models, and client functions.
Implementation Note & Scope: Heliobond is architected to operate in two modes:
- Live On-Chain Mode (Soroban Testnet): When
NEXT_PUBLIC_VAULT_CONTRACT_IDand wallet connections are active, core vault accounting (share_price,total_assets) and transactional flows (deposit,withdraw) execute directly against deployed Soroban smart contracts.- Simulated / Fixture Mode: When contract IDs are unset or in demo wallet mode, the application falls back gracefully to deterministic typed fixtures (
src/data.ts,src/data/*) and synchronous client simulations (src/wallet/vault.ts).Several contract surfaces (notably
ProjectRegistry,WhitelistController, and oracle administrative mutations) represent future/planned on-chain counterparts and are currently backed by local fixtures or internal in-memory state. They must not be presented as fully deployed on-chain contracts.
The investment pool is governed by Soroban smart contract logic mirroring ERC-4626 tokenized vault standards on Stellar (denominated in USDC with HBS pool share tokens). The frontend client layer is implemented in src/wallet/vault.ts and consumed by src/wallet/useVault.ts.
| Contract Method / Concept | Client Function / Binding | Type | Description |
|---|---|---|---|
share_price |
fetchSharePrice(sourceAddress) |
View Read | Reads total assets / total supply ratio via Soroban RPC simulation. Fallback: vault.sharePrice(). |
total_assets |
fetchTotalAssets(sourceAddress) |
View Read | Reads total USDC controlled by the vault via Soroban RPC simulation. Fallback: HB_DATA.pool.totalAssets. |
convert_to_shares |
vault.convertToShares(usdc)vault.previewDeposit(usdc) |
Client Math / Sim | Converts USDC amount to equivalent HBS shares based on current share_price for immediate input preview. |
convert_to_assets |
vault.convertToAssets(shares)vault.previewWithdraw(usdc) |
Client Math / Sim | Converts HBS shares to equivalent USDC asset value based on share_price. |
deposit |
submitDeposit(amount, address, sign, signal) |
Signed Tx | Builds transaction invoking contract deposit(amount, min_shares), simulates via RPC, requests wallet signature, submits to network, and polls confirmation. |
withdraw |
submitWithdraw(amount, address, sign, signal) |
Signed Tx | Builds transaction invoking contract withdraw(shares, min_assets), simulates, requests wallet signature, submits, and polls confirmation. |
- Route:
/(src/screens/Landing.tsx) - Current Data Source: Mock / fixture data (
HB_DATA.poolinsrc/data.ts). - Expected Soroban Read Dependency:
InvestmentVault.total_assets: Total pool value ($ TVL).InvestmentVault.share_price: Price per HBS share (for return rate projections).ProjectRegistry.get_projects/get_project_count: Number of active funded projects (determines particle/mote density on the WebGLLiveHelioorb).
- Expected Soroban Write Dependency: None (public informational surface).
- Relevant Vault / Client Function:
fetchTotalAssets,useVault(),LiveHelio.
- Route:
/connect(src/screens/Connect.tsx) - Current Data Source: Live wallet integration via
@creit.tech/stellar-wallets-kit(src/wallet/WalletProvider.tsx) with fallback demo session (connectDemo). - Expected Soroban Read Dependency:
- Stellar Horizon / RPC account check: Validates account existence, sequence number, native XLM balance (for transaction fees), and SAC USDC trustline / balance.
- Expected Soroban Write Dependency: None during initial connection (wallet session handshake).
- Relevant Vault / Client Function:
useWallet().connect(),useWallet().connectDemo(),useWallet().sign().
- Route:
/explore(src/screens/Explore.tsx) - Current Data Source: Mock / fixture data (
HB_DATA.projects) with optional REST API fallback (src/lib/api.tsgetProjects()). - Expected Soroban Read Dependency:
ProjectRegistry.list_projects(): Listing of all registered green energy projects, project metadata (location, type, funding goal, capital deployed).Oracle / ProjectRegistry: Current oracle-verifiedcredit(Credit Quality, 0–100) andgreen(Green Impact, 0–100) scores.
- Expected Soroban Write Dependency: None (filtering and browsing).
- Relevant Vault / Client Function:
getProjects()(currently REST/fixture client; future on-chain registry reader).
- Route:
/project/[id](src/screens/ProjectDetail.tsx) - Current Data Source: Fixture data (
PROJECT_DETAILSinsrc/data/projectDetails.ts,HB_DATA.projects) or API client (src/lib/api.tsgetProject(id)). - Expected Soroban Read Dependency:
ProjectRegistry.get_project(id): Detailed project profile, verified creator attribution, stated funding goal, and pool capital allocated.ProjectRegistry.get_score_history(id)/Oracleevents: Historical credit & green score data points and associated Stellar transaction hashes.InvestmentVaultmilestone events: Drawdown history and capital releases from the pool to the project.
- Expected Soroban Write Dependency: None directly on page view (primary CTA navigates to
/deposit). - Relevant Vault / Client Function:
getProject(id)(future Soroban project & oracle history query).
- Route:
/deposit(src/screens/Deposit.tsx) - Current Data Source: Active Soroban contract integration when
NEXT_PUBLIC_VAULT_CONTRACT_IDis set; synchronous simulation in demo mode or without env configuration. - Expected Soroban Read Dependency:
InvestmentVault.share_price: Live share price to calculate expected HBS output.InvestmentVault.total_assets: Vault TVL for pool-level metrics.InvestmentVault.convert_to_shares: Real-time conversion preview calculation.
- Expected Soroban Write Dependency:
InvestmentVault.deposit(amount, min_shares): Transfers USDC from investor account into the vault, mints corresponding HBS shares to the investor.
- Relevant Vault / Client Function:
- Read / Preview:
fetchSharePrice,fetchTotalAssets,vault.convertToShares,vault.previewDeposit,useVault(). - Transaction:
submitDeposit(amount, address, sign, signal).
- Read / Preview:
- Route:
/portfolio(src/screens/Portfolio.tsx) - Current Data Source: Mock / fixture data (
HB_DATA.you,HB_DATA.activity,HB_DATA.poolinsrc/data.ts) when connected. - Expected Soroban Read Dependency:
InvestmentVault.balance(user_address): User HBS share token balance.InvestmentVault.convert_to_assets(shares): Current USDC valuation of user holdings.InvestmentVault.total_assets&share_price: Calculation of user's percentage share of the pool.InvestmentVault.get_liquid_assets(): Pool-wide liquid reserves vs. deployed assets (displayed viaLiquidityMeter).- Indexer / Horizon Event stream: User deposit/withdrawal history and oracle score updates.
- Expected Soroban Write Dependency: None on portfolio view (action buttons route to
/depositand/withdraw). - Relevant Vault / Client Function:
vault.convertToAssets,useVault(), future user account position reader.
- Route:
/withdraw(src/screens/Withdraw.tsx) - Current Data Source: Active Soroban contract integration when
NEXT_PUBLIC_VAULT_CONTRACT_IDis set; simulated 2-second delay in demo mode. Liquid cap is currently fixture-backed (liquid = 236). - Expected Soroban Read Dependency:
InvestmentVault.share_price: Live exchange rate for asset conversion.InvestmentVault.convert_to_assets: Share redemption preview.InvestmentVault.max_withdraw/ available liquid reserve: Enforces the immediate withdrawal ceiling to respect pool liquidity constraints.
- Expected Soroban Write Dependency:
InvestmentVault.withdraw(shares, min_assets): Burns HBS shares from the caller and transfers equivalent USDC assets to the caller's wallet.
- Relevant Vault / Client Function:
- Read / Preview:
vault.convertToAssets,vault.previewWithdraw. - Transaction:
submitWithdraw(amount, address, sign, signal).
- Read / Preview:
- Route:
/creator(src/screens/creator/*) - Current Data Source: Mock / fixture data (
CREATOR_APPLICATION,DRAFT_PROJECT,CREATOR_DASHBOARDinsrc/data/creator.ts). Form submission updates local state. - Expected Soroban Read Dependency:
WhitelistController.get_status(creator_address): Creator whitelist stage (submitted,in_review,approved).ProjectRegistry.get_creator_projects(creator_address): Existing projects owned by the creator.Oracle / ProjectRegistry: Creator project oracle scores (creditScore,greenScore), score history sparklines, evaluation factors, and recent verified updates.InvestmentVault: Funding deployed to the creator's project vs. stated funding goal.
- Expected Soroban Write Dependency (Future Counterparts):
WhitelistController.apply_whitelist(org_name, project_type, location, links): Submit creator onboarding application.ProjectRegistry.create_project(name, location, project_type, story_uri, funding_goal): Register a new project draft.
- Relevant Vault / Client Function: Future
CreatorClient/WhitelistClient(currently typed fixture models insrc/data/creator.ts).
- Route:
/admin(src/screens/admin/*) - Current Data Source: Internal console using fixture data (
VAULT_STATS,REGISTRY,WHITELISTinsrc/data/admin.ts) with interactive in-memory state mutations. - Expected Soroban Read Dependency:
InvestmentVault: Privileged accounting views (total_assets,share_price,hbs_supply,liquid,deployed,projects_funded).ProjectRegistry.list_all_projects(): Complete project registry with last-verified timestamps.WhitelistController.list_creators(): Registered creators and approval statuses.
- Expected Soroban Write Dependency (Future Counterparts):
Oracle.push_scores(project_id, credit, green): Oracle score updates written to the registry.InvestmentVault.fund_project(project_id, amount): Privileged contract call deploying idle liquid vault USDC to a project.WhitelistController.set_creator_status(address, status): Approving or revoking creator whitelist permissions.
- Relevant Vault / Client Function: Future privileged
AdminClient/OracleClient(currently simulated via local state insrc/screens/admin/AdminConsole.tsx).
| Surface | Route | Current Data Source | Soroban Read Dependency | Soroban Write Dependency | Vault / Client Function |
|---|---|---|---|---|---|
| Landing | / |
Fixtures (HB_DATA.pool) |
total_assets, share_price, get_projects |
None | fetchTotalAssets, useVault |
| Connect | /connect |
Stellar Wallets Kit + Demo | Horizon / RPC Account Check | None | WalletProvider (connect, sign) |
| Explore | /explore |
Fixtures / REST API | list_projects, oracle scores |
None | getProjects() |
| Project Detail | /project/[id] |
Fixtures / REST API | get_project, get_score_history, milestone draws |
None | getProject(id) |
| Deposit | /deposit |
Live Soroban / Mock fallback | share_price, total_assets, convert_to_shares |
deposit(amount, min_shares) |
fetchSharePrice, submitDeposit, previewDeposit |
| Portfolio | /portfolio |
Fixtures (HB_DATA.you) |
balance, convert_to_assets, get_liquid_assets |
None | vault.convertToAssets, useVault |
| Withdraw | /withdraw |
Live Soroban / Mock fallback | share_price, convert_to_assets, max_withdraw |
withdraw(shares, min_assets) |
vault.convertToAssets, submitWithdraw, previewWithdraw |
| Creator | /creator |
Fixtures (data/creator.ts) |
get_status, get_creator_projects, oracle scores |
Future: apply_whitelist, create_project |
Future CreatorClient |
| Admin / Oracle | /admin |
Fixtures + In-Memory State | Vault stats, registry entries, creator whitelist | Future: push_scores, fund_project, whitelist updates |
Future OracleClient / AdminClient |
When interacting with Soroban contracts (e.g. submitDeposit / submitWithdraw), the application follows a 5-step lifecycle:
┌─────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ 1. Parameter │ ──> │ 2. RPC Simulation │ ──> │ 3. Assemble & Sign │
│ Validation │ │ (sorobanServer. │ │ (WalletProvider. │
│ (parseAmount)│ │ simulateTx) │ │ sign) │
└─────────────────┘ └──────────────────────┘ └──────────────────────┘
│
▼
┌─────────────────┐ ┌──────────────────────┐ ┌──────────────────────┐
│ 5. UI Confirmed │ <── │ 4. Status Polling │ <── │ 3b. RPC Submission │
│ (Toast + │ │ (getTransaction │ │ (sendTransaction)│
│ Explorer) │ │ until SUCCESS) │ │ │
└─────────────────┘ └──────────────────────┘ └──────────────────────┘
- Parameter Validation: User inputs are parsed and validated against balance/liquidity limits using
src/lib/format.ts. - Simulation: The transaction is constructed with dummy fees (
100stroops) and simulated via@stellar/stellar-sdkRPC Server to calculate accurate resource fees and footprint. - Assembly & Signing:
rpc.assembleTransactionmerges simulation results into the transaction; the user signs the XDR via their connected wallet (Freighter, xBull, etc.). - Submission & Polling: The signed transaction is submitted to Stellar testnet and polled via
server.getTransaction(hash)until reachingSUCCESSorFAILEDstate (timeout: 30s). - UI Update: The client transitions to the success step, displays the transaction hash linking to StellarExpert (
https://stellar.expert/explorer/testnet/tx/...), and invalidates cached vault stats.