-
Bond USDC
+
Bond USDC
Lock USDC into the Credence contract to build your economic reputation.
@@ -228,6 +369,27 @@ export default function Bond() {
)}
+ {/* Network mismatch banner */}
+ {networkMismatch.mismatch && (
+
+ setNetwork(walletNetwork!),
+ }
+ : undefined
+ }
+ >
+ Credence is set to {appNetwork === 'test' ? 'Test (Testnet)' : 'Public (Mainnet)'}, but
+ Freighter is on {walletNetwork === 'test' ? 'Test (Testnet)' : 'Public (Mainnet)'}
+
+
+ )}
+
{/* Persistent error banner for bond-create failures (wallet rejected, network down).
Dismissed by the user or cleared automatically on the next successful attempt. */}
{createError && (
@@ -249,7 +411,7 @@ export default function Bond() {
)}
- {/* Persistent error banner for bond-withdraw failures. */}
+ {/* Persistent error banner for bond-withdraw failures */}
{withdrawError && (
)}
+ {/* Transaction status announcer for screen readers */}
+ {txStatusAnnouncer}
+
- {t('bond.createBondDescription')}
+
+ Lock USDC in the Credence smart contract to establish your on-chain reputation.
+
{
+ onChange={(next: string) => {
setBondAmount(next)
if (bondAmountError) setBondAmountError('')
}}
@@ -331,16 +498,14 @@ export default function Bond() {
>
{isLoadingBonds ? (
- // Skeleton shown while bond list is loading from the API
) : bonds.length === 0 ? (
- // ✅ EMPTY STATE - This is what we're adding
setConnectModalOpen(true)}
+ onConnect={connect}
+ onSelect={() => navigateRow(bond.id)}
/>
))}
@@ -363,6 +529,11 @@ export default function Bond() {
+
+
{withdrawTarget && withdrawBreakdown && (
)}
-
-
)
-}
\ No newline at end of file
+}
diff --git a/src/pages/BondDetail.css b/src/pages/BondDetail.css
index dc894615..c3a9b93e 100644
--- a/src/pages/BondDetail.css
+++ b/src/pages/BondDetail.css
@@ -100,6 +100,11 @@
color: var(--credence-color-primary);
}
+.bond-detail__info-row .bond-detail__timeRemaining {
+ color: var(--credence-color-primary);
+ font-weight: var(--credence-font-weight-bold);
+}
+
.bond-detail__actions {
display: grid;
gap: var(--credence-space-4);
diff --git a/src/pages/BondDetail.test.tsx b/src/pages/BondDetail.test.tsx
index 0b1e7ff6..c1c76279 100644
--- a/src/pages/BondDetail.test.tsx
+++ b/src/pages/BondDetail.test.tsx
@@ -130,7 +130,7 @@ describe('BondDetail Page', () => {
expect(screen.getByText('Active')).toBeInTheDocument()
})
- it('renders the bond specifications (amount, lock duration, unlock date)', () => {
+ it('renders the bond specifications (amount, time remaining, lock duration, start date, unlock date)', () => {
render(
@@ -139,11 +139,25 @@ describe('BondDetail Page', () => {
expect(screen.getByText('Bonded Amount')).toBeInTheDocument()
expect(screen.getByText('1,000 USDC')).toBeInTheDocument()
+ expect(screen.getByText('Time Remaining')).toBeInTheDocument()
+ expect(screen.getByText('30 days remaining')).toBeInTheDocument()
expect(screen.getByText('Lock Duration')).toBeInTheDocument()
expect(screen.getByText('30 Days')).toBeInTheDocument()
+ expect(screen.getByText('Lock Start Date')).toBeInTheDocument()
expect(screen.getByText('Estimated Unlock Date')).toBeInTheDocument()
})
+ it('shows top-up bond button with Add USDC label', () => {
+ render(
+
+
+
+ )
+
+ expect(screen.getByRole('button', { name: /Add USDC/i })).toBeInTheDocument()
+ expect(screen.getByText('Top-Up Bond')).toBeInTheDocument()
+ })
+
it('renders the slash-risk panel with the live penalty breakdown', () => {
render(
diff --git a/src/pages/BondDetail.tsx b/src/pages/BondDetail.tsx
index 664dda01..75523a24 100644
--- a/src/pages/BondDetail.tsx
+++ b/src/pages/BondDetail.tsx
@@ -10,7 +10,7 @@ import { useDocumentTitle } from '../hooks/useDocumentTitle'
import { formatUsdc } from '../lib/format'
import ConfirmDialog from '../components/ConfirmDialog'
import ConnectWalletDialog from '../components/ConnectWalletDialog'
-import { computeWithdrawBreakdown, calcUnlockDate, type MockBond } from '../lib/bondPenalty'
+import { computeWithdrawBreakdown, calcUnlockDate, calcTimeRemaining, calcLockStartDate, type MockBond } from '../lib/bondPenalty'
import './BondDetail.css'
const mockBonds: MockBond[] = [
@@ -144,10 +144,18 @@ export default function BondDetail() {
Bonded Amount
{formatUsdc(initialBond.amountUsdc)}