Skip to content

feat(biobridge): upgrade forge to BioBridge with redemption support - #230

Merged
Gaubee merged 16 commits into
mainfrom
feature/biobridge-redemption
Jan 13, 2026
Merged

Gaubee merged 16 commits into
mainfrom
feature/biobridge-redemption

Conversation

@Gaubee

@Gaubee Gaubee commented Jan 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Upgrade the forge (锻造) miniapp to BioBridge (跨链通) with dual-mode bridge functionality:

  • Recharge (外链→内链): Existing functionality, rebranded
  • Redemption (内链→外链): New functionality added

Changes

API Layer

  • Add redemption API client (redemption.ts) with endpoints:
    • submitRedemption - Submit redemption request
    • getRecords - Fetch redemption history
    • getRecordDetail - Get single record detail
    • retryInternalOnChain / retryExternalOnChain - Retry failed transactions
  • Add redemption types (REDEMPTION_ORDER_STATE_ID, REDEMPTION_RECORD_STATE, DTOs)

Hooks

  • useRedemption - Redemption flow (create tx → sign → submit)
  • useRedemptionRecords - Record listing and detail fetching

UI Components

  • RedemptionForm - Full redemption UI with option selection, amount input, address input, fee preview
  • ModeTabs - Tab switcher for recharge/redemption modes

Fee Calculation

  • lib/fee.ts - calculateRedemptionFee, formatAmount, parseAmount, isAmountWithinLimits

App Integration

  • Complete rewrite of App.tsx with dual-mode architecture
  • Shared config fetching, separate forms per mode

Branding

  • Update manifest.json (id, name, version, theme colors)
  • Update package.json (name: @biochain/miniapp-biobridge)
  • Update all i18n files (en, zh-CN, zh-TW)

Testing

  • TypeScript: ✅ Pass
  • Lint: ✅ Pass (warnings only)
  • Unit Tests: ✅ 66 tests passed

Breaking Changes

App renamed from forge to biobridge with new dual-mode UI. No backward compatibility needed per requirements.

Gaubee added 16 commits January 12, 2026 19:13
The IconCircle component from @biochain/key-ui expects ReactNode (elements)
but was receiving Component functions, causing 'Objects are not valid as
React child' error during token transfers.

Fixed 7 occurrences across:
- send-result.tsx
- pattern-lock-setup.tsx
- recover.tsx
- wallet-chains.tsx
- create.tsx
When assetType is specified in URL params (e.g. ?assetType=CPCC), the
previous code would immediately fallback to native asset if tokens
hadn't loaded yet, then get overwritten again causing a flicker.

Now returns null from initialAsset when tokens are still loading,
allowing the useEffect to properly set the asset once tokens are
available.
Tests verify that:
- assetType param correctly selects the specified token after async load
- Unknown assetType falls back to native asset
- SendPage: use explorer.queryTx to open block explorer, disable button if not configured
- TransferWalletLockJob: add onViewExplorer callback to TxStatusDisplay
- DestroyPage: same fix as SendPage
- TxStatusDisplay: add onViewExplorer prop for explorer link button
Previously assetType was hardcoded to chainConfig.symbol (native asset),
causing all token transfers to incorrectly use the native asset (e.g., BFM)
instead of the user-selected token (e.g., CPCC).

Changes:
- Add assetType param to SubmitBioforestParams interface
- Pass state.asset.assetType in submit and submitWithTwoStepSecret
- Add PendingTxService for managing unconfirmed transaction lifecycle
  - Schema: PendingTxSchema with status, rawTx, meta fields
  - Service: IndexedDB storage with CRUD operations
  - States: created -> broadcasting -> broadcasted -> confirmed/failed

- Add BroadcastError class with i18n error code translation
  - Zod Schema for BroadcastResult validation
  - Error codes: 001-11028 (asset not enough), 001-11029 (fee not enough)
  - translateBroadcastError() for user-friendly messages

- Fix broadcast error handling in hooks
  - Remove silent .catch() that hid broadcast failures
  - Properly catch and translate BroadcastError
  - Return error status with translated message

- Add i18n translations for broadcast errors
  - zh-CN/en: broadcast.assetNotEnough, feeNotEnough, rejected, unknown
  - zh-CN/en: pendingTx.title, broadcasting, broadcasted, failed, retry, delete
- Add redemption API client (submitRedemption, getRecords, retryInternal/External)
- Add useRedemption and useRedemptionRecords hooks
- Add RedemptionForm and ModeTabs UI components
- Add fee calculation utilities (lib/fee.ts)
- Rewrite App.tsx with dual-mode (recharge/redemption) architecture
- Update branding from 锻造/Forge to 跨链通/BioBridge
- Update manifest.json, package.json with new identity
- Add all redemption-related i18n translations (en, zh-CN, zh-TW)
- Update tests for new branding

BREAKING CHANGE: App renamed from forge to biobridge with new dual-mode UI
…used imports

- Replace BigInt/parseFloat with big.js for accurate ratio fee calculation
- Remove unused Loader2 import from RedemptionForm
- Remove unused onBack parameter from RedemptionForm
- Add big.js and @types/big.js dependencies
- Update e2e/helpers/i18n.ts with new BioBridge branding
- Update e2e/ui.spec.ts tests for new UI structure
- Add RedemptionMode story to App.stories.tsx
- Update mock config with redemption parameters
- Regenerate E2E screenshots for new UI
- Remove token picker tests (functionality changed in new UI)
… mode tests

- Add redemption config to mockApiResponses (enable, min, max, fee, radioFee)
- Add redemption API endpoint mock
- Add test '09 - mode tabs visible' to verify mode tabs display
- Add test '09b - redemption mode UI' to verify redemption mode works
- Regenerate all screenshots with mode tabs visible
@Gaubee
Gaubee merged commit 057c883 into main Jan 13, 2026
11 of 15 checks passed
@Gaubee
Gaubee deleted the feature/biobridge-redemption branch January 13, 2026 04:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant