mirror of
https://github.com/Qortal/q-trade.git
synced 2025-06-18 12:11:21 +00:00
added lock fee functionality
This commit is contained in:
parent
e75fadf1bd
commit
bbfd29e8fb
15
package-lock.json
generated
15
package-lock.json
generated
@ -19,7 +19,7 @@
|
|||||||
"jotai": "^2.12.3",
|
"jotai": "^2.12.3",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"qapp-core": "^1.0.22",
|
"qapp-core": "^1.0.24",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-countdown-circle-timer": "^3.2.1",
|
"react-countdown-circle-timer": "^3.2.1",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
@ -4298,6 +4298,12 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dexie": {
|
||||||
|
"version": "4.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/dexie/-/dexie-4.0.11.tgz",
|
||||||
|
"integrity": "sha512-SOKO002EqlvBYYKQSew3iymBoN2EQ4BDw/3yprjh7kAfFzjBYkaMNa/pZvcA7HSWlcKSQb9XhPe3wKyQ0x4A8A==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/dir-glob": {
|
"node_modules/dir-glob": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
@ -6575,9 +6581,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/qapp-core": {
|
"node_modules/qapp-core": {
|
||||||
"version": "1.0.22",
|
"version": "1.0.24",
|
||||||
"resolved": "https://registry.npmjs.org/qapp-core/-/qapp-core-1.0.22.tgz",
|
"resolved": "https://registry.npmjs.org/qapp-core/-/qapp-core-1.0.24.tgz",
|
||||||
"integrity": "sha512-3q8Ebr9lpyDW7lTo91Rlak2EGIAXrU9DYhUBuLsYZMuRyI/bKoc0E4hHrrAo946eJ/5AxqNGmZDkYSJq5tOTZg==",
|
"integrity": "sha512-KnrwiysaHlTR1rUnPGwN79gQgcjvtLr4xRH3EGGQcbXKCcbrklV7lv4KLUfFR4UwhskbgOXpJY5PECWdrlGXSw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/react-virtual": "^3.13.2",
|
"@tanstack/react-virtual": "^3.13.2",
|
||||||
@ -6586,6 +6592,7 @@
|
|||||||
"compressorjs": "^1.2.1",
|
"compressorjs": "^1.2.1",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
|
"dexie": "^4.0.11",
|
||||||
"dompurify": "^3.2.4",
|
"dompurify": "^3.2.4",
|
||||||
"react-dropzone": "^14.3.8",
|
"react-dropzone": "^14.3.8",
|
||||||
"react-hot-toast": "^2.5.2",
|
"react-hot-toast": "^2.5.2",
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
"jotai": "^2.12.3",
|
"jotai": "^2.12.3",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"moment": "^2.30.1",
|
"moment": "^2.30.1",
|
||||||
"qapp-core": "^1.0.22",
|
"qapp-core": "^1.0.24",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-countdown-circle-timer": "^3.2.1",
|
"react-countdown-circle-timer": "^3.2.1",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
|
@ -60,6 +60,7 @@ export const baseLocalHost = window.location.host;
|
|||||||
import CloseIcon from "@mui/icons-material/Close";
|
import CloseIcon from "@mui/icons-material/Close";
|
||||||
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
|
import { RequestQueueWithPromise } from "qapp-core";
|
||||||
|
|
||||||
const copyToClipboard = (text: string) => {
|
const copyToClipboard = (text: string) => {
|
||||||
navigator.clipboard.writeText(text);
|
navigator.clipboard.writeText(text);
|
||||||
@ -84,6 +85,9 @@ export const autoSizeStrategy: SizeColumnsToContentStrategy = {
|
|||||||
type: "fitCellContents",
|
type: "fitCellContents",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const requestQueueGetNames = new RequestQueueWithPromise(4);
|
||||||
|
|
||||||
|
|
||||||
export const TradeOffers: React.FC<any> = ({
|
export const TradeOffers: React.FC<any> = ({
|
||||||
foreignCoinBalance,
|
foreignCoinBalance,
|
||||||
fee,
|
fee,
|
||||||
@ -175,9 +179,17 @@ export const TradeOffers: React.FC<any> = ({
|
|||||||
setIsRemoveOrders(val);
|
setIsRemoveOrders(val);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isFetchingName = useRef({})
|
||||||
|
|
||||||
const getName = async (address) => {
|
const getName = async (address) => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch("/names/address/" + address);
|
if(isFetchingName.current[address]) return
|
||||||
|
isFetchingName.current[address] = true
|
||||||
|
const response = await requestQueueGetNames.enqueue(
|
||||||
|
() => {
|
||||||
|
return fetch("/names/address/" + address);
|
||||||
|
}
|
||||||
|
);
|
||||||
const nameData = await response.json();
|
const nameData = await response.json();
|
||||||
if (nameData?.length > 0) {
|
if (nameData?.length > 0) {
|
||||||
setQortalNames((prev) => {
|
setQortalNames((prev) => {
|
||||||
|
@ -549,7 +549,7 @@ export const Header = ({
|
|||||||
setSenderAddress("");
|
setSenderAddress("");
|
||||||
}}
|
}}
|
||||||
backdrop
|
backdrop
|
||||||
open={openCoinActionModal}
|
open={!!openCoinActionModal}
|
||||||
>
|
>
|
||||||
<CoinActionContainer>
|
<CoinActionContainer>
|
||||||
{openCoinActionModal.type === "send" ? (
|
{openCoinActionModal.type === "send" ? (
|
||||||
|
@ -30,7 +30,26 @@ import { usePublish, Service, QortalGetMetadata } from "qapp-core";
|
|||||||
import { SetLeftFeature } from "ag-grid-community";
|
import { SetLeftFeature } from "ag-grid-community";
|
||||||
import { formatTimestampForum } from "../../utils/formatTime";
|
import { formatTimestampForum } from "../../utils/formatTime";
|
||||||
import { useAtom } from "jotai/react";
|
import { useAtom } from "jotai/react";
|
||||||
import { selectedFeePublisherAtom } from "../../global/state";
|
import { isEnabledCustomLockingFeeAtom, selectedFeePublisherAtom } from "../../global/state";
|
||||||
|
|
||||||
|
type FeeEstimate = {
|
||||||
|
height: number;
|
||||||
|
time: number;
|
||||||
|
low_fee_per_kb: number;
|
||||||
|
medium_fee_per_kb: number;
|
||||||
|
high_fee_per_kb: number;
|
||||||
|
};
|
||||||
|
function isValidFeeEstimate(obj: any): obj is FeeEstimate {
|
||||||
|
return (
|
||||||
|
typeof obj === 'object' &&
|
||||||
|
obj !== null &&
|
||||||
|
typeof obj.height === 'number' &&
|
||||||
|
typeof obj.time === 'number' &&
|
||||||
|
typeof obj.low_fee_per_kb === 'number' &&
|
||||||
|
typeof obj.medium_fee_per_kb === 'number' &&
|
||||||
|
typeof obj.high_fee_per_kb === 'number'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function calculateFeeFromRate(feePerKb, sizeInBytes) {
|
function calculateFeeFromRate(feePerKb, sizeInBytes) {
|
||||||
const fee = (feePerKb / 1000) * sizeInBytes;
|
const fee = (feePerKb / 1000) * sizeInBytes;
|
||||||
@ -38,7 +57,8 @@ function calculateFeeFromRate(feePerKb, sizeInBytes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function calculateRateFromFee(totalFee, sizeInBytes) {
|
function calculateRateFromFee(totalFee, sizeInBytes) {
|
||||||
return (totalFee / sizeInBytes) * 1000;
|
const fee = (totalFee / sizeInBytes) * 1000;
|
||||||
|
return fee.toFixed(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FeeManager = ({ selectedCoin, setFee, fee }) => {
|
export const FeeManager = ({ selectedCoin, setFee, fee }) => {
|
||||||
@ -49,13 +69,13 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
|
|||||||
});
|
});
|
||||||
const { resource } = usePublish(3, "JSON", feeLocation);
|
const { resource } = usePublish(3, "JSON", feeLocation);
|
||||||
const [selectedFeePublisher, setSelectedFeePublisher] = useAtom(selectedFeePublisherAtom)
|
const [selectedFeePublisher, setSelectedFeePublisher] = useAtom(selectedFeePublisherAtom)
|
||||||
|
const [isEnabledCustomLockingFee, setIsEnabledCustomLockingFee] = useAtom(isEnabledCustomLockingFeeAtom)
|
||||||
|
|
||||||
const [editFee, setEditFee] = useState("");
|
const [editFee, setEditFee] = useState("");
|
||||||
const [openModal, setOpenModal] = useState(false);
|
const [openModal, setOpenModal] = useState(false);
|
||||||
const [recommendedFee, setRecommendedFee] = useState("m");
|
const [recommendedFee, setRecommendedFee] = useState("m");
|
||||||
const [openAlert, setOpenAlert] = useState(false);
|
const [openAlert, setOpenAlert] = useState(false);
|
||||||
const [info, setInfo] = useState<any>(null);
|
const [info, setInfo] = useState<any>(null);
|
||||||
const [feeTimestamp, setFeeTimestamp] = useState(null)
|
|
||||||
const { getCoinLabel } = useContext(gameContext);
|
const { getCoinLabel } = useContext(gameContext);
|
||||||
const handleCloseAlert = (
|
const handleCloseAlert = (
|
||||||
event?: React.SyntheticEvent | Event,
|
event?: React.SyntheticEvent | Event,
|
||||||
@ -70,10 +90,15 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
|
|||||||
};
|
};
|
||||||
const coin = useMemo(() => {
|
const coin = useMemo(() => {
|
||||||
const coinLabel = getCoinLabel(selectedCoin)
|
const coinLabel = getCoinLabel(selectedCoin)
|
||||||
if(typeof coinLabel !== 'string') return
|
if(typeof coinLabel !== 'string') return null
|
||||||
return coinLabel?.toLowerCase();
|
return coinLabel?.toLowerCase();
|
||||||
}, [selectedCoin, getCoinLabel]);
|
}, [selectedCoin, getCoinLabel]);
|
||||||
|
|
||||||
|
|
||||||
|
const feeTimestamp = useMemo(()=> {
|
||||||
|
if(!resource?.qortalMetadata?.identifier?.includes(`${coin.toUpperCase()}`)) return
|
||||||
|
return resource?.data?.time || null
|
||||||
|
}, [resource, coin])
|
||||||
const establishUpdateFeeForm = useCallback(async (coin) => {
|
const establishUpdateFeeForm = useCallback(async (coin) => {
|
||||||
setFee("");
|
setFee("");
|
||||||
// if the coin or type is not set, then abort
|
// if the coin or type is not set, then abort
|
||||||
@ -107,24 +132,25 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
|
|||||||
}, [coin, establishUpdateFeeForm]);
|
}, [coin, establishUpdateFeeForm]);
|
||||||
|
|
||||||
const recommendedFeeData = useMemo(() => {
|
const recommendedFeeData = useMemo(() => {
|
||||||
|
if(!resource?.qortalMetadata?.identifier?.includes(`${coin.toUpperCase()}`)) return
|
||||||
if (!resource?.data) return null;
|
if (!resource?.data) return null;
|
||||||
|
const isValid = isValidFeeEstimate(resource.data)
|
||||||
|
if(!isValid) return null
|
||||||
return resource.data;
|
return resource.data;
|
||||||
}, [resource?.data]);
|
}, [resource, coin]);
|
||||||
|
|
||||||
const recommendedFeeDisplay = useMemo(() => {
|
const recommendedFeeDisplay = useMemo(() => {
|
||||||
if (!selectedCoin || !recommendedFeeData) return null;
|
if (!recommendedFeeData) return null;
|
||||||
const coinLabel = getCoinLabel(selectedCoin)
|
|
||||||
if(typeof coinLabel !== 'string') return
|
if(!recommendedFeeData) return null
|
||||||
const coin = coinLabel?.toUpperCase();
|
return recommendedFeeData[recommendedFee] || null;
|
||||||
if(!recommendedFeeData[coin]) return null
|
}, [recommendedFeeData, recommendedFee]);
|
||||||
return recommendedFeeData[coin][recommendedFee];
|
|
||||||
}, [recommendedFeeData, recommendedFee, selectedCoin]);
|
|
||||||
|
|
||||||
const hideRecommendations = useMemo(()=> {
|
const hideRecommendations = useMemo(()=> {
|
||||||
if(selectedCoin === 'LITECOIN' || selectedCoin === 'BITCOIN' || selectedCoin === 'DOGECOIN') return false
|
if(recommendedFeeData) return false
|
||||||
return true
|
return true
|
||||||
}, [selectedCoin])
|
}, [recommendedFeeData])
|
||||||
|
|
||||||
|
|
||||||
useEffect(()=> {
|
useEffect(()=> {
|
||||||
if(hideRecommendations){
|
if(hideRecommendations){
|
||||||
@ -134,6 +160,7 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
|
|||||||
|
|
||||||
const updateFee = async () => {
|
const updateFee = async () => {
|
||||||
const typeRequest = "feerequired";
|
const typeRequest = "feerequired";
|
||||||
|
const typeRequestLocking = "feekb";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let feeToSave = editFee
|
let feeToSave = editFee
|
||||||
@ -150,6 +177,19 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
|
|||||||
1800000
|
1800000
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(!isEnabledCustomLockingFee){
|
||||||
|
await qortalRequestWithTimeout(
|
||||||
|
{
|
||||||
|
action: "UPDATE_FOREIGN_FEE",
|
||||||
|
coin: coin,
|
||||||
|
type: typeRequestLocking,
|
||||||
|
value: calculateRateFromFee(feeToSave, 300),
|
||||||
|
},
|
||||||
|
1800000
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (response && !isNaN(+response)) {
|
if (response && !isNaN(+response)) {
|
||||||
setFee(response);
|
setFee(response);
|
||||||
setOpenAlert(true);
|
setOpenAlert(true);
|
||||||
@ -181,21 +221,21 @@ export const FeeManager = ({ selectedCoin, setFee, fee }) => {
|
|||||||
|
|
||||||
const getLatestFees = useCallback(async () => {
|
const getLatestFees = useCallback(async () => {
|
||||||
try {
|
try {
|
||||||
|
const coinLabel = getCoinLabel(selectedCoin)
|
||||||
|
if(typeof coinLabel !== 'string') return
|
||||||
|
const coin = coinLabel?.toUpperCase();
|
||||||
|
const identifier = `coinInfo-${coin}`
|
||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`/arbitrary/resources/searchsimple?service=JSON&identifier=foreign-fee&name=${selectedFeePublisher}&prefix=true&limit=1&reverse=true`
|
`/arbitrary/resources/searchsimple?service=JSON&identifier=${identifier}&name=${selectedFeePublisher}&prefix=true&limit=1&reverse=true`
|
||||||
);
|
);
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data && data?.length > 0) {
|
if (data && data?.length > 0) {
|
||||||
setFeeLocation(data[0]);
|
setFeeLocation(data[0]);
|
||||||
const id = data[0].identifier;
|
|
||||||
const parts = id.split("-");
|
|
||||||
const timestampSec = parseInt(parts[2], 10);
|
|
||||||
setFeeTimestamp(timestampSec)
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
}, [selectedFeePublisher]);
|
}, [selectedFeePublisher, selectedCoin]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getLatestFees();
|
getLatestFees();
|
||||||
@ -286,9 +326,9 @@ const timestampSec = parseInt(parts[2], 10);
|
|||||||
>
|
>
|
||||||
{!hideRecommendations && (
|
{!hideRecommendations && (
|
||||||
<>
|
<>
|
||||||
<ToggleButton value="l">Low</ToggleButton>
|
<ToggleButton value="low_fee_per_kb">Low</ToggleButton>
|
||||||
<ToggleButton value="m">Medium</ToggleButton>
|
<ToggleButton value="medium_fee_per_kb">Medium</ToggleButton>
|
||||||
<ToggleButton value="h">High</ToggleButton>
|
<ToggleButton value="high_fee_per_kb">High</ToggleButton>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@ import {
|
|||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
ButtonBase,
|
ButtonBase,
|
||||||
|
Checkbox,
|
||||||
|
FormControlLabel,
|
||||||
IconButton,
|
IconButton,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
Select,
|
Select,
|
||||||
@ -32,21 +34,25 @@ import {
|
|||||||
} from "../header/Header-styles";
|
} from "../header/Header-styles";
|
||||||
import { CustomInput, CustomLabel } from "./CreateSell";
|
import { CustomInput, CustomLabel } from "./CreateSell";
|
||||||
import { Spacer } from "../common/Spacer";
|
import { Spacer } from "../common/Spacer";
|
||||||
import { usePublish, Service, QortalGetMetadata } from "qapp-core";
|
import { usePublish, Service, QortalGetMetadata, useGlobal } from "qapp-core";
|
||||||
import { SetLeftFeature } from "ag-grid-community";
|
import { SetLeftFeature } from "ag-grid-community";
|
||||||
import { formatTimestampForum } from "../../utils/formatTime";
|
import { formatTimestampForum } from "../../utils/formatTime";
|
||||||
import { SelectRow } from "../header/Header";
|
import { SelectRow } from "../header/Header";
|
||||||
import { useAtom } from "jotai/react";
|
import { useAtom } from "jotai/react";
|
||||||
import { selectedFeePublisherAtom } from "../../global/state";
|
import { isEnabledCustomLockingFeeAtom, selectedFeePublisherAtom } from "../../global/state";
|
||||||
|
|
||||||
export const Settings = () => {
|
export const Settings = () => {
|
||||||
|
const saveDataLocal = useGlobal().persistentOperations.saveData
|
||||||
|
const getDataLocal = useGlobal().persistentOperations.getData
|
||||||
const [openModal, setOpenModal] = useState(false);
|
const [openModal, setOpenModal] = useState(false);
|
||||||
const [lockingFee, setLockingFee] = useState("");
|
const [lockingFee, setLockingFee] = useState("");
|
||||||
|
|
||||||
const [editLockingFee, setEditLockingFee] = useState("");
|
const [editLockingFee, setEditLockingFee] = useState("");
|
||||||
const [openAlert, setOpenAlert] = useState(false);
|
const [openAlert, setOpenAlert] = useState(false);
|
||||||
const [info, setInfo] = useState<any>(null);
|
const [info, setInfo] = useState<any>(null);
|
||||||
const [selectedCoin, setSelectedCoin] = useState("LTC");
|
const [selectedCoin, setSelectedCoin] = useState("LTC");
|
||||||
const [selectedFeePublisher, setSelectedFeePublisher] = useAtom(selectedFeePublisherAtom)
|
const [selectedFeePublisher, setSelectedFeePublisher] = useAtom(selectedFeePublisherAtom)
|
||||||
|
const [isEnabledCustomLockingFee, setIsEnabledCustomLockingFee] = useAtom(isEnabledCustomLockingFeeAtom)
|
||||||
const handleCloseAlert = (
|
const handleCloseAlert = (
|
||||||
event?: React.SyntheticEvent | Event,
|
event?: React.SyntheticEvent | Event,
|
||||||
reason?: SnackbarCloseReason
|
reason?: SnackbarCloseReason
|
||||||
@ -94,6 +100,11 @@ export const Settings = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
setIsEnabledCustomLockingFee(event.target.checked);
|
||||||
|
saveDataLocal('isEnabledCustomLockingFee', event.target.checked)
|
||||||
|
};
|
||||||
|
|
||||||
const establishUpdateFeeForm = useCallback(async (coin) => {
|
const establishUpdateFeeForm = useCallback(async (coin) => {
|
||||||
setLockingFee("");
|
setLockingFee("");
|
||||||
setEditLockingFee("");
|
setEditLockingFee("");
|
||||||
@ -125,8 +136,27 @@ export const Settings = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if(!openModal) return
|
||||||
establishUpdateFeeForm(selectedCoin);
|
establishUpdateFeeForm(selectedCoin);
|
||||||
}, [selectedCoin, establishUpdateFeeForm]);
|
}, [selectedCoin, establishUpdateFeeForm, openModal]);
|
||||||
|
|
||||||
|
useEffect(()=> {
|
||||||
|
const getSavedSelectedPublisher = async ()=> {
|
||||||
|
try {
|
||||||
|
const res = await getDataLocal('selectedFeePublisher')
|
||||||
|
if(res){
|
||||||
|
setSelectedFeePublisher(res)
|
||||||
|
}
|
||||||
|
const res2 = await getDataLocal('isEnabledCustomLockingFee')
|
||||||
|
if(res2){
|
||||||
|
setIsEnabledCustomLockingFee(res)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getSavedSelectedPublisher()
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -163,48 +193,53 @@ export const Settings = () => {
|
|||||||
padding: '5px'
|
padding: '5px'
|
||||||
}}>
|
}}>
|
||||||
<Typography>Locking fees</Typography>
|
<Typography>Locking fees</Typography>
|
||||||
<CoinSelectRow sx={{
|
<FormControlLabel control={<Checkbox checked={isEnabledCustomLockingFee} onChange={handleChange} />} label="Enable custom locking fee" />
|
||||||
gap: '20px'
|
|
||||||
}}>
|
{isEnabledCustomLockingFee && (
|
||||||
<Select
|
<CoinSelectRow sx={{
|
||||||
size="small"
|
gap: '20px'
|
||||||
value={selectedCoin}
|
}}>
|
||||||
onChange={(e) => {
|
<Select
|
||||||
setLockingFee("");
|
size="small"
|
||||||
setEditLockingFee("");
|
value={selectedCoin}
|
||||||
setSelectedCoin(e.target.value);
|
onChange={(e) => {
|
||||||
}}
|
setLockingFee("");
|
||||||
>
|
setEditLockingFee("");
|
||||||
<MenuItem value={"LTC"}>
|
setSelectedCoin(e.target.value);
|
||||||
<SelectRow coin="LTC" />
|
}}
|
||||||
</MenuItem>
|
>
|
||||||
<MenuItem value={"DOGE"}>
|
<MenuItem value={"LTC"}>
|
||||||
<SelectRow coin="DOGE" />
|
<SelectRow coin="LTC" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value={"BTC"}>
|
<MenuItem value={"DOGE"}>
|
||||||
<SelectRow coin="BTC" />
|
<SelectRow coin="DOGE" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value={"DGB"}>
|
<MenuItem value={"BTC"}>
|
||||||
<SelectRow coin="DGB" />
|
<SelectRow coin="BTC" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem value={"RVN"}>
|
<MenuItem value={"DGB"}>
|
||||||
<SelectRow coin="RVN" />
|
<SelectRow coin="DGB" />
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Select>
|
<MenuItem value={"RVN"}>
|
||||||
<Box>
|
<SelectRow coin="RVN" />
|
||||||
<CustomLabel htmlFor="standard-adornment-name">
|
</MenuItem>
|
||||||
Locking fee for {selectedCoin} (sats)
|
</Select>
|
||||||
</CustomLabel>
|
<Box>
|
||||||
<Spacer height="5px" />
|
<CustomLabel htmlFor="standard-adornment-name">
|
||||||
<CustomInput
|
Locking fee for {selectedCoin} (sats per kb)
|
||||||
id="standard-adornment-name"
|
</CustomLabel>
|
||||||
type="number"
|
<Spacer height="5px" />
|
||||||
value={editLockingFee}
|
<CustomInput
|
||||||
onChange={(e) => setEditLockingFee(e.target.value)}
|
id="standard-adornment-name"
|
||||||
autoComplete="off"
|
type="number"
|
||||||
/>
|
value={editLockingFee}
|
||||||
</Box>
|
onChange={(e) => setEditLockingFee(e.target.value)}
|
||||||
</CoinSelectRow>
|
autoComplete="off"
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</CoinSelectRow>
|
||||||
|
)}
|
||||||
|
|
||||||
|
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
onClick={updateLockingFee}
|
onClick={updateLockingFee}
|
||||||
@ -242,7 +277,11 @@ export const Settings = () => {
|
|||||||
size="small"
|
size="small"
|
||||||
value={selectedFeePublisher}
|
value={selectedFeePublisher}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setSelectedFeePublisher(e.target.value);
|
if(e.target.value){
|
||||||
|
setSelectedFeePublisher(e.target.value);
|
||||||
|
saveDataLocal('selectedFeePublisher', e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MenuItem value={"Foreign-Fee-Publisher"}>
|
<MenuItem value={"Foreign-Fee-Publisher"}>
|
||||||
|
2
src/global.d.ts
vendored
2
src/global.d.ts
vendored
@ -44,7 +44,7 @@ interface QortalRequestOptions {
|
|||||||
foreignAmount?: number;
|
foreignAmount?: number;
|
||||||
atAddress?: string;
|
atAddress?: string;
|
||||||
type?: string
|
type?: string
|
||||||
value?: string
|
value?: string | number
|
||||||
}
|
}
|
||||||
|
|
||||||
declare function qortalRequest(options: QortalRequestOptions): Promise<any>;
|
declare function qortalRequest(options: QortalRequestOptions): Promise<any>;
|
||||||
|
@ -2,4 +2,6 @@ import { atomWithReset } from 'jotai/utils';
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const selectedFeePublisherAtom = atomWithReset('Foreign-Fee-Publisher');
|
export const selectedFeePublisherAtom = atomWithReset('Ice.JSON');
|
||||||
|
|
||||||
|
export const isEnabledCustomLockingFeeAtom = atomWithReset(false);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user