diff --git a/src/components/Earn.tsx b/src/components/Earn.tsx
index ddc32c8c..57386b99 100644
--- a/src/components/Earn.tsx
+++ b/src/components/Earn.tsx
@@ -13,7 +13,7 @@ import PageTitle from './PageTitle'
 import SegmentedTabs from './SegmentedTabs'
 import { CreateFidelityBond } from './fb/CreateFidelityBond'
 import { ExistingFidelityBond } from './fb/ExistingFidelityBond'
-import { SpendFidelityBondModal } from './fb/SpendFidelityBondModal'
+import { RenewFidelityBondModal, SpendFidelityBondModal } from './fb/SpendFidelityBondModal'
 import { EarnReportOverlay } from './EarnReport'
 import { OrderbookOverlay } from './Orderbook'
 import Balance from './Balance'
@@ -632,6 +632,20 @@ export default function Earn({ wallet }: EarnProps) {
                     }}
                   />
                 )}
+                {currentWalletInfo && renewFidelityBondId && (
+                  <RenewFidelityBondModal
+                    show={true}
+                    fidelityBondId={renewFidelityBondId}
+                    wallet={wallet}
+                    walletInfo={currentWalletInfo}
+                    onClose={({ mustReload }) => {
+                      setRenewFidelityBondId(undefined)
+                      if (mustReload) {
+                        reloadFidelityBonds({ delay: 0 })
+                      }
+                    }}
+                  />
+                )}
                 {fidelityBonds.map((fidelityBond, index) => {
                   const isExpired = !fb.utxo.isLocked(fidelityBond)
                   const actionsEnabled =
diff --git a/src/components/fb/CreateFidelityBond.tsx b/src/components/fb/CreateFidelityBond.tsx
index bd21685c..c83c55ca 100644
--- a/src/components/fb/CreateFidelityBond.tsx
+++ b/src/components/fb/CreateFidelityBond.tsx
@@ -254,8 +254,8 @@ const CreateFidelityBond = ({ otherFidelityBondExists, wallet, walletInfo, onDon
         return (
           <SelectDate
             description={t('earn.fidelity_bond.select_date.description')}
-            selectableYearsRange={yearsRange}
-            onDateSelected={(date) => setLockDate(date)}
+            yearsRange={yearsRange}
+            onChange={(date) => setLockDate(date)}
           />
         )
       case steps.selectJar:
diff --git a/src/components/fb/FidelityBondSteps.tsx b/src/components/fb/FidelityBondSteps.tsx
index 1dfd3174..bc6f3fcc 100644
--- a/src/components/fb/FidelityBondSteps.tsx
+++ b/src/components/fb/FidelityBondSteps.tsx
@@ -10,17 +10,15 @@ import { SelectableJar, jarInitial, jarFillLevel } from '../jars/Jar'
 import Sprite from '../Sprite'
 import Balance from '../Balance'
 import { CopyButton } from '../CopyButton'
-import LockdateForm from './LockdateForm'
+import LockdateForm, { LockdateFormProps } from './LockdateForm'
 import * as fb from './utils'
 import styles from './FidelityBondSteps.module.css'
 
 const cx = classnamesBind.bind(styles)
 
-interface SelectDateProps {
+type SelectDateProps = {
   description: string
-  selectableYearsRange: fb.YearsRange
-  onDateSelected: (lockdate: Api.Lockdate | null) => void
-}
+} & LockdateFormProps
 
 interface SelectJarProps {
   description: string
@@ -70,11 +68,11 @@ interface CreatedFidelityBondProps {
   frozenUtxos: Array<Utxo>
 }
 
-const SelectDate = ({ description, selectableYearsRange, onDateSelected }: SelectDateProps) => {
+const SelectDate = ({ description, yearsRange, disabled, onChange }: SelectDateProps) => {
   return (
     <div className="d-flex flex-column gap-4">
       <div className={styles.stepDescription}>{description}</div>
-      <LockdateForm onChange={(date) => onDateSelected(date)} yearsRange={selectableYearsRange} />
+      <LockdateForm yearsRange={yearsRange} onChange={onChange} disabled={disabled} />
     </div>
   )
 }
diff --git a/src/components/fb/LockdateForm.tsx b/src/components/fb/LockdateForm.tsx
index 5f6005df..748d2f27 100644
--- a/src/components/fb/LockdateForm.tsx
+++ b/src/components/fb/LockdateForm.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useMemo, useState } from 'react'
+import { useEffect, useMemo, useState } from 'react'
 import * as rb from 'react-bootstrap'
 import { Trans, useTranslation } from 'react-i18next'
 
@@ -58,13 +58,14 @@ export const _selectableYears = (yearsRange: fb.YearsRange, now = new Date()): n
     .map((_, index) => index + now.getUTCFullYear() + extra)
 }
 
-interface LockdateFormProps {
+export interface LockdateFormProps {
   onChange: (lockdate: Api.Lockdate | null) => void
   yearsRange?: fb.YearsRange
   now?: Date
+  disabled?: boolean
 }
 
-const LockdateForm = ({ onChange, now, yearsRange }: LockdateFormProps) => {
+const LockdateForm = ({ onChange, now, yearsRange, disabled }: LockdateFormProps) => {
   const { i18n } = useTranslation()
   const _now = useMemo<Date>(() => now || new Date(), [now])
   const _yearsRange = useMemo<fb.YearsRange>(() => yearsRange || fb.DEFAULT_TIMELOCK_YEARS_RANGE, [yearsRange])
@@ -115,6 +116,7 @@ const LockdateForm = ({ onChange, now, yearsRange }: LockdateFormProps) => {
               onChange={(e) => setLockdateYear(parseInt(e.target.value, 10))}
               required
               isInvalid={!isLockdateYearValid}
+              disabled={disabled}
               data-testid="select-lockdate-year"
             >
               {selectableYears.map((year) => (
@@ -135,6 +137,7 @@ const LockdateForm = ({ onChange, now, yearsRange }: LockdateFormProps) => {
               onChange={(e) => setLockdateMonth(parseInt(e.target.value, 10) as Month)}
               required
               isInvalid={!isLockdateMonthValid}
+              disabled={disabled}
               data-testid="select-lockdate-month"
             >
               {selectableMonths.map((it) => (
diff --git a/src/components/fb/SpendFidelityBondModal.tsx b/src/components/fb/SpendFidelityBondModal.tsx
index d4228e23..f9efb8a1 100644
--- a/src/components/fb/SpendFidelityBondModal.tsx
+++ b/src/components/fb/SpendFidelityBondModal.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useMemo, useRef, useState } from 'react'
+import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
 import * as rb from 'react-bootstrap'
 import { TFunction } from 'i18next'
 import { useTranslation } from 'react-i18next'
@@ -7,12 +7,14 @@ import * as Api from '../../libs/JmWalletApi'
 import * as fb from './utils'
 import Alert from '../Alert'
 import Sprite from '../Sprite'
-import { SelectJar } from './FidelityBondSteps'
+import { SelectDate, SelectJar } from './FidelityBondSteps'
 import { PaymentConfirmModal } from '../PaymentConfirmModal'
 import { jarInitial } from '../jars/Jar'
 import { useFeeConfigValues } from '../../hooks/Fees'
 
 import styles from './SpendFidelityBondModal.module.css'
+import { isDebugFeatureEnabled } from '../../constants/debugFeatures'
+import { CopyButton } from '../CopyButton'
 
 type Input = {
   outpoint: Api.UtxoId
@@ -138,6 +140,394 @@ const spendUtxosWithDirectSend = async (
   }
 }
 
+type SendFidelityBondToAddressProps = {
+  fidelityBond: Utxo | undefined
+  destination: Api.BitcoinAddress
+  wallet: CurrentWallet
+  t: TFunction
+}
+
+const sendFidelityBondToAddress = async ({ fidelityBond, destination, wallet, t }: SendFidelityBondToAddressProps) => {
+  if (!fidelityBond || fb.utxo.isLocked(fidelityBond)) {
+    throw new Error(t('earn.fidelity_bond.move.error_fidelity_bond_still_locked'))
+  }
+
+  const abortCtrl = new AbortController()
+  const requestContext = { ...wallet, signal: abortCtrl.signal }
+
+  return await spendUtxosWithDirectSend(
+    requestContext,
+    {
+      destination,
+      sourceJarIndex: fidelityBond.mixdepth,
+      utxos: [fidelityBond],
+    },
+    {
+      onReloadWalletError: (res) =>
+        Api.Helper.throwResolved(res, errorResolver(t, 'global.errors.error_reloading_wallet_failed')),
+      onFreezeUtxosError: (res) =>
+        Api.Helper.throwResolved(res, errorResolver(t, 'earn.fidelity_bond.move.error_freezing_utxos')),
+      onUnfreezeUtxosError: (res) =>
+        Api.Helper.throwResolved(res, errorResolver(t, 'earn.fidelity_bond.move.error_unfreezing_fidelity_bond')),
+      onSendError: (res) =>
+        Api.Helper.throwResolved(res, errorResolver(t, 'earn.fidelity_bond.move.error_spending_fidelity_bond')),
+    },
+  )
+}
+
+type SendFidelityBondToJarProps = {
+  fidelityBond: Utxo | undefined
+  targetJarIndex: JarIndex
+  wallet: CurrentWallet
+  t: TFunction
+}
+
+const sendFidelityBondToJar = async ({ fidelityBond, targetJarIndex, wallet, t }: SendFidelityBondToJarProps) => {
+  if (!fidelityBond || fb.utxo.isLocked(fidelityBond)) {
+    throw new Error(t('earn.fidelity_bond.move.error_fidelity_bond_still_locked'))
+  }
+
+  const abortCtrl = new AbortController()
+  const requestContext = { ...wallet, signal: abortCtrl.signal }
+
+  const destination = await Api.getAddressNew({ ...requestContext, mixdepth: targetJarIndex })
+    .then((res) => {
+      if (res.ok) return res.json()
+      return Api.Helper.throwResolved(res, errorResolver(t, 'earn.fidelity_bond.move.error_loading_address'))
+    })
+    .then((data) => data.address as Api.BitcoinAddress)
+
+  return await sendFidelityBondToAddress({ destination, fidelityBond, wallet, t })
+}
+
+const Done = ({ text }: { text: string }) => {
+  return (
+    <div className="d-flex flex-column justify-content-center align-items-center gap-1">
+      <div className={styles.successCheckmark}>
+        <Sprite symbol="checkmark" width="24" height="30" />
+      </div>
+      <div className={styles.successSummaryTitle}>{text}</div>
+    </div>
+  )
+}
+
+type RenewFidelityBondModalProps = {
+  fidelityBondId: Api.UtxoId
+  wallet: CurrentWallet
+  walletInfo: WalletInfo
+  onClose: (result: Result) => void
+} & Omit<rb.ModalProps, 'onHide'>
+
+const RenewFidelityBondModal = ({
+  fidelityBondId,
+  wallet,
+  walletInfo,
+  onClose,
+  ...modalProps
+}: RenewFidelityBondModalProps) => {
+  const { t } = useTranslation()
+  const reloadCurrentWalletInfo = useReloadCurrentWalletInfo()
+  const feeConfigValues = useFeeConfigValues()[0]
+
+  const [alert, setAlert] = useState<SimpleAlert>()
+
+  const [txInfo, setTxInfo] = useState<TxInfo>()
+  const [waitForUtxosToBeSpent, setWaitForUtxosToBeSpent] = useState<Api.UtxoId[]>([])
+
+  const [lockDate, setLockDate] = useState<Api.Lockdate>()
+  const [timelockedAddress, setTimelockedAddress] = useState<Api.BitcoinAddress>()
+
+  const [parentMustReload, setParentMustReload] = useState(false)
+  const [isSending, setIsSending] = useState(false)
+  const [isLoadingTimelockedAddress, setIsLoadingTimelockAddress] = useState(false)
+  const isLoading = useMemo(() => isSending || waitForUtxosToBeSpent.length > 0, [isSending, waitForUtxosToBeSpent])
+
+  const [showConfirmSendModal, setShowConfirmSendModal] = useState(false)
+
+  const submitButtonRef = useRef<HTMLButtonElement>(null)
+
+  const fidelityBond = useMemo(() => {
+    return walletInfo.data.utxos.utxos.find((utxo) => utxo.utxo === fidelityBondId)
+  }, [walletInfo, fidelityBondId])
+
+  // This callback is responsible for updating the loading state when the
+  // the payment is made. The wallet needs some time after a tx is sent
+  // to reflect the changes internally. All outputs in
+  // `waitForUtxosToBeSpent` must have been removed from the wallet
+  // for the payment to be considered done.
+  useEffect(() => {
+    if (waitForUtxosToBeSpent.length === 0) return
+
+    const abortCtrl = new AbortController()
+
+    // Delaying the poll requests gives the wallet some time to synchronize
+    // the utxo set and reduces amount of http requests
+    const initialDelayInMs = 250
+    const timer = setTimeout(() => {
+      if (abortCtrl.signal.aborted) return
+
+      reloadCurrentWalletInfo
+        .reloadUtxos({ signal: abortCtrl.signal })
+        .then((res) => {
+          if (abortCtrl.signal.aborted) return
+
+          const outputs = res.utxos.map((it) => it.utxo)
+          const utxosStillPresent = waitForUtxosToBeSpent.filter((it) => outputs.includes(it))
+          setWaitForUtxosToBeSpent([...utxosStillPresent])
+        })
+        .catch((err) => {
+          if (abortCtrl.signal.aborted) return
+
+          // Stop waiting for wallet synchronization on errors, but inform
+          // the user that loading the wallet info failed
+          setWaitForUtxosToBeSpent([])
+
+          const message = t('global.errors.error_reloading_wallet_failed', {
+            reason: err.message || t('global.errors.reason_unknown'),
+          })
+          setAlert({ variant: 'danger', message })
+        })
+    }, initialDelayInMs)
+
+    return () => {
+      abortCtrl.abort()
+      clearTimeout(timer)
+    }
+  }, [waitForUtxosToBeSpent, reloadCurrentWalletInfo, t])
+
+  const yearsRange = useMemo(() => {
+    if (isDebugFeatureEnabled('allowCreatingExpiredFidelityBond')) {
+      return fb.toYearsRange(-1, fb.DEFAULT_MAX_TIMELOCK_YEARS)
+    }
+    return fb.toYearsRange(0, fb.DEFAULT_MAX_TIMELOCK_YEARS)
+  }, [])
+
+  const loadTimeLockedAddress = useCallback(
+    (lockdate: Api.Lockdate, signal: AbortSignal) => {
+      setIsLoadingTimelockAddress(true)
+      setAlert(undefined)
+
+      return (
+        Api.getAddressTimelockNew({
+          ...wallet,
+          lockdate,
+          signal,
+        })
+          .then((res) => {
+            return res.ok ? res.json() : Api.Helper.throwError(res, t('earn.fidelity_bond.error_loading_address'))
+          })
+          // show the loader a little longer to avoid flickering
+          .then((result) => new Promise((r) => setTimeout(() => r(result), 221)))
+          .then((data: any) => {
+            if (signal.aborted) return
+            setTimelockedAddress(data.address)
+            setIsLoadingTimelockAddress(false)
+          })
+          .catch((err) => {
+            if (signal.aborted) return
+            setAlert({ variant: 'danger', message: err.message })
+            setIsLoadingTimelockAddress(false)
+          })
+      )
+    },
+    [wallet, t],
+  )
+
+  useEffect(() => {
+    if (!lockDate) return
+    const abortCtrl = new AbortController()
+    loadTimeLockedAddress(lockDate, abortCtrl.signal)
+    return () => abortCtrl.abort()
+  }, [loadTimeLockedAddress, lockDate])
+
+  const primaryButtonContent = useMemo(() => {
+    if (isSending) {
+      return (
+        <>
+          <rb.Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" className="me-2" />
+          {t('earn.fidelity_bond.renew.text_sending')}
+        </>
+      )
+    } else if (txInfo) {
+      return <>{t('global.done')}</>
+    }
+    return <>{t('earn.fidelity_bond.renew.text_button_submit')}</>
+  }, [isSending, txInfo, t])
+
+  const onSelectedDateChanged = useCallback((date) => {
+    setTimelockedAddress(undefined)
+    setLockDate(date ?? undefined)
+  }, [])
+
+  const modalBodyContent = useMemo(() => {
+    if (isLoading) {
+      return (
+        <div className="d-flex justify-content-center align-items-center my-5">
+          <rb.Spinner as="span" animation="border" size="sm" role="status" aria-hidden="true" className="me-2" />
+          <div>{t(`earn.fidelity_bond.renew.${isSending ? 'text_sending' : 'text_loading'}`)}</div>
+        </div>
+      )
+    }
+
+    if (txInfo) {
+      return (
+        <div className="my-4">
+          <Done text={t('earn.fidelity_bond.renew.success_text')} />
+        </div>
+      )
+    }
+
+    return (
+      <div className="my-2 d-flex flex-column gap-4">
+        <SelectDate
+          description={t('earn.fidelity_bond.select_date.description')}
+          yearsRange={yearsRange}
+          disabled={isLoading || isLoadingTimelockedAddress}
+          onChange={onSelectedDateChanged}
+        />
+        {timelockedAddress && (
+          <>
+            <div className="d-flex flex-column gap-3">
+              <div className="d-flex align-items-center gap-2">
+                <CopyButton
+                  text={<Sprite symbol="copy" width="18" height="18" />}
+                  successText={<Sprite symbol="checkmark" width="18" height="18" />}
+                  value={timelockedAddress}
+                />
+                <div className="d-flex flex-column">
+                  <div>{t('earn.fidelity_bond.review_inputs.label_address')}</div>
+                  <div>
+                    <code>{timelockedAddress}</code>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </>
+        )}
+      </div>
+    )
+  }, [
+    isLoading,
+    isSending,
+    yearsRange,
+    timelockedAddress,
+    isLoadingTimelockedAddress,
+    txInfo,
+    onSelectedDateChanged,
+    t,
+  ])
+
+  const onPrimaryButtonClicked = async () => {
+    if (isLoading) return
+    if (isLoadingTimelockedAddress) return
+    if (timelockedAddress === undefined) return
+    if (waitForUtxosToBeSpent.length > 0) return
+
+    if (txInfo) {
+      onClose({ txInfo, mustReload: parentMustReload })
+    } else if (!showConfirmSendModal) {
+      setShowConfirmSendModal(true)
+    } else {
+      if (!fidelityBond || fb.utxo.isLocked(fidelityBond)) {
+        throw new Error(t('earn.fidelity_bond.move.error_fidelity_bond_still_locked'))
+      }
+      setShowConfirmSendModal(false)
+      setParentMustReload(true)
+
+      setAlert(undefined)
+      setIsSending(true)
+
+      return sendFidelityBondToAddress({
+        destination: timelockedAddress,
+        fidelityBond,
+        wallet,
+        t,
+      })
+        .then((data) => data.txinfo as TxInfo)
+        .then((txinfo) => {
+          setTxInfo(txinfo)
+
+          setWaitForUtxosToBeSpent(txinfo.inputs.map((it) => it.outpoint))
+
+          setIsSending(false)
+        })
+        .catch((e) => {
+          setIsSending(false)
+
+          const message = e instanceof Error ? e.message : t('global.errors.reason_unknown')
+          setAlert({ variant: 'danger', message })
+        })
+    }
+  }
+
+  return (
+    <>
+      <rb.Modal
+        animation={true}
+        backdrop="static"
+        centered={true}
+        keyboard={false}
+        size="lg"
+        {...modalProps}
+        onHide={() => onClose({ txInfo, mustReload: parentMustReload })}
+        dialogClassName={showConfirmSendModal ? 'invisible' : ''}
+      >
+        <rb.Modal.Header closeButton>
+          <rb.Modal.Title>{t('earn.fidelity_bond.renew.title')}</rb.Modal.Title>
+        </rb.Modal.Header>
+        <rb.Modal.Body>
+          {alert && <Alert {...alert} className="mt-0" onClose={() => setAlert(undefined)} />}
+          {modalBodyContent}
+        </rb.Modal.Body>
+        <rb.Modal.Footer>
+          <div className="w-100 d-flex gap-4 justify-content-center align-items-center">
+            <rb.Button
+              variant="light"
+              disabled={isLoading}
+              onClick={() => onClose({ txInfo, mustReload: parentMustReload })}
+              className="flex-1 d-flex justify-content-center align-items-center"
+            >
+              {t('global.cancel')}
+            </rb.Button>
+            <rb.Button
+              ref={submitButtonRef}
+              variant="dark"
+              className="flex-1 d-flex justify-content-center align-items-center"
+              disabled={isLoading || timelockedAddress === undefined}
+              onClick={onPrimaryButtonClicked}
+            >
+              {primaryButtonContent}
+            </rb.Button>
+          </div>
+        </rb.Modal.Footer>
+      </rb.Modal>
+      {showConfirmSendModal && fidelityBond && timelockedAddress !== undefined && (
+        <PaymentConfirmModal
+          isShown={true}
+          title={t(`earn.fidelity_bond.renew.${timelockedAddress ? 'confirm_send_modal.title' : 'title'}`)}
+          onCancel={() => {
+            setShowConfirmSendModal(false)
+            onClose({ txInfo, mustReload: parentMustReload })
+          }}
+          onConfirm={() => {
+            submitButtonRef.current?.click()
+          }}
+          data={{
+            sourceJarIndex: undefined, // dont show a source jar - might be confusing in this context
+            destination: timelockedAddress,
+            amount: fidelityBond.value,
+            isSweep: true,
+            isCoinjoin: false, // not sent as collaborative transaction
+            numCollaborators: undefined,
+            feeConfigValues,
+            showPrivacyInfo: false,
+          }}
+        />
+      )}
+    </>
+  )
+}
+
 type SpendFidelityBondModalProps = {
   fidelityBondId: Api.UtxoId
   wallet: CurrentWallet
@@ -240,7 +630,12 @@ const SpendFidelityBondModal = ({
       setAlert(undefined)
       setIsSending(true)
 
-      sendFidelityBondToJar(fidelityBond, selectedDestinationJarIndex)
+      sendFidelityBondToJar({
+        fidelityBond,
+        targetJarIndex: selectedDestinationJarIndex,
+        wallet,
+        t,
+      })
         .then((data) => data.txinfo as TxInfo)
         .then((txinfo) => {
           setTxInfo(txinfo)
@@ -258,42 +653,7 @@ const SpendFidelityBondModal = ({
     }
   }
 
-  const sendFidelityBondToJar = async (fidelityBond: Utxo | undefined, targetJarIndex: JarIndex) => {
-    if (!fidelityBond || fb.utxo.isLocked(fidelityBond)) {
-      throw new Error(t('earn.fidelity_bond.move.error_fidelity_bond_still_locked'))
-    }
-
-    const abortCtrl = new AbortController()
-    const requestContext = { ...wallet, signal: abortCtrl.signal }
-
-    const destination = await Api.getAddressNew({ ...requestContext, mixdepth: targetJarIndex })
-      .then((res) => {
-        if (res.ok) return res.json()
-        return Api.Helper.throwResolved(res, errorResolver(t, 'earn.fidelity_bond.move.error_loading_address'))
-      })
-      .then((data) => data.address as Api.BitcoinAddress)
-
-    return await spendUtxosWithDirectSend(
-      requestContext,
-      {
-        destination,
-        sourceJarIndex: fidelityBond.mixdepth,
-        utxos: [fidelityBond],
-      },
-      {
-        onReloadWalletError: (res) =>
-          Api.Helper.throwResolved(res, errorResolver(t, 'global.errors.error_reloading_wallet_failed')),
-        onFreezeUtxosError: (res) =>
-          Api.Helper.throwResolved(res, errorResolver(t, 'earn.fidelity_bond.move.error_freezing_utxos')),
-        onUnfreezeUtxosError: (res) =>
-          Api.Helper.throwResolved(res, errorResolver(t, 'earn.fidelity_bond.move.error_unfreezing_fidelity_bond')),
-        onSendError: (res) =>
-          Api.Helper.throwResolved(res, errorResolver(t, 'earn.fidelity_bond.move.error_spending_fidelity_bond')),
-      },
-    )
-  }
-
-  const PrimaryButtonContent = () => {
+  const primaryButtonContent = useMemo(() => {
     if (isSending) {
       return (
         <>
@@ -305,18 +665,7 @@ const SpendFidelityBondModal = ({
       return <>{t('earn.fidelity_bond.move.text_button_done')}</>
     }
     return <>{t('earn.fidelity_bond.move.text_button_submit')}</>
-  }
-
-  const Done = ({ text }: { text: string }) => {
-    return (
-      <div className="d-flex flex-column justify-content-center align-items-center gap-1">
-        <div className={styles.successCheckmark}>
-          <Sprite symbol="checkmark" width="24" height="30" />
-        </div>
-        <div className={styles.successSummaryTitle}>{text}</div>
-      </div>
-    )
-  }
+  }, [isSending, txInfo, t])
 
   const ModalBodyContent = () => {
     if (isLoading) {
@@ -384,7 +733,7 @@ const SpendFidelityBondModal = ({
               disabled={isLoading || selectedDestinationJarIndex === undefined}
               onClick={onPrimaryButtonClicked}
             >
-              {PrimaryButtonContent()}
+              {primaryButtonContent}
             </rb.Button>
           </div>
         </rb.Modal.Footer>
@@ -420,4 +769,4 @@ const SpendFidelityBondModal = ({
   )
 }
 
-export { SpendFidelityBondModal }
+export { RenewFidelityBondModal, SpendFidelityBondModal }
diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json
index 700b1351..86bcb109 100644
--- a/src/i18n/locales/en/translation.json
+++ b/src/i18n/locales/en/translation.json
@@ -8,6 +8,7 @@
     "close": "Close",
     "abort": "Abort",
     "cancel": "Cancel",
+    "done": "Done",
     "table": {
       "pagination": {
         "items_per_page": {
@@ -504,6 +505,17 @@
         "button_spend": "Unlock Funds",
         "button_renew": "Renew Bond"
       },
+      "renew": {
+        "title": "Renew Bond",
+        "text_loading": "Loading...",
+        "text_sending": "Renewing...",
+        "text_button_submit": "Renew Bond",
+        "success_text": "Fidelity Bond renewed successfully!",
+        "error_renewing_fidelity_bond": "Error while renewing expired fidelity bond.",
+        "confirm_send_modal": {
+          "title": "Confirm renewing expired Fidelity Bond"
+        }
+      },
       "move": {
         "title": "Unlock Funds",
         "success_text": "Fidelity Bond unlocked successfully!",