diff --git a/src/components/Earn.jsx b/src/components/Earn.jsx index c47734738..e5002067d 100644 --- a/src/components/Earn.jsx +++ b/src/components/Earn.jsx @@ -14,6 +14,7 @@ import { EarnReportOverlay } from './EarnReport' import * as Api from '../libs/JmWalletApi' import styles from './Earn.module.css' import { OrderbookOverlay } from './Orderbook' +import Balance from './Balance' // In order to prevent state mismatch, the 'maker stop' response is delayed shortly. // Even though the API response suggests that the maker has started or stopped immediately, it seems that this is not always the case. @@ -28,8 +29,11 @@ const RELOAD_FIDELITY_BONDS_DELAY_MS = 2_000 const OFFERTYPE_REL = 'sw0reloffer' const OFFERTYPE_ABS = 'sw0absoffer' -const isRelativeOffer = (offertype) => offertype === OFFERTYPE_REL -const isAbsoluteOffer = (offertype) => offertype === OFFERTYPE_ABS +// can be any of ['sw0reloffer', 'swreloffer', 'reloffer'] +const isRelativeOffer = (offertype) => offertype.includes('reloffer') + +// can be any of ['sw0absoffer', 'swabsoffer', 'absoffer'] +const isAbsoluteOffer = (offertype) => offertype.includes('absoffer') const FORM_INPUT_LOCAL_STORAGE_KEYS = { offertype: 'jm-offertype', @@ -83,6 +87,95 @@ const factorToPercentage = (val, precision = 6) => { return Number((val * 100).toFixed(precision)) } +const renderOrderType = (val, t) => { + if (isAbsoluteOffer(val)) { + return {t('earn.current.text_offer_type_absolute')} + } + if (isRelativeOffer(val)) { + return {t('earn.current.text_offer_type_relative')} + } + return {val} +} + +function CurrentOffer({ offer, nickname }) { + const { t } = useTranslation() + const settings = useSettings() + + return ( +
+
+
+ {nickname}:{offer.oid} +
+
{renderOrderType(offer.ordertype, t)}
+
+ + + +
+
{t('earn.current.text_cjfee')}
+
+ {isRelativeOffer(offer.ordertype) ? ( + <>{factorToPercentage(offer.cjfee)}% + ) : ( + <> + + + )} +
+
+
+ + +
+
{t('earn.current.text_minsize')}
+
+ +
+
+
+
+ + + +
+
{t('earn.current.text_txfee')}
+
+ +
+
+
+ + +
+
{t('earn.current.text_maxsize')}
+
+ +
+
+
+
+
+
+ ) +} + export default function Earn() { const { t } = useTranslation() const settings = useSettings() @@ -294,10 +387,22 @@ export default function Earn() { !serviceInfo?.makerRunning && !isWaitingMakerStart && !isWaitingMakerStop &&

{t('earn.market_explainer')}

} + {serviceInfo?.makerRunning && + (serviceInfo?.offers && serviceInfo?.nickname ? ( + <> + {serviceInfo.offers.map((offer, index) => ( + + ))} + + ) : ( + + + + ))} {!serviceInfo?.coinjoinInProgress && ( <> 0 ? t('earn.title_fidelity_bond_exists') : t('earn.title_fidelity_bonds')} + title={t('earn.title_fidelity_bonds', { count: fidelityBonds.length })} subtitle={t('earn.subtitle_fidelity_bonds')} />
@@ -319,7 +424,7 @@ export default function Earn() { /> ) : ( - + ))} diff --git a/src/components/Earn.module.css b/src/components/Earn.module.css index c35b0b212..03aa74024 100644 --- a/src/components/Earn.module.css +++ b/src/components/Earn.module.css @@ -3,7 +3,7 @@ border-radius: 0.25rem; } -.earn .fb-loader { +.earn .fidelityBondsLoader { height: 11rem; border-radius: 0.25rem; } @@ -46,3 +46,36 @@ border-color: var(--bs-gray-800); opacity: 100%; } + +.offerLoader { + height: 10rem; + border-radius: 0.25rem; + margin-bottom: 1.5rem; +} + +.offerContainer { + border: 1px solid var(--bs-gray-200); + border-radius: 0.3rem; + padding: 1.25rem; + margin-bottom: 1.5rem; +} + +:root[data-theme='dark'] .offerContainer { + border-color: var(--bs-gray-700); +} + +.offerContainer .offerTitle { + width: 100%; + font-size: 1.2rem; + color: var(--bs-body-color); +} + +.offerContainer .offerLabel { + color: var(--bs-gray-600); + font-size: 0.8rem; +} + +.offerContainer .offerContent { + font-size: 0.8rem; + word-break: break-all; +} diff --git a/src/i18n/locales/en/translation.json b/src/i18n/locales/en/translation.json index 510f0af59..bf044ad93 100644 --- a/src/i18n/locales/en/translation.json +++ b/src/i18n/locales/en/translation.json @@ -246,6 +246,14 @@ "text_stopping": "Stopping", "button_show_report": "Show earnings report", "button_show_orderbook": "Show orderbook", + "current": { + "text_cjfee": "Fee", + "text_minsize": "Minimum Size", + "text_maxsize": "Maximum Size", + "text_txfee": "Transaction Fee", + "text_offer_type_absolute": "absolute", + "text_offer_type_relative": "relative" + }, "report": { "title": "Earnings Report", "text_report_summary_one": "{{ count }} entry", @@ -261,8 +269,9 @@ "heading_earned": "Earned", "heading_notes": "Notes" }, - "title_fidelity_bonds": "Create a Fidelity Bond", - "title_fidelity_bond_exists": "Your Fidelity Bonds", + "title_fidelity_bonds_zero": "Create a Fidelity Bond", + "title_fidelity_bonds_one": "Your Fidelity Bond", + "title_fidelity_bonds_other": "Your Fidelity Bonds", "subtitle_fidelity_bonds": "A fidelity bond is a long-term deposit that makes cryptographic identities deliberately costly. By cryptographically locking up funds for a specific duration, you signal that you are a serious market participant and increase the chance of your offers being taken.", "fidelity_bond": { "error_freezing_utxos": "Could not freeze UTXOs.", diff --git a/src/libs/JmWalletApi.ts b/src/libs/JmWalletApi.ts index dd5871090..fe2f9ca78 100644 --- a/src/libs/JmWalletApi.ts +++ b/src/libs/JmWalletApi.ts @@ -64,7 +64,10 @@ interface WalletUnlockRequest { password: string } -type OrderType = 'sw0reloffer' | 'sw0absoffer' +// only support starting the maker with native segwit offers +type RelOfferType = 'sw0reloffer' +type AbsOfferType = 'sw0absoffer' +type OrderType = RelOfferType | AbsOfferType interface StartMakerRequest { cjfee_a: AmountSats