-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Pending Transaction Service for broadcast error handling #231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+18,576
−12,336
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
- 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
…cast error handling - Move BroadcastResultSchema into apis/bnqkl_wallet/bioforest/types.ts - Move pending-tx service into services/transaction/pending-tx.ts - Fix broadcastTransaction to catch ApiError and extract error info - Add E2E tests for broadcast errors (real chain + mock) - Captured real error codes: 001-11028 (asset not enough), 002-41011 (fee not enough)
- Store transactions to pendingTxService before broadcasting - Update status to 'broadcasting' during broadcast - Update status to 'broadcasted' on success with txHash - Update status to 'failed' on BroadcastError with error details
- Create PendingTxList component for displaying pending transactions - Create usePendingTransactions hook for fetching pending tx data - Integrate pending tx list at top of transaction history page - Support delete action for pending transactions
- Create PendingTxDetailPage with full transaction status display - Add PendingTxDetailActivity and register route /pending-tx/:pendingTxId - Support retry broadcast for failed transactions - Support delete for failed/created transactions - Navigate to detail page on pending tx item click - Add retryCount i18n translation
- Create PendingTxManager with auto-retry for failed broadcasts - Add subscription mechanism for UI status updates - Sync broadcasted transactions to check confirmation status - Integrate manager into usePendingTransactions hook - Auto-start manager when pending transactions exist
- Add PendingTxList to WalletTab for visibility - Show pending transactions between quick actions and portfolio - Support retry and delete actions from home page
- Send notifications on broadcast success/failure - Send notification when transaction is confirmed - Include transaction details in notification data
…tions - Add pending tx count badge on wallet tab in TabBar - Add deleteExpired method to PendingTxService for cleanup - Auto-cleanup expired transactions (24h) during sync - Badge shows count or '9+' for many pending transactions
- Add onNavigate callback to NotificationItem for transaction notifications - Navigate to /pending-tx/:pendingTxId when clicking transaction notifications - Add 'View Details' link with chevron icon for actionable notifications - Add viewDetails i18n translations for en/zh-CN
- Add status-specific background colors (blue/amber/red/green) - Add pulse animation for broadcasting and broadcasted states - Improve visual feedback for transaction status
- Test deleteExpired cleanup functionality - Test incrementRetry counter - Test status color consistency - Test notification with pendingTxId for navigation
- Add invalidateBalance method to PendingTxManager - Invalidate balance query cache when transaction is confirmed - Triggers automatic balance refresh in UI
- Add transactionHistoryKeys import - Invalidate transaction history cache along with balance - Ensures UI shows the confirmed transaction immediately
- Remove direct IndexedDB manipulation that caused NotFoundError - Test only verifies method exists and is callable - Full deleteExpired logic is covered in unit tests
- Add pendingTx translations (title, broadcasting, broadcasted, failed, retry, delete, retryCount) - Add broadcast error translations (assetNotEnough, feeNotEnough, rejected, unknown) - Add txStatus.created translations for pending broadcast state
- Add pending-tx-list.stories.tsx with 6 stories (Default, Broadcasting, Broadcasted, Failed, Empty, MultipleStates) - Add storybook-e2e/pending-tx-list.spec.ts for visual regression testing - Generate 5 screenshots for different pending tx states - All storybook tests passing (6 tests)
c75d512 to
acfcf35
Compare
- Fix broadcastTransaction to detect success when API returns transaction object - Fix pattern lock to show error message and allow retry on broadcast failure - Add E2E testing checklist documentation
When broadcast returns error code 001-00034 (transaction already exists), treat it as success since the transaction is already on chain.
fdd0c92 to
bd4ffdc
Compare
- Change broadcastTransaction to return BroadcastResult with alreadyExists flag - When transaction already exists on chain, mark as 'confirmed' instead of 'broadcasted' - Update all callers: use-send, use-burn, pending-tx detail page, pending-tx-manager
- Add tests for BroadcastResult type structure - Add tests for 001-00034 duplicate transaction handling - Add tests for PendingTx marking as confirmed on duplicate broadcast style: use flex-col for pending tx actions layout
- Add errorCode check for 001-00034 in ApiError handling - Return BroadcastResult with alreadyExists=true for duplicate tx - Refactor pending-tx-list to use @biochain/key-ui components (IconCircle, AddressDisplay, Alert) - Remove unreliable message-based fallback checks
- When tx not found in pending list, query transaction API - Handles case where tx is confirmed and removed from pending queue - Fixes: UI stuck at 'broadcasting' when transaction is already confirmed - Updates status to 'confirmed' when found via transaction API
- Remove complex pending tx list subscription logic - Directly subscribe to chainProvider.transaction - Much simpler and cleaner implementation - Automatically updates when transaction status changes
- Use useChainProvider hook from correct path - Add Transaction type annotation - Remove unused imports and variables - All type checks pass
- TransferWalletLockJob is not wrapped in ChainProviderGate - Use getChainProvider(selectedChain) to get provider instance - Fixes: useChainProvider must be used within ChainProviderGate error
- Document completed BioChain implementation - Plan for EVM chains (Ethereum, BSC) - Plan for Tron - Plan for Bitcoin - Include implementation guidelines and best practices
- Implement eth_getTransactionByHash RPC call - Implement eth_getTransactionReceipt RPC call - Use combine to merge tx + receipt - Convert EVM transaction to unified Transaction schema - Support pending/confirmed/failed status detection - Works for Ethereum, BSC and other EVM chains
- Implement /wallet/gettransactionbyid API call - Convert Tron transaction to unified Transaction schema - Support pending/confirmed/failed status detection - Pending detection: no ret array means pending - Works for Tron network
1. Fix translation: use transaction:type.{action} instead of fallback
2. Fix icon size: add size-5 to icon itself, not wrapper div
3. Auto-check confirmed status: already implemented in getPendingTxFetcher
1. Fix conditional Hook call in usePendingTransactions - Manually manage state with useState/useEffect - Avoid fetcher?.useState() conditional call - Subscribe to both fetch and subscribe events 2. Delete confirmed transactions instead of updating status - Simpler approach: directly remove from database - No need to rely on getPending filter logic - Immediately triggers refetch via pendingTxService.notify
- Replace fetcher?.useState() with manual state management - Use useState + useEffect to avoid React Hooks rule violation - Always call Hooks in the same order regardless of fetcher state - Should fix initial render issue where pending txs don't show
- Check if displayType already has 'type.' prefix - Avoid double prefix like 'type.type.transfer' - Fixes translation display issue
- Add onRetry and onDelete callbacks - Show action buttons instead of amount/time for pending txs - Create pendingTxToTransactionInfo conversion function - Prepare for unified rendering with TransactionList
- Replace PendingTxList with TransactionItem mapping in WalletTab - Use pendingTxToTransactionInfo conversion function - TransactionItem handles translation automatically (fixes type display) - Support onRetry/onDelete actions in TransactionItem - Two independent lists (pending and confirmed) use same item component
- Import Amount class from types/amount - Use Amount.fromFormatted to create proper Amount object - Convert timestamp to Date object - Remove all 'as any' type assertions for type safety
- Add decimals parameter to conversion function - Get chainConfig in WalletTabContent for proper decimals - Fallback to 8 decimals if chainConfig not available
- TransactionType doesn't have 'transfer', only 'send'/'receive' - Add mapMetaType function for proper type conversion - Remove debug code
BREAKING CHANGE: PendingTxMeta.type now uses TransactionType enum - Add TransactionTypeSchema to pending-tx.ts - Change meta.type from 'transfer' to 'send' in use-send.bioforest.ts - Simplify convert.ts by removing mapMetaType function - Remove duplicate imports in pending-tx.ts
- Fix duplicate imports in pending-tx.ts - Add missing DBSchema import from idb - Add type assertions for dynamic translation keys in pending-tx-list.tsx
BREAKING: Remove deprecated PendingTxList component - Replace PendingTxList with TransactionItem in history/index.tsx - Delete pending-tx-list.tsx and pending-tx-list.stories.tsx - All pending transaction rendering now uses TransactionItem - Type-safe with proper TransactionType enum
Breaking Changes: - pending-tx 使用 rawTx.signature 作为 ID(不再使用 UUID) - 删除 pending-tx/detail.tsx,统一使用 history/detail.tsx - 删除 PendingTxDetailActivity Changes: - biowallet-provider: 使用 transaction.signature 作为交易 hash - detail.tsx: 支持双输入模式(txData 或 txId) - WalletTab: pending 交易导航到统一详情页 - convert.ts: 生成 chainId--txHash 格式 ID - use-pending-transactions: 删除后立即更新本地状态
- getBioforestCore 内部调用 chainConfigService.getBiowalletGenesisBlock - fetchGenesisBlock 要求提供路径,删除回退逻辑 - 删除未使用的 getGenesisBaseUrl 和 genesisBaseUrl - setGenesisBaseUrl 改名为 setGenesisImportOptions
- 新增 allBalances getter 合并 nativeBalance 和 tokenBalances - 如果只有 nativeBalance,使用 derive 转换为 TokenBalance[] - WalletTab 简化:使用 allBalances.useState 替代分离查询 - 删除 tokensSupported/balanceData 相关逻辑 - 修复加载状态不统一问题:Tron 不再显示'无资产'再显示数据
- Fix fetch mock type casting with 'as unknown as typeof fetch' pattern - Fix derive API usage to use 'use: [transform(...)]' instead of direct transform property - Add missing transform import in react-integration.test.ts - Add required params argument to useState call
- Add error handling to context.refetch() call in derive onSubscribe - Prevents unhandled promise rejections when transform throws - Add wait before mockRestore in test to ensure async cleanup completes
- Add console.error in events.ts catch block for handler error logging - Add console.warn in provider.ts when not running in iframe This fixes 2 failing tests that expected these console calls to exist.
- Fix eqeqeq errors: use === and !== for null/undefined checks in params.ts - Fix no-explicit-any: use Record<string, unknown> in params.ts - Fix no-explicit-any: properly type FetchParams in fallback.ts - Fix no-unused-imports: remove unused _SubscribeContext import in cache.ts
- derive.ts: use InferOutput<P> instead of any for params casts - types.ts: use import type for superjson default export - combine.ts: use AnyZodSchema constraints and proper casts - core.ts: use Record<string, unknown> and explicit this param - params.ts: handle null/undefined with strict equality - fallback.ts: use FetchParams type - cache.ts: remove unused import Reduces lint errors from 17 to 0 (plus 17 warnings that are acceptable).
- Remove build script (pure TS package exports TS directly) - Rename typecheck to typecheck:run for turbo - Remove unused @ts-expect-error in paths.ts (Bun types now available) - Replace toSorted with spread+sort in meta.mcp.ts for ES2022 compat - Add skipLibCheck to tsconfig to skip bun-types/undici-types conflict
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements a comprehensive Pending Transaction Service for systematically managing unconfirmed transactions and proper broadcast error handling.
Core Features
Testing
Screenshots
Generated storybook-e2e screenshots:
pending-tx-list-default.png- 默认多状态列表pending-tx-broadcasting.png- 广播中状态pending-tx-broadcasted.png- 等待上链状态pending-tx-failed.png- 广播失败状态pending-tx-multiple-states.png- 多状态组合Commits (26)
Architecture
New/Modified Files
New Files:
src/services/transaction/pending-tx.ts- PendingTxService (IndexedDB)src/services/transaction/pending-tx-manager.ts- Background managersrc/services/bioforest-sdk/errors.ts- BroadcastError classsrc/components/transaction/pending-tx-list.tsx- UI with animationssrc/components/transaction/pending-tx-list.stories.tsx- Storybook storiessrc/pages/pending-tx/detail.tsx- Detail pagesrc/hooks/use-pending-transactions.ts- React hooke2e/pending-tx-ui.mock.spec.ts- E2E testsstorybook-e2e/pending-tx-list.spec.ts- Visual regression testsModified Files:
src/stackflow/components/TabBar.tsx- Pending tx badgesrc/stackflow/activities/tabs/WalletTab.tsx- Home page integrationsrc/pages/history/index.tsx- History page integrationsrc/pages/notifications/index.tsx- Click navigationsrc/hooks/use-send.bioforest.ts- Service integrationsrc/hooks/use-burn.bioforest.ts- Service integrationsrc/i18n/locales/*/transaction.json- i18n translations (4 languages)