diff --git a/src/components/app-body/counter-offers/counter-offer-card.js b/src/components/app-body/counter-offers/counter-offer-card.js
new file mode 100644
index 0000000..d6641e5
--- /dev/null
+++ b/src/components/app-body/counter-offers/counter-offer-card.js
@@ -0,0 +1,71 @@
+/*
+ This Card component displays a counter offer with token icon, name, and price.
+*/
+
+// Global npm libraries
+import React, { useState } from 'react'
+import { Container, Row, Col, Card, Button } from 'react-bootstrap'
+import Jdenticon from '@chris.troutner/react-jdenticon'
+
+function CounterOfferCard (props) {
+ const { offer } = props
+ const [icon, setIcon] = useState(offer.tokenIcon)
+
+ return (
+ <>
+
+
+
+ {/** If the icon is loaded, display it */}
+ {icon && (
+ {
+ setIcon(null) // Set the icon to null if it fails to load the image url.
+ }}
+ />
+ )}
+
+ {/** If the icon is not loaded, display the Jdenticon */}
+ {!icon && (
+
+
+
+ )}
+
+
+ {offer.ticker}
+
+
+
+
+
+ {/* {offer.tokenName} */}
+ Counter Offer UTXO
+
+
+
+
+
+ {/* Price: */}
+ {offer.price}
+
+
+
+
+
+
+ Cancel
+
+
+
+
+
+
+
+ >
+ )
+}
+
+export default CounterOfferCard
diff --git a/src/components/app-body/counter-offers/index.js b/src/components/app-body/counter-offers/index.js
new file mode 100644
index 0000000..3bf41a4
--- /dev/null
+++ b/src/components/app-body/counter-offers/index.js
@@ -0,0 +1,90 @@
+/*
+ Shows Counter Offers created by the user.
+*/
+
+// Global npm libraries
+import React, { useState, useEffect } from 'react'
+import { Container, Row, Col, Spinner } from 'react-bootstrap'
+
+// Local libraries
+import CounterOfferCard from './counter-offer-card'
+import AsyncLoad from '../../../services/async-load'
+
+function CounterOffers (props) {
+ const appData = props.appData
+
+ const [counterOffers, setCounterOffers] = useState([])
+ const [isLoading, setIsLoading] = useState(true)
+
+ // Generate counter offer cards
+ const generateCards = () => {
+ return counterOffers.map((offer) => (
+
+ ))
+ }
+
+ useEffect(() => {
+ const loadWallet = async () => {
+ try {
+ setIsLoading(true)
+ const { bchWalletState, serverUrl } = appData
+ const asyncLoad = new AsyncLoad()
+ await asyncLoad.loadWalletLib()
+ const counterOfferWallet = await asyncLoad.getDerivatedWallet(serverUrl, bchWalletState.mnemonic, "m/44'/245'/0'/0/1")
+
+ const utxoStore = counterOfferWallet.utxos.utxoStore
+ const bchUtxos = utxoStore.bchUtxos
+ setCounterOffers(bchUtxos)
+ console.log('counterOffers', bchUtxos)
+ setIsLoading(false)
+ } catch (error) {
+ setIsLoading(false)
+ console.log('error', error)
+ }
+ }
+
+ loadWallet()
+ }, [appData])
+
+ return (
+
+
+
+ Counter Offers
+ Your pending counter offers
+
+
+ {isLoading
+ ? (
+
+
+
+ Loading...
+
+ Loading counter offers...
+
+
+ )
+ : (
+ <>
+
+ {generateCards()}
+
+ {counterOffers.length === 0 && (
+
+
+ No counter offers found.
+
+
+ )}
+ >
+ )}
+
+ )
+}
+
+export default CounterOffers
diff --git a/src/components/app-body/index.js b/src/components/app-body/index.js
index cccf610..285b2ea 100644
--- a/src/components/app-body/index.js
+++ b/src/components/app-body/index.js
@@ -30,6 +30,7 @@ import ContentCreators from './nostr/content-creators/index.js'
import UserDataReview from './user-data-review'
import Offers from './offers'
import NostrChat from './nostr-chat'
+import CounterOffers from './counter-offers'
function AppBody (props) {
// Dependency injection through props
const appData = props.appData
@@ -55,6 +56,7 @@ function AppBody (props) {
} />
} />
} />
+ } />
} />
{/** Show in all paths except the servers view */}
diff --git a/src/components/nav-menu/index.js b/src/components/nav-menu/index.js
index 8d615da..39d7b4a 100644
--- a/src/components/nav-menu/index.js
+++ b/src/components/nav-menu/index.js
@@ -58,6 +58,14 @@ function NavMenu (props) {
Fungible Tokens
+
+ Counter Offers
+
+