mirror of
https://github.com/Qortal/qortal-mobile.git
synced 2025-05-06 01:37:52 +00:00
Compare commits
No commits in common. "feature/initial-conversion" and "v0.5.4-pre" have entirely different histories.
feature/in
...
v0.5.4-pre
141
src/App.tsx
141
src/App.tsx
@ -21,7 +21,6 @@ import {
|
|||||||
DialogContentText,
|
DialogContentText,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
Divider,
|
Divider,
|
||||||
FormControlLabel,
|
|
||||||
Input,
|
Input,
|
||||||
InputLabel,
|
InputLabel,
|
||||||
Popover,
|
Popover,
|
||||||
@ -30,7 +29,6 @@ import {
|
|||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { decryptStoredWallet } from "./utils/decryptWallet";
|
import { decryptStoredWallet } from "./utils/decryptWallet";
|
||||||
import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet';
|
import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet';
|
||||||
import PriorityHighIcon from '@mui/icons-material/PriorityHigh';
|
|
||||||
|
|
||||||
import { JsonView, allExpanded, darkStyles } from 'react-json-view-lite';
|
import { JsonView, allExpanded, darkStyles } from 'react-json-view-lite';
|
||||||
import 'react-json-view-lite/dist/index.css';
|
import 'react-json-view-lite/dist/index.css';
|
||||||
@ -155,7 +153,6 @@ import { BuyQortInformation } from "./components/BuyQortInformation";
|
|||||||
import { InstallPWA } from "./components/InstallPWA";
|
import { InstallPWA } from "./components/InstallPWA";
|
||||||
import { QortPayment } from "./components/QortPayment";
|
import { QortPayment } from "./components/QortPayment";
|
||||||
import { PdfViewer } from "./common/PdfViewer";
|
import { PdfViewer } from "./common/PdfViewer";
|
||||||
import { DownloadWallet } from "./components/Auth/DownloadWallet";
|
|
||||||
|
|
||||||
|
|
||||||
type extStates =
|
type extStates =
|
||||||
@ -489,8 +486,6 @@ function App() {
|
|||||||
url: "http://127.0.0.1:12391",
|
url: "http://127.0.0.1:12391",
|
||||||
});
|
});
|
||||||
const [useLocalNode, setUseLocalNode] = useState(false);
|
const [useLocalNode, setUseLocalNode] = useState(false);
|
||||||
const [confirmRequestRead, setConfirmRequestRead] = useState(false);
|
|
||||||
|
|
||||||
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
|
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
|
||||||
const [showSeed, setShowSeed] = useState(false)
|
const [showSeed, setShowSeed] = useState(false)
|
||||||
const [creationStep, setCreationStep] = useState(1)
|
const [creationStep, setCreationStep] = useState(1)
|
||||||
@ -883,8 +878,6 @@ function App() {
|
|||||||
if(message?.payload?.checkbox1){
|
if(message?.payload?.checkbox1){
|
||||||
qortalRequestCheckbox1Ref.current = message?.payload?.checkbox1?.value || false
|
qortalRequestCheckbox1Ref.current = message?.payload?.checkbox1?.value || false
|
||||||
}
|
}
|
||||||
setConfirmRequestRead(false)
|
|
||||||
|
|
||||||
await showQortalRequestExtension(message?.payload);
|
await showQortalRequestExtension(message?.payload);
|
||||||
if (qortalRequestCheckbox1Ref.current) {
|
if (qortalRequestCheckbox1Ref.current) {
|
||||||
event.source.postMessage(
|
event.source.postMessage(
|
||||||
@ -2585,14 +2578,87 @@ function App() {
|
|||||||
)}
|
)}
|
||||||
{extState === "download-wallet" && (
|
{extState === "download-wallet" && (
|
||||||
<>
|
<>
|
||||||
<DownloadWallet
|
<Spacer height="22px" />
|
||||||
returnToMain={returnToMain}
|
<Box
|
||||||
setIsLoading={setIsLoading}
|
sx={{
|
||||||
showInfo={showInfo}
|
display: "flex",
|
||||||
rawWallet={rawWallet}
|
width: "100%",
|
||||||
setWalletToBeDownloaded={setWalletToBeDownloaded}
|
justifyContent: "flex-start",
|
||||||
walletToBeDownloaded={walletToBeDownloaded}
|
paddingLeft: "22px",
|
||||||
|
boxSizing: "border-box",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
}}
|
||||||
|
onClick={returnToMain}
|
||||||
|
src={Return}
|
||||||
/>
|
/>
|
||||||
|
</Box>
|
||||||
|
<Spacer height="10px" />
|
||||||
|
<div
|
||||||
|
className="image-container"
|
||||||
|
style={{
|
||||||
|
width: "136px",
|
||||||
|
height: "154px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img src={Logo1Dark} className="base-image" />
|
||||||
|
</div>
|
||||||
|
<Spacer height="35px" />
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
alignItems: "flex-start",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextP
|
||||||
|
sx={{
|
||||||
|
textAlign: "start",
|
||||||
|
lineHeight: "24px",
|
||||||
|
fontSize: "20px",
|
||||||
|
fontWeight: 600,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Download Account
|
||||||
|
</TextP>
|
||||||
|
</Box>
|
||||||
|
<Spacer height="35px" />
|
||||||
|
{!walletToBeDownloaded && (
|
||||||
|
<>
|
||||||
|
<CustomLabel htmlFor="standard-adornment-password">
|
||||||
|
Confirm Wallet Password
|
||||||
|
</CustomLabel>
|
||||||
|
<Spacer height="5px" />
|
||||||
|
<PasswordField
|
||||||
|
id="standard-adornment-password"
|
||||||
|
value={walletToBeDownloadedPassword}
|
||||||
|
onChange={(e) =>
|
||||||
|
setWalletToBeDownloadedPassword(e.target.value)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Spacer height="20px" />
|
||||||
|
<CustomButton onClick={confirmPasswordToDownload}>
|
||||||
|
Confirm password
|
||||||
|
</CustomButton>
|
||||||
|
<ErrorText>{walletToBeDownloadedError}</ErrorText>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{walletToBeDownloaded && (
|
||||||
|
<>
|
||||||
|
<CustomButton onClick={async ()=> {
|
||||||
|
await saveFileToDiskFunc()
|
||||||
|
await showInfo({
|
||||||
|
message: isNative ? `Your account file was saved to internal storage, in the document folder. Keep that file secure.` : `Your account file was downloaded by your browser. Keep that file secure.` ,
|
||||||
|
})
|
||||||
|
}}>
|
||||||
|
Download account
|
||||||
|
</CustomButton>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{extState === "create-wallet" && (
|
{extState === "create-wallet" && (
|
||||||
@ -3044,7 +3110,7 @@ function App() {
|
|||||||
>
|
>
|
||||||
<CountdownCircleTimer
|
<CountdownCircleTimer
|
||||||
isPlaying
|
isPlaying
|
||||||
duration={60}
|
duration={30}
|
||||||
colors={["#004777", "#F7B801", "#A30000", "#A30000"]}
|
colors={["#004777", "#F7B801", "#A30000", "#A30000"]}
|
||||||
colorsTime={[7, 5, 2, 0]}
|
colorsTime={[7, 5, 2, 0]}
|
||||||
onComplete={() => {
|
onComplete={() => {
|
||||||
@ -3125,14 +3191,12 @@ function App() {
|
|||||||
>
|
>
|
||||||
{messageQortalRequestExtension?.text3}
|
{messageQortalRequestExtension?.text3}
|
||||||
</TextP>
|
</TextP>
|
||||||
|
|
||||||
</Box>
|
|
||||||
<Spacer height="15px" />
|
<Spacer height="15px" />
|
||||||
|
</Box>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{messageQortalRequestExtension?.text4 && (
|
{messageQortalRequestExtension?.text4 && (
|
||||||
<>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -3150,8 +3214,6 @@ function App() {
|
|||||||
{messageQortalRequestExtension?.text4}
|
{messageQortalRequestExtension?.text4}
|
||||||
</TextP>
|
</TextP>
|
||||||
</Box>
|
</Box>
|
||||||
<Spacer height="15px" />
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{messageQortalRequestExtension?.html && (
|
{messageQortalRequestExtension?.html && (
|
||||||
@ -3279,35 +3341,6 @@ function App() {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
{messageQortalRequestExtension?.confirmCheckbox && (
|
|
||||||
<FormControlLabel
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
onChange={(e) => setConfirmRequestRead(e.target.checked)}
|
|
||||||
checked={confirmRequestRead}
|
|
||||||
edge="start"
|
|
||||||
tabIndex={-1}
|
|
||||||
disableRipple
|
|
||||||
sx={{
|
|
||||||
"&.Mui-checked": {
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
"& .MuiSvgIcon-root": {
|
|
||||||
color: "white",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label={
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
<Typography sx={{ fontSize: "14px" }}>
|
|
||||||
I have read this request
|
|
||||||
</Typography>
|
|
||||||
<PriorityHighIcon color="warning" />
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Spacer height="29px" />
|
<Spacer height="29px" />
|
||||||
<Box
|
<Box
|
||||||
@ -3322,16 +3355,8 @@ function App() {
|
|||||||
bgColor="var(--green)"
|
bgColor="var(--green)"
|
||||||
sx={{
|
sx={{
|
||||||
minWidth: "102px",
|
minWidth: "102px",
|
||||||
opacity: messageQortalRequestExtension?.confirmCheckbox && !confirmRequestRead ? 0.1 : 0.7,
|
|
||||||
cursor: messageQortalRequestExtension?.confirmCheckbox && !confirmRequestRead ? 'default' : 'pointer',
|
|
||||||
"&:hover": {
|
|
||||||
opacity: messageQortalRequestExtension?.confirmCheckbox && !confirmRequestRead ? 0.1 : 1,
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
if(messageQortalRequestExtension?.confirmCheckbox && !confirmRequestRead) return
|
|
||||||
onOkQortalRequestExtension("accepted")
|
|
||||||
}}
|
}}
|
||||||
|
onClick={() => onOkQortalRequestExtension("accepted")}
|
||||||
>
|
>
|
||||||
accept
|
accept
|
||||||
</CustomButtonAccept>
|
</CustomButtonAccept>
|
||||||
|
@ -41,14 +41,6 @@ export const sortablePinnedAppsAtom = atom({
|
|||||||
{
|
{
|
||||||
name: 'Q-Wallets',
|
name: 'Q-Wallets',
|
||||||
service: 'APP'
|
service: 'APP'
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Q-Search',
|
|
||||||
service: 'APP'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Q-Nodecontrol',
|
|
||||||
service: 'APP'
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@ -188,8 +180,3 @@ export const lastPaymentSeenTimestampAtom = atom<null | number>({
|
|||||||
key: 'lastPaymentSeenTimestampAtom',
|
key: 'lastPaymentSeenTimestampAtom',
|
||||||
default: null,
|
default: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const isOpenBlockedModalAtom = atom({
|
|
||||||
key: 'isOpenBlockedModalAtom',
|
|
||||||
default: false,
|
|
||||||
});
|
|
@ -928,59 +928,6 @@ export async function getBalanceInfo() {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAssetBalanceInfo(assetId: number) {
|
|
||||||
const wallet = await getSaveWallet();
|
|
||||||
const address = wallet.address0;
|
|
||||||
const validApi = await getBaseApi();
|
|
||||||
const response = await fetch(validApi + `/assets/balances?address=${address}&assetid=${assetId}&ordering=ASSET_BALANCE_ACCOUNT&limit=1`);
|
|
||||||
|
|
||||||
if (!response?.ok) throw new Error("Cannot fetch asset balance");
|
|
||||||
const data = await response.json();
|
|
||||||
return +data?.[0]?.balance
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAssetInfo(assetId: number) {
|
|
||||||
const validApi = await getBaseApi();
|
|
||||||
const response = await fetch(validApi + `/assets/info?assetId=${assetId}`);
|
|
||||||
|
|
||||||
if (!response?.ok) throw new Error("Cannot fetch asset info");
|
|
||||||
const data = await response.json();
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function transferAsset({
|
|
||||||
amount,
|
|
||||||
recipient,
|
|
||||||
assetId,
|
|
||||||
}) {
|
|
||||||
const lastReference = await getLastRef();
|
|
||||||
const resKeyPair = await getKeyPair();
|
|
||||||
const parsedData = resKeyPair;
|
|
||||||
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
||||||
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
||||||
const keyPair = {
|
|
||||||
privateKey: uint8PrivateKey,
|
|
||||||
publicKey: uint8PublicKey,
|
|
||||||
};
|
|
||||||
const feeres = await getFee("TRANSFER_ASSET");
|
|
||||||
|
|
||||||
const tx = await createTransaction(12, keyPair, {
|
|
||||||
fee: feeres.fee,
|
|
||||||
recipient: recipient,
|
|
||||||
amount: amount,
|
|
||||||
assetId: assetId,
|
|
||||||
lastReference: lastReference,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
const signedBytes = Base58.encode(tx.signedBytes);
|
|
||||||
|
|
||||||
const res = await processTransactionVersion2(signedBytes);
|
|
||||||
if (!res?.signature)
|
|
||||||
throw new Error(res?.message || "Transaction was not able to be processed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
export async function getLTCBalance() {
|
export async function getLTCBalance() {
|
||||||
const wallet = await getSaveWallet();
|
const wallet = await getSaveWallet();
|
||||||
let _url = `${buyTradeNodeBaseUrl}/crosschain/ltc/walletbalance`;
|
let _url = `${buyTradeNodeBaseUrl}/crosschain/ltc/walletbalance`;
|
||||||
@ -2300,150 +2247,6 @@ export async function createGroup({
|
|||||||
if (!res?.signature) throw new Error(res?.message || "Transaction was not able to be processed");
|
if (!res?.signature) throw new Error(res?.message || "Transaction was not able to be processed");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sellName({
|
|
||||||
name,
|
|
||||||
sellPrice
|
|
||||||
}) {
|
|
||||||
const wallet = await getSaveWallet();
|
|
||||||
const address = wallet.address0;
|
|
||||||
if (!address) throw new Error("Cannot find user");
|
|
||||||
const lastReference = await getLastRef();
|
|
||||||
const feeres = await getFee("SELL_NAME");
|
|
||||||
const resKeyPair = await getKeyPair();
|
|
||||||
const parsedData = resKeyPair;
|
|
||||||
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
||||||
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
||||||
const keyPair = {
|
|
||||||
privateKey: uint8PrivateKey,
|
|
||||||
publicKey: uint8PublicKey,
|
|
||||||
};
|
|
||||||
|
|
||||||
const tx = await createTransaction(5, keyPair, {
|
|
||||||
fee: feeres.fee,
|
|
||||||
name,
|
|
||||||
sellPrice: sellPrice,
|
|
||||||
lastReference: lastReference,
|
|
||||||
});
|
|
||||||
|
|
||||||
const signedBytes = Base58.encode(tx.signedBytes);
|
|
||||||
|
|
||||||
const res = await processTransactionVersion2(signedBytes);
|
|
||||||
if (!res?.signature)
|
|
||||||
throw new Error(res?.message || "Transaction was not able to be processed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function cancelSellName({
|
|
||||||
name
|
|
||||||
}) {
|
|
||||||
const wallet = await getSaveWallet();
|
|
||||||
const address = wallet.address0;
|
|
||||||
if (!address) throw new Error("Cannot find user");
|
|
||||||
const lastReference = await getLastRef();
|
|
||||||
const feeres = await getFee("SELL_NAME");
|
|
||||||
const resKeyPair = await getKeyPair();
|
|
||||||
const parsedData = resKeyPair;
|
|
||||||
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
||||||
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
||||||
const keyPair = {
|
|
||||||
privateKey: uint8PrivateKey,
|
|
||||||
publicKey: uint8PublicKey,
|
|
||||||
};
|
|
||||||
|
|
||||||
const tx = await createTransaction(6, keyPair, {
|
|
||||||
fee: feeres.fee,
|
|
||||||
name,
|
|
||||||
lastReference: lastReference,
|
|
||||||
});
|
|
||||||
|
|
||||||
const signedBytes = Base58.encode(tx.signedBytes);
|
|
||||||
|
|
||||||
const res = await processTransactionVersion2(signedBytes);
|
|
||||||
if (!res?.signature)
|
|
||||||
throw new Error(res?.message || "Transaction was not able to be processed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function buyName({
|
|
||||||
name,
|
|
||||||
sellerAddress,
|
|
||||||
sellPrice
|
|
||||||
}) {
|
|
||||||
const wallet = await getSaveWallet();
|
|
||||||
const address = wallet.address0;
|
|
||||||
if (!address) throw new Error("Cannot find user");
|
|
||||||
const lastReference = await getLastRef();
|
|
||||||
const feeres = await getFee("BUY_NAME");
|
|
||||||
const resKeyPair = await getKeyPair();
|
|
||||||
const parsedData = resKeyPair;
|
|
||||||
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
||||||
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
||||||
const keyPair = {
|
|
||||||
privateKey: uint8PrivateKey,
|
|
||||||
publicKey: uint8PublicKey,
|
|
||||||
};
|
|
||||||
|
|
||||||
const tx = await createTransaction(7, keyPair, {
|
|
||||||
fee: feeres.fee,
|
|
||||||
name,
|
|
||||||
sellPrice,
|
|
||||||
recipient: sellerAddress,
|
|
||||||
lastReference: lastReference,
|
|
||||||
});
|
|
||||||
|
|
||||||
const signedBytes = Base58.encode(tx.signedBytes);
|
|
||||||
|
|
||||||
const res = await processTransactionVersion2(signedBytes);
|
|
||||||
if (!res?.signature)
|
|
||||||
throw new Error(res?.message || "Transaction was not able to be processed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function updateGroup({
|
|
||||||
groupId,
|
|
||||||
newOwner,
|
|
||||||
newIsOpen,
|
|
||||||
newDescription,
|
|
||||||
newApprovalThreshold,
|
|
||||||
newMinimumBlockDelay,
|
|
||||||
newMaximumBlockDelay
|
|
||||||
}) {
|
|
||||||
const wallet = await getSaveWallet();
|
|
||||||
const address = wallet.address0;
|
|
||||||
if (!address) throw new Error("Cannot find user");
|
|
||||||
const lastReference = await getLastRef();
|
|
||||||
const feeres = await getFee("UPDATE_GROUP");
|
|
||||||
const resKeyPair = await getKeyPair();
|
|
||||||
const parsedData = resKeyPair;
|
|
||||||
const uint8PrivateKey = Base58.decode(parsedData.privateKey);
|
|
||||||
const uint8PublicKey = Base58.decode(parsedData.publicKey);
|
|
||||||
const keyPair = {
|
|
||||||
privateKey: uint8PrivateKey,
|
|
||||||
publicKey: uint8PublicKey,
|
|
||||||
};
|
|
||||||
|
|
||||||
const tx = await createTransaction(23, keyPair, {
|
|
||||||
fee: feeres.fee,
|
|
||||||
_groupId: groupId,
|
|
||||||
newOwner,
|
|
||||||
newIsOpen,
|
|
||||||
newDescription,
|
|
||||||
newApprovalThreshold,
|
|
||||||
newMinimumBlockDelay,
|
|
||||||
newMaximumBlockDelay,
|
|
||||||
lastReference: lastReference,
|
|
||||||
});
|
|
||||||
|
|
||||||
const signedBytes = Base58.encode(tx.signedBytes);
|
|
||||||
|
|
||||||
const res = await processTransactionVersion2(signedBytes);
|
|
||||||
if (!res?.signature)
|
|
||||||
throw new Error(res?.message || "Transaction was not able to be processed");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export async function inviteToGroup({ groupId, qortalAddress, inviteTime }) {
|
export async function inviteToGroup({ groupId, qortalAddress, inviteTime }) {
|
||||||
const address = await getNameOrAddress(qortalAddress);
|
const address = await getNameOrAddress(qortalAddress);
|
||||||
if (!address) throw new Error("Cannot find user");
|
if (!address) throw new Error("Cannot find user");
|
||||||
|
@ -130,17 +130,12 @@ export const BoundedNumericTextField = ({
|
|||||||
...props?.InputProps,
|
...props?.InputProps,
|
||||||
endAdornment: addIconButtons ? (
|
endAdornment: addIconButtons ? (
|
||||||
<InputAdornment position="end">
|
<InputAdornment position="end">
|
||||||
<IconButton size="small" onClick={() =>
|
<IconButton size="small" onClick={() => changeValueWithIncDecButton(1)}>
|
||||||
changeValueWithIncDecButton(1)
|
|
||||||
|
|
||||||
} onTouchStart={(e)=> e.stopPropagation()}>
|
|
||||||
<AddIcon sx={{
|
<AddIcon sx={{
|
||||||
color: 'white'
|
color: 'white'
|
||||||
}} />{" "}
|
}} />{" "}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton onTouchStart={(e)=> e.stopPropagation()} size="small" onClick={() =>
|
<IconButton size="small" onClick={() => changeValueWithIncDecButton(-1)}>
|
||||||
changeValueWithIncDecButton(-1)
|
|
||||||
}>
|
|
||||||
<RemoveIcon sx={{
|
<RemoveIcon sx={{
|
||||||
color: 'white'
|
color: 'white'
|
||||||
}} />{" "}
|
}} />{" "}
|
||||||
|
@ -41,9 +41,7 @@ const officialAppList = [
|
|||||||
"q-trade",
|
"q-trade",
|
||||||
"q-support",
|
"q-support",
|
||||||
"q-manager",
|
"q-manager",
|
||||||
"q-wallets",
|
"q-wallets"
|
||||||
"q-search",
|
|
||||||
"q-nodecontrol"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const ScrollerStyled = styled('div')({
|
const ScrollerStyled = styled('div')({
|
||||||
|
@ -47,9 +47,7 @@ const officialAppList = [
|
|||||||
"q-fund",
|
"q-fund",
|
||||||
"q-shop",
|
"q-shop",
|
||||||
"q-manager",
|
"q-manager",
|
||||||
"q-wallets",
|
"q-wallets"
|
||||||
"q-search",
|
|
||||||
"q-nodecontrol"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const ScrollerStyled = styled("div")({
|
const ScrollerStyled = styled("div")({
|
||||||
|
@ -45,9 +45,7 @@ const officialAppList = [
|
|||||||
"q-support",
|
"q-support",
|
||||||
"q-manager",
|
"q-manager",
|
||||||
"q-mintership",
|
"q-mintership",
|
||||||
"q-wallets",
|
"q-wallets"
|
||||||
"q-search",
|
|
||||||
"q-nodecontrol"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const ScrollerStyled = styled('div')({
|
const ScrollerStyled = styled('div')({
|
||||||
|
@ -56,9 +56,7 @@ const officialAppList = [
|
|||||||
"q-shop",
|
"q-shop",
|
||||||
"q-manager",
|
"q-manager",
|
||||||
"q-mintership",
|
"q-mintership",
|
||||||
"q-wallets",
|
"q-wallets"
|
||||||
"q-search",
|
|
||||||
"q-nodecontrol"
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const ScrollerStyled = styled("div")({
|
const ScrollerStyled = styled("div")({
|
||||||
|
@ -255,13 +255,7 @@ export function openIndexedDB() {
|
|||||||
'GET_NODE_INFO',
|
'GET_NODE_INFO',
|
||||||
'GET_NODE_STATUS',
|
'GET_NODE_STATUS',
|
||||||
'GET_ARRR_SYNC_STATUS',
|
'GET_ARRR_SYNC_STATUS',
|
||||||
'SHOW_PDF_READER',
|
'SHOW_PDF_READER'
|
||||||
'UPDATE_GROUP',
|
|
||||||
'SELL_NAME',
|
|
||||||
'CANCEL_SELL_NAME',
|
|
||||||
'BUY_NAME', 'MULTI_ASSET_PAYMENT_WITH_PRIVATE_DATA',
|
|
||||||
'TRANSFER_ASSET',
|
|
||||||
'SIGN_FOREIGN_FEES',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -275,11 +269,7 @@ const UIQortalRequests = [
|
|||||||
'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER',
|
'GET_SERVER_CONNECTION_HISTORY', 'SET_CURRENT_FOREIGN_SERVER',
|
||||||
'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY', 'CREATE_TRADE_BUY_ORDER',
|
'ADD_FOREIGN_SERVER', 'REMOVE_FOREIGN_SERVER', 'GET_DAY_SUMMARY', 'CREATE_TRADE_BUY_ORDER',
|
||||||
'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_PUBLIC_NODE', 'SIGN_TRANSACTION', 'ADMIN_ACTION', 'OPEN_NEW_TAB', 'CREATE_AND_COPY_EMBED_LINK', 'DECRYPT_QORTAL_GROUP_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA', 'SHOW_ACTIONS', 'REGISTER_NAME', 'UPDATE_NAME', 'LEAVE_GROUP', 'INVITE_TO_GROUP', 'KICK_FROM_GROUP', 'BAN_FROM_GROUP', 'CANCEL_GROUP_BAN', 'ADD_GROUP_ADMIN', 'REMOVE_GROUP_ADMIN','DECRYPT_AESGCM', 'CANCEL_GROUP_INVITE', 'CREATE_GROUP', 'GET_USER_WALLET_TRANSACTIONS', 'GET_NODE_INFO',
|
'CREATE_TRADE_SELL_ORDER', 'CANCEL_TRADE_SELL_ORDER', 'IS_USING_PUBLIC_NODE', 'SIGN_TRANSACTION', 'ADMIN_ACTION', 'OPEN_NEW_TAB', 'CREATE_AND_COPY_EMBED_LINK', 'DECRYPT_QORTAL_GROUP_DATA', 'DECRYPT_DATA_WITH_SHARING_KEY', 'DELETE_HOSTED_DATA', 'GET_HOSTED_DATA', 'SHOW_ACTIONS', 'REGISTER_NAME', 'UPDATE_NAME', 'LEAVE_GROUP', 'INVITE_TO_GROUP', 'KICK_FROM_GROUP', 'BAN_FROM_GROUP', 'CANCEL_GROUP_BAN', 'ADD_GROUP_ADMIN', 'REMOVE_GROUP_ADMIN','DECRYPT_AESGCM', 'CANCEL_GROUP_INVITE', 'CREATE_GROUP', 'GET_USER_WALLET_TRANSACTIONS', 'GET_NODE_INFO',
|
||||||
'GET_NODE_STATUS', 'GET_ARRR_SYNC_STATUS', 'SHOW_PDF_READER', 'UPDATE_GROUP', 'SELL_NAME',
|
'GET_NODE_STATUS', 'GET_ARRR_SYNC_STATUS', 'SHOW_PDF_READER'
|
||||||
'CANCEL_SELL_NAME',
|
|
||||||
'BUY_NAME', 'MULTI_ASSET_PAYMENT_WITH_PRIVATE_DATA',
|
|
||||||
'TRANSFER_ASSET',
|
|
||||||
'SIGN_FOREIGN_FEES',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
@ -561,7 +551,7 @@ isDOMContentLoaded: false
|
|||||||
result: null,
|
result: null,
|
||||||
error: {
|
error: {
|
||||||
error: response.error,
|
error: response.error,
|
||||||
message: typeof response?.error === 'string' ? response?.error : typeof response?.message === 'string' ? response?.message : 'An error has occurred'
|
message: typeof response?.error === 'string' ? response.error : 'An error has occurred'
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,248 +0,0 @@
|
|||||||
import {
|
|
||||||
Box,
|
|
||||||
Checkbox,
|
|
||||||
FormControlLabel,
|
|
||||||
Typography,
|
|
||||||
useTheme,
|
|
||||||
} from '@mui/material';
|
|
||||||
import { Spacer } from '../../common/Spacer';
|
|
||||||
import { PasswordField } from '../PasswordField/PasswordField';
|
|
||||||
import { ErrorText } from '../ErrorText/ErrorText';
|
|
||||||
import Logo1Dark from '../../assets/svgs/Logo1Dark.svg';
|
|
||||||
import { saveFileToDisk } from '../../utils/generateWallet/generateWallet';
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { decryptStoredWallet } from '../../utils/decryptWallet';
|
|
||||||
import PhraseWallet from '../../utils/generateWallet/phrase-wallet';
|
|
||||||
import { crypto, walletVersion } from '../../constants/decryptWallet';
|
|
||||||
import Return from "../../assets/svgs/Return.svg";
|
|
||||||
import { CustomButton, CustomLabel, TextP } from '../../App-styles';
|
|
||||||
|
|
||||||
export const DownloadWallet = ({
|
|
||||||
returnToMain,
|
|
||||||
setIsLoading,
|
|
||||||
showInfo,
|
|
||||||
rawWallet,
|
|
||||||
setWalletToBeDownloaded,
|
|
||||||
walletToBeDownloaded,
|
|
||||||
}) => {
|
|
||||||
const [walletToBeDownloadedPassword, setWalletToBeDownloadedPassword] =
|
|
||||||
useState<string>('');
|
|
||||||
const [newPassword, setNewPassword] = useState<string>('');
|
|
||||||
const [keepCurrentPassword, setKeepCurrentPassword] = useState<boolean>(true);
|
|
||||||
const theme = useTheme();
|
|
||||||
const [walletToBeDownloadedError, setWalletToBeDownloadedError] =
|
|
||||||
useState<string>('');
|
|
||||||
|
|
||||||
|
|
||||||
const saveFileToDiskFunc = async () => {
|
|
||||||
try {
|
|
||||||
await saveFileToDisk(
|
|
||||||
walletToBeDownloaded.wallet,
|
|
||||||
walletToBeDownloaded.qortAddress
|
|
||||||
);
|
|
||||||
} catch (error: any) {
|
|
||||||
setWalletToBeDownloadedError(error?.message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const saveWalletFunc = async (password: string, newPassword) => {
|
|
||||||
let wallet = structuredClone(rawWallet);
|
|
||||||
|
|
||||||
const res = await decryptStoredWallet(password, wallet);
|
|
||||||
const wallet2 = new PhraseWallet(res, wallet?.version || walletVersion);
|
|
||||||
const passwordToUse = newPassword || password;
|
|
||||||
wallet = await wallet2.generateSaveWalletData(
|
|
||||||
passwordToUse,
|
|
||||||
crypto.kdfThreads,
|
|
||||||
() => {}
|
|
||||||
);
|
|
||||||
|
|
||||||
setWalletToBeDownloaded({
|
|
||||||
wallet,
|
|
||||||
qortAddress: rawWallet.address0,
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
wallet,
|
|
||||||
qortAddress: rawWallet.address0,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const confirmPasswordToDownload = async () => {
|
|
||||||
try {
|
|
||||||
setWalletToBeDownloadedError('');
|
|
||||||
if (!keepCurrentPassword && !newPassword) {
|
|
||||||
setWalletToBeDownloadedError(
|
|
||||||
'Please enter a new password'
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!walletToBeDownloadedPassword) {
|
|
||||||
setWalletToBeDownloadedError(
|
|
||||||
'Please enter your password'
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setIsLoading(true);
|
|
||||||
await new Promise<void>((res) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
res();
|
|
||||||
}, 250);
|
|
||||||
});
|
|
||||||
const newPasswordForWallet = !keepCurrentPassword ? newPassword : null;
|
|
||||||
const res = await saveWalletFunc(
|
|
||||||
walletToBeDownloadedPassword,
|
|
||||||
newPasswordForWallet
|
|
||||||
);
|
|
||||||
} catch (error: any) {
|
|
||||||
setWalletToBeDownloadedError(error?.message);
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Spacer height="22px" />
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
boxSizing: 'border-box',
|
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'flex-start',
|
|
||||||
maxWidth: '700px',
|
|
||||||
paddingLeft: '22px',
|
|
||||||
width: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
style={{
|
|
||||||
cursor: "pointer",
|
|
||||||
height: '24px'
|
|
||||||
}}
|
|
||||||
onClick={returnToMain}
|
|
||||||
src={Return}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Spacer height="10px" />
|
|
||||||
|
|
||||||
<div
|
|
||||||
className="image-container"
|
|
||||||
style={{
|
|
||||||
width: '136px',
|
|
||||||
height: '154px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img src={Logo1Dark} className="base-image" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Spacer height="35px" />
|
|
||||||
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: 'flex',
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'flex-start',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TextP
|
|
||||||
sx={{
|
|
||||||
textAlign: 'start',
|
|
||||||
lineHeight: '24px',
|
|
||||||
fontSize: '20px',
|
|
||||||
fontWeight: 600,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Download account
|
|
||||||
</TextP>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Spacer height="35px" />
|
|
||||||
|
|
||||||
{!walletToBeDownloaded && (
|
|
||||||
<>
|
|
||||||
<CustomLabel htmlFor="standard-adornment-password">
|
|
||||||
Confirm password
|
|
||||||
</CustomLabel>
|
|
||||||
|
|
||||||
<Spacer height="5px" />
|
|
||||||
|
|
||||||
<PasswordField
|
|
||||||
id="standard-adornment-password"
|
|
||||||
value={walletToBeDownloadedPassword}
|
|
||||||
onChange={(e) => setWalletToBeDownloadedPassword(e.target.value)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Spacer height="20px" />
|
|
||||||
|
|
||||||
<FormControlLabel
|
|
||||||
sx={{
|
|
||||||
margin: 0,
|
|
||||||
}}
|
|
||||||
control={
|
|
||||||
<Checkbox
|
|
||||||
onChange={(e) => setKeepCurrentPassword(e.target.checked)}
|
|
||||||
checked={keepCurrentPassword}
|
|
||||||
edge="start"
|
|
||||||
tabIndex={-1}
|
|
||||||
disableRipple
|
|
||||||
sx={{
|
|
||||||
'&.Mui-checked': {
|
|
||||||
color: theme.palette.text.secondary,
|
|
||||||
},
|
|
||||||
'& .MuiSvgIcon-root': {
|
|
||||||
color: theme.palette.text.secondary,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label={
|
|
||||||
<Box sx={{ display: 'flex', alignItems: 'center' }}>
|
|
||||||
<Typography sx={{ fontSize: '14px' }}>
|
|
||||||
Keep current password
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Spacer height="20px" />
|
|
||||||
{!keepCurrentPassword && (
|
|
||||||
<>
|
|
||||||
<CustomLabel htmlFor="standard-adornment-password">
|
|
||||||
New password
|
|
||||||
</CustomLabel>
|
|
||||||
|
|
||||||
<Spacer height="5px" />
|
|
||||||
<PasswordField
|
|
||||||
id="standard-adornment-password"
|
|
||||||
value={newPassword}
|
|
||||||
onChange={(e) => setNewPassword(e.target.value)}
|
|
||||||
/>
|
|
||||||
<Spacer height="20px" />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<CustomButton onClick={confirmPasswordToDownload}>
|
|
||||||
Confirm wallet password
|
|
||||||
</CustomButton>
|
|
||||||
|
|
||||||
<ErrorText>{walletToBeDownloadedError}</ErrorText>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{walletToBeDownloaded && (
|
|
||||||
<>
|
|
||||||
<CustomButton
|
|
||||||
onClick={async () => {
|
|
||||||
await saveFileToDiskFunc();
|
|
||||||
await showInfo({
|
|
||||||
message: 'Keep your account file secure',
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Download account
|
|
||||||
</CustomButton>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
@ -79,7 +79,7 @@ export const AdminSpaceInner = ({
|
|||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${getBaseApiReact()}/arbitrary/DOCUMENT_PRIVATE/${
|
`${getBaseApiReact()}/arbitrary/DOCUMENT_PRIVATE/${
|
||||||
getLatestPublish.name
|
getLatestPublish.name
|
||||||
}/${getLatestPublish.identifier}?encoding=base64&rebuild=true`
|
}/${getLatestPublish.identifier}?encoding=base64`
|
||||||
);
|
);
|
||||||
data = await res.text();
|
data = await res.text();
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ export const CreateCommonSecret = ({groupId, secretKey, isOwner, myAddress, sec
|
|||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${getBaseApiReact()}/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${
|
`${getBaseApiReact()}/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${
|
||||||
publish.identifier
|
publish.identifier
|
||||||
}?encoding=base64&rebuild=true`
|
}?encoding=base64`
|
||||||
);
|
);
|
||||||
const data = await res.text();
|
const data = await res.text();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useCallback, useEffect, useRef } from "react";
|
import React, { useCallback, useEffect, useRef } from "react";
|
||||||
|
import { getBaseApiReact } from "../../App";
|
||||||
|
import { truncate } from "lodash";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ export const useBlockedAddresses = () => {
|
|||||||
const isUserBlocked = useCallback((address, name)=> {
|
const isUserBlocked = useCallback((address, name)=> {
|
||||||
try {
|
try {
|
||||||
if(!address) return false
|
if(!address) return false
|
||||||
if(userBlockedRef.current[address]) return true
|
if(userBlockedRef.current[address] || userNamesBlockedRef.current[name]) return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
@ -89,13 +90,12 @@ export const useBlockedAddresses = () => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const removeBlockFromList = useCallback(async (address, name)=> {
|
const removeBlockFromList = useCallback(async (address, name)=> {
|
||||||
if(name){
|
|
||||||
await new Promise((res, rej) => {
|
await new Promise((res, rej) => {
|
||||||
window.sendMessage("listActions", {
|
window.sendMessage("listActions", {
|
||||||
|
|
||||||
type: 'remove',
|
type: 'remove',
|
||||||
items: [name] ,
|
items: name ? [name] : [address],
|
||||||
listName: 'blockedNames'
|
listName: name ? 'blockedNames' : 'blockedAddresses'
|
||||||
|
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
@ -103,40 +103,15 @@ export const useBlockedAddresses = () => {
|
|||||||
rej(response?.message);
|
rej(response?.message);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
if(!name){
|
||||||
const copyObject = {...userNamesBlockedRef.current}
|
|
||||||
delete copyObject[name]
|
|
||||||
userNamesBlockedRef.current = copyObject
|
|
||||||
|
|
||||||
|
|
||||||
res(response);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("Failed qortalRequest", error);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if(address){
|
|
||||||
await new Promise((res, rej) => {
|
|
||||||
window.sendMessage("listActions", {
|
|
||||||
|
|
||||||
type: 'remove',
|
|
||||||
items: [address],
|
|
||||||
listName: 'blockedAddresses'
|
|
||||||
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.error) {
|
|
||||||
rej(response?.message);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
|
|
||||||
const copyObject = {...userBlockedRef.current}
|
const copyObject = {...userBlockedRef.current}
|
||||||
delete copyObject[address]
|
delete copyObject[address]
|
||||||
userBlockedRef.current = copyObject
|
userBlockedRef.current = copyObject
|
||||||
|
} else {
|
||||||
|
const copyObject = {...userNamesBlockedRef.current}
|
||||||
|
delete copyObject[name]
|
||||||
|
userNamesBlockedRef.current = copyObject
|
||||||
|
}
|
||||||
|
|
||||||
res(response);
|
res(response);
|
||||||
}
|
}
|
||||||
@ -145,19 +120,41 @@ export const useBlockedAddresses = () => {
|
|||||||
console.error("Failed qortalRequest", error);
|
console.error("Failed qortalRequest", error);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
if(name && userBlockedRef.current[address]){
|
||||||
|
await new Promise((res, rej) => {
|
||||||
|
window.sendMessage("listActions", {
|
||||||
|
|
||||||
|
type: 'remove',
|
||||||
|
items: !name ? [name] : [address],
|
||||||
|
listName: !name ? 'blockedNames' : 'blockedAddresses'
|
||||||
|
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.error) {
|
||||||
|
rej(response?.message);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
const copyObject = {...userBlockedRef.current}
|
||||||
|
delete copyObject[address]
|
||||||
|
userBlockedRef.current = copyObject
|
||||||
|
res(response);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Failed qortalRequest", error);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const addToBlockList = useCallback(async (address, name)=> {
|
const addToBlockList = useCallback(async (address, name)=> {
|
||||||
if(name){
|
|
||||||
await new Promise((res, rej) => {
|
await new Promise((res, rej) => {
|
||||||
window.sendMessage("listActions", {
|
window.sendMessage("listActions", {
|
||||||
|
|
||||||
type: 'add',
|
type: 'add',
|
||||||
items: [name],
|
items: name ? [name] : [address],
|
||||||
listName: 'blockedNames'
|
listName: name ? 'blockedNames' : 'blockedAddresses'
|
||||||
|
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
@ -165,38 +162,18 @@ export const useBlockedAddresses = () => {
|
|||||||
rej(response?.message);
|
rej(response?.message);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
if(name){
|
||||||
|
|
||||||
const copyObject = {...userNamesBlockedRef.current}
|
const copyObject = {...userNamesBlockedRef.current}
|
||||||
copyObject[name] = true
|
copyObject[name] = true
|
||||||
userNamesBlockedRef.current = copyObject
|
userNamesBlockedRef.current = copyObject
|
||||||
|
|
||||||
|
|
||||||
res(response);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("Failed qortalRequest", error);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(address){
|
|
||||||
await new Promise((res, rej) => {
|
|
||||||
window.sendMessage("listActions", {
|
|
||||||
|
|
||||||
type: 'add',
|
|
||||||
items: [address],
|
|
||||||
listName: 'blockedAddresses'
|
|
||||||
|
|
||||||
})
|
|
||||||
.then((response) => {
|
|
||||||
if (response.error) {
|
|
||||||
rej(response?.message);
|
|
||||||
return;
|
|
||||||
}else {
|
}else {
|
||||||
|
|
||||||
const copyObject = {...userBlockedRef.current}
|
const copyObject = {...userBlockedRef.current}
|
||||||
copyObject[address] = true
|
copyObject[address] = true
|
||||||
userBlockedRef.current = copyObject
|
userBlockedRef.current = copyObject
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
res(response);
|
res(response);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -204,8 +181,6 @@ export const useBlockedAddresses = () => {
|
|||||||
console.error("Failed qortalRequest", error);
|
console.error("Failed qortalRequest", error);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -10,23 +10,15 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import React, { useContext, useEffect, useState } from "react";
|
import React, { useContext, useEffect, useState } from "react";
|
||||||
import { getBaseApiReact, MyContext } from "../../App";
|
import { MyContext } from "../../App";
|
||||||
import { Spacer } from "../../common/Spacer";
|
import { Spacer } from "../../common/Spacer";
|
||||||
import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events";
|
import { executeEvent } from "../../utils/events";
|
||||||
import { validateAddress } from "../../utils/validateAddress";
|
|
||||||
import { getNameInfo, requestQueueMemberNames } from "./Group";
|
export const BlockedUsersModal = ({ close }) => {
|
||||||
import { useModal } from "../../common/useModal";
|
|
||||||
import { useRecoilState } from "recoil";
|
|
||||||
import { isOpenBlockedModalAtom } from "../../atoms/global";
|
|
||||||
import InfoIcon from '@mui/icons-material/Info';
|
|
||||||
export const BlockedUsersModal = () => {
|
|
||||||
const [isOpenBlockedModal, setIsOpenBlockedModal] = useRecoilState(isOpenBlockedModalAtom)
|
|
||||||
const [hasChanged, setHasChanged] = useState(false);
|
const [hasChanged, setHasChanged] = useState(false);
|
||||||
const [value, setValue] = useState("");
|
const [value, setValue] = useState("");
|
||||||
const [addressesWithNames, setAddressesWithNames] = useState({})
|
|
||||||
const { isShow, onCancel, onOk, show, message } = useModal();
|
const { getAllBlockedUsers, removeBlockFromList, addToBlockList } = useContext(MyContext);
|
||||||
const { getAllBlockedUsers, removeBlockFromList, addToBlockList, setOpenSnackGlobal, setInfoSnackCustom } =
|
|
||||||
useContext(MyContext);
|
|
||||||
const [blockedUsers, setBlockedUsers] = useState({
|
const [blockedUsers, setBlockedUsers] = useState({
|
||||||
addresses: {},
|
addresses: {},
|
||||||
names: {},
|
names: {},
|
||||||
@ -36,119 +28,20 @@ export const BlockedUsersModal = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(!isOpenBlockedModal) return
|
|
||||||
fetchBlockedUsers();
|
fetchBlockedUsers();
|
||||||
}, [isOpenBlockedModal]);
|
|
||||||
|
|
||||||
const getNames = async () => {
|
|
||||||
// const validApi = await findUsableApi();
|
|
||||||
const addresses = Object.keys(blockedUsers?.addresses)
|
|
||||||
const addressNames = {}
|
|
||||||
|
|
||||||
|
|
||||||
const getMemNames = addresses.map(async (address) => {
|
|
||||||
const name = await requestQueueMemberNames.enqueue(() => {
|
|
||||||
return getNameInfo(address);
|
|
||||||
});
|
|
||||||
if (name) {
|
|
||||||
addressNames[address] = name
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
await Promise.all(getMemNames);
|
|
||||||
|
|
||||||
setAddressesWithNames(addressNames)
|
|
||||||
};
|
|
||||||
|
|
||||||
const blockUser = async (e, user?: string) => {
|
|
||||||
try {
|
|
||||||
const valUser = user || value
|
|
||||||
if (!valUser) return;
|
|
||||||
const isAddress = validateAddress(valUser);
|
|
||||||
let userName = null;
|
|
||||||
let userAddress = null;
|
|
||||||
if (isAddress) {
|
|
||||||
userAddress = valUser;
|
|
||||||
const name = await getNameInfo(valUser);
|
|
||||||
if (name) {
|
|
||||||
userName = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isAddress) {
|
|
||||||
const response = await fetch(`${getBaseApiReact()}/names/${valUser}`);
|
|
||||||
const data = await response.json();
|
|
||||||
if (!data?.owner) throw new Error("Name does not exist");
|
|
||||||
if (data?.owner) {
|
|
||||||
userAddress = data.owner;
|
|
||||||
userName = valUser;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!userName){
|
|
||||||
await addToBlockList(userAddress, null);
|
|
||||||
fetchBlockedUsers();
|
|
||||||
setHasChanged(true);
|
|
||||||
executeEvent('updateChatMessagesWithBlocks', true)
|
|
||||||
setValue('')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const responseModal = await show({
|
|
||||||
userName,
|
|
||||||
userAddress,
|
|
||||||
});
|
|
||||||
if (responseModal === "both") {
|
|
||||||
await addToBlockList(userAddress, userName);
|
|
||||||
} else if (responseModal === "address") {
|
|
||||||
await addToBlockList(userAddress, null);
|
|
||||||
} else if (responseModal === "name") {
|
|
||||||
await addToBlockList(null, userName);
|
|
||||||
}
|
|
||||||
fetchBlockedUsers();
|
|
||||||
setHasChanged(true);
|
|
||||||
setValue('')
|
|
||||||
if(user){
|
|
||||||
setIsOpenBlockedModal(false)
|
|
||||||
}
|
|
||||||
if(responseModal === 'both' || responseModal === 'address'){
|
|
||||||
executeEvent('updateChatMessagesWithBlocks', true)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
setOpenSnackGlobal(true);
|
|
||||||
|
|
||||||
setInfoSnackCustom({
|
|
||||||
type: "error",
|
|
||||||
message: error?.message || "Unable to block user",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const blockUserFromOutsideModalFunc = (e) => {
|
|
||||||
const user = e.detail?.user;
|
|
||||||
setIsOpenBlockedModal(true)
|
|
||||||
blockUser(null, user)
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
subscribeToEvent("blockUserFromOutside", blockUserFromOutsideModalFunc);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
unsubscribeFromEvent("blockUserFromOutside", blockUserFromOutsideModalFunc);
|
|
||||||
};
|
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={isOpenBlockedModal}
|
open={true}
|
||||||
aria-labelledby="alert-dialog-title"
|
aria-labelledby="alert-dialog-title"
|
||||||
aria-describedby="alert-dialog-description"
|
aria-describedby="alert-dialog-description"
|
||||||
>
|
>
|
||||||
<DialogTitle>Blocked Users</DialogTitle>
|
<DialogTitle>Blocked Users</DialogTitle>
|
||||||
<DialogContent
|
<DialogContent sx={{
|
||||||
sx={{
|
padding: '20px'
|
||||||
padding: "20px",
|
}}>
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
<Box
|
||||||
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
@ -156,42 +49,39 @@ export const BlockedUsersModal = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TextField
|
<TextField
|
||||||
placeholder="Name or address"
|
placeholder="Name"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setValue(e.target.value);
|
setValue(e.target.value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button variant="contained" onClick={async ()=> {
|
||||||
sx={{
|
try {
|
||||||
flexShrink: 0,
|
if(!value) return
|
||||||
}}
|
await addToBlockList(undefined, value)
|
||||||
variant="contained"
|
fetchBlockedUsers()
|
||||||
onClick={blockUser}
|
setHasChanged(true)
|
||||||
>
|
} catch (error) {
|
||||||
Block
|
console.error(error)
|
||||||
</Button>
|
}
|
||||||
|
}}>Block</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{Object.entries(blockedUsers?.addresses).length > 0 && (
|
{Object.entries(blockedUsers?.addresses).length > 0 && (
|
||||||
<>
|
<>
|
||||||
<Spacer height="20px" />
|
<Spacer height="20px" />
|
||||||
<DialogContentText id="alert-dialog-description">
|
<DialogContentText id="alert-dialog-description">
|
||||||
Blocked addresses- blocks processing of txs
|
Blocked Users for Chat ( addresses )
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
<Spacer height="10px" />
|
<Spacer height="10px" />
|
||||||
<Button variant="contained" size="small" onClick={getNames}>Fetch names</Button>
|
|
||||||
<Spacer height="10px" />
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box
|
<Box sx={{
|
||||||
sx={{
|
display: 'flex',
|
||||||
display: "flex",
|
flexDirection: 'column',
|
||||||
flexDirection: "column",
|
gap: '10px'
|
||||||
gap: "10px",
|
}}>
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Object.entries(blockedUsers?.addresses || {})?.map(
|
{Object.entries(blockedUsers?.addresses || {})?.map(
|
||||||
([key, value]) => {
|
([key, value]) => {
|
||||||
return (
|
return (
|
||||||
@ -200,22 +90,18 @@ export const BlockedUsersModal = () => {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: "10px",
|
gap: "10px",
|
||||||
width: "100%",
|
width: '100%',
|
||||||
justifyContent: "space-between",
|
justifyContent: 'space-between'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography>{addressesWithNames[key] || key}</Typography>
|
<Typography>{key}</Typography>
|
||||||
<Button
|
<Button
|
||||||
sx={{
|
|
||||||
flexShrink: 0,
|
|
||||||
}}
|
|
||||||
size="small"
|
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
await removeBlockFromList(key, undefined);
|
await removeBlockFromList(key, undefined);
|
||||||
setHasChanged(true);
|
setHasChanged(true);
|
||||||
setValue("");
|
setValue('')
|
||||||
fetchBlockedUsers();
|
fetchBlockedUsers();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -233,19 +119,17 @@ export const BlockedUsersModal = () => {
|
|||||||
<>
|
<>
|
||||||
<Spacer height="20px" />
|
<Spacer height="20px" />
|
||||||
<DialogContentText id="alert-dialog-description">
|
<DialogContentText id="alert-dialog-description">
|
||||||
Blocked names for QDN
|
Blocked Users for QDN and Chat (names)
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
<Spacer height="10px" />
|
<Spacer height="10px" />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Box
|
<Box sx={{
|
||||||
sx={{
|
display: 'flex',
|
||||||
display: "flex",
|
flexDirection: 'column',
|
||||||
flexDirection: "column",
|
gap: '10px'
|
||||||
gap: "10px",
|
}}>
|
||||||
}}
|
|
||||||
>
|
|
||||||
{Object.entries(blockedUsers?.names || {})?.map(([key, value]) => {
|
{Object.entries(blockedUsers?.names || {})?.map(([key, value]) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@ -253,16 +137,12 @@ export const BlockedUsersModal = () => {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
gap: "10px",
|
gap: "10px",
|
||||||
width: "100%",
|
width: '100%',
|
||||||
justifyContent: "space-between",
|
justifyContent: 'space-between'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography>{key}</Typography>
|
<Typography>{key}</Typography>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
|
||||||
sx={{
|
|
||||||
flexShrink: 0,
|
|
||||||
}}
|
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
@ -297,65 +177,14 @@ export const BlockedUsersModal = () => {
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={()=> {
|
onClick={()=> {
|
||||||
if(hasChanged){
|
if(hasChanged){
|
||||||
executeEvent("updateChatMessagesWithBlocks", true);
|
executeEvent('updateChatMessagesWithBlocks', true)
|
||||||
}
|
}
|
||||||
setIsOpenBlockedModal(false);
|
close()
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
close
|
close
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
|
|
||||||
<Dialog
|
|
||||||
open={isShow}
|
|
||||||
aria-labelledby="alert-dialog-title"
|
|
||||||
aria-describedby="alert-dialog-description"
|
|
||||||
>
|
|
||||||
<DialogTitle id="alert-dialog-title">
|
|
||||||
{"Decide what to block"}
|
|
||||||
</DialogTitle>
|
|
||||||
<DialogContent>
|
|
||||||
<DialogContentText id="alert-dialog-description">
|
|
||||||
Blocking {message?.userName || message?.userAddress}
|
|
||||||
</DialogContentText>
|
|
||||||
<Box sx={{
|
|
||||||
display: 'flex',
|
|
||||||
alignItems: 'center',
|
|
||||||
gap: '10px',
|
|
||||||
marginTop: '20px'
|
|
||||||
}}>
|
|
||||||
<InfoIcon sx={{
|
|
||||||
color: 'fff'
|
|
||||||
}}/> <Typography>Choose "block txs" or "all" to block chat messages </Typography>
|
|
||||||
</Box>
|
|
||||||
</DialogContent>
|
|
||||||
<DialogActions>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
onClick={() => {
|
|
||||||
onOk("address");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Block txs
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
onClick={() => {
|
|
||||||
onOk("name");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Block QDN data
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
onClick={() => {
|
|
||||||
onOk("both");
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Block All
|
|
||||||
</Button>
|
|
||||||
</DialogActions>
|
|
||||||
</Dialog>
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -19,8 +19,7 @@ import React, {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import PersonOffIcon from '@mui/icons-material/PersonOff';
|
import BlockIcon from '@mui/icons-material/Block';
|
||||||
|
|
||||||
import { WalletsAppWrapper } from "./WalletsAppWrapper";
|
import { WalletsAppWrapper } from "./WalletsAppWrapper";
|
||||||
|
|
||||||
import SettingsIcon from "@mui/icons-material/Settings";
|
import SettingsIcon from "@mui/icons-material/Settings";
|
||||||
@ -100,7 +99,7 @@ import { formatEmailDate } from "./QMailMessages";
|
|||||||
import { useHandleMobileNativeBack } from "../../hooks/useHandleMobileNativeBack";
|
import { useHandleMobileNativeBack } from "../../hooks/useHandleMobileNativeBack";
|
||||||
import { AdminSpace } from "../Chat/AdminSpace";
|
import { AdminSpace } from "../Chat/AdminSpace";
|
||||||
import { useRecoilState, useSetRecoilState } from "recoil";
|
import { useRecoilState, useSetRecoilState } from "recoil";
|
||||||
import { addressInfoControllerAtom, groupsPropertiesAtom, isOpenBlockedModalAtom, lastEnteredGroupIdAtom, selectedGroupIdAtom } from "../../atoms/global";
|
import { addressInfoControllerAtom, groupsPropertiesAtom, lastEnteredGroupIdAtom, selectedGroupIdAtom } from "../../atoms/global";
|
||||||
import { sortArrayByTimestampAndGroupName } from "../../utils/time";
|
import { sortArrayByTimestampAndGroupName } from "../../utils/time";
|
||||||
import { BlockedUsersModal } from "./BlockedUsersModal";
|
import { BlockedUsersModal } from "./BlockedUsersModal";
|
||||||
import { GlobalTouchMenu } from "../GlobalTouchMenu";
|
import { GlobalTouchMenu } from "../GlobalTouchMenu";
|
||||||
@ -484,8 +483,6 @@ export const Group = ({
|
|||||||
const [groupAnnouncements, setGroupAnnouncements] = React.useState({});
|
const [groupAnnouncements, setGroupAnnouncements] = React.useState({});
|
||||||
const [defaultThread, setDefaultThread] = React.useState(null);
|
const [defaultThread, setDefaultThread] = React.useState(null);
|
||||||
const [isOpenDrawer, setIsOpenDrawer] = React.useState(false);
|
const [isOpenDrawer, setIsOpenDrawer] = React.useState(false);
|
||||||
const setIsOpenBlockedUserModal = useSetRecoilState(isOpenBlockedModalAtom)
|
|
||||||
|
|
||||||
const [hideCommonKeyPopup, setHideCommonKeyPopup] = React.useState(false);
|
const [hideCommonKeyPopup, setHideCommonKeyPopup] = React.useState(false);
|
||||||
const [isLoadingGroupMessage, setIsLoadingGroupMessage] = React.useState("");
|
const [isLoadingGroupMessage, setIsLoadingGroupMessage] = React.useState("");
|
||||||
const [drawerMode, setDrawerMode] = React.useState("groups");
|
const [drawerMode, setDrawerMode] = React.useState("groups");
|
||||||
@ -510,6 +507,7 @@ export const Group = ({
|
|||||||
const [isForceShowCreationKeyPopup, setIsForceShowCreationKeyPopup] = useState(false)
|
const [isForceShowCreationKeyPopup, setIsForceShowCreationKeyPopup] = useState(false)
|
||||||
const [groupsProperties, setGroupsProperties] = useRecoilState(groupsPropertiesAtom)
|
const [groupsProperties, setGroupsProperties] = useRecoilState(groupsPropertiesAtom)
|
||||||
const setUserInfoForLevels = useSetRecoilState(addressInfoControllerAtom);
|
const setUserInfoForLevels = useSetRecoilState(addressInfoControllerAtom);
|
||||||
|
const [isOpenBlockedUserModal, setIsOpenBlockedUserModal] = React.useState(false);
|
||||||
const setLastEnteredGroupIdAtom = useSetRecoilState(lastEnteredGroupIdAtom)
|
const setLastEnteredGroupIdAtom = useSetRecoilState(lastEnteredGroupIdAtom)
|
||||||
const isPrivate = useMemo(()=> {
|
const isPrivate = useMemo(()=> {
|
||||||
if(selectedGroup?.groupId === '0') return false
|
if(selectedGroup?.groupId === '0') return false
|
||||||
@ -841,7 +839,7 @@ export const Group = ({
|
|||||||
const res = await fetch(
|
const res = await fetch(
|
||||||
`${getBaseApiReact()}/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${
|
`${getBaseApiReact()}/arbitrary/DOCUMENT_PRIVATE/${publish.name}/${
|
||||||
publish.identifier
|
publish.identifier
|
||||||
}?encoding=base64&rebuild=true`
|
}?encoding=base64`
|
||||||
);
|
);
|
||||||
data = await res.text();
|
data = await res.text();
|
||||||
}
|
}
|
||||||
@ -2161,7 +2159,7 @@ export const Group = ({
|
|||||||
padding: '10px'
|
padding: '10px'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PersonOffIcon
|
<BlockIcon
|
||||||
sx={{
|
sx={{
|
||||||
color: "white",
|
color: "white",
|
||||||
}}
|
}}
|
||||||
@ -2658,9 +2656,11 @@ export const Group = ({
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
{isOpenBlockedUserModal && (
|
||||||
<BlockedUsersModal />
|
<BlockedUsersModal close={()=> {
|
||||||
|
setIsOpenBlockedUserModal(false)
|
||||||
|
}} />
|
||||||
|
)}
|
||||||
{selectedDirect && !newChat && (
|
{selectedDirect && !newChat && (
|
||||||
<>
|
<>
|
||||||
<Box
|
<Box
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import { DrawerUserLookup } from "../Drawer/DrawerUserLookup";
|
import { DrawerUserLookup } from "../Drawer/DrawerUserLookup";
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
@ -16,7 +16,6 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
Table,
|
Table,
|
||||||
CircularProgress,
|
CircularProgress,
|
||||||
Autocomplete,
|
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { getAddressInfo, getNameOrAddress } from "../../background";
|
import { getAddressInfo, getNameOrAddress } from "../../background";
|
||||||
import { getBaseApiReact } from "../../App";
|
import { getBaseApiReact } from "../../App";
|
||||||
@ -27,7 +26,6 @@ import { formatTimestamp } from "../../utils/time";
|
|||||||
import CloseFullscreenIcon from '@mui/icons-material/CloseFullscreen';
|
import CloseFullscreenIcon from '@mui/icons-material/CloseFullscreen';
|
||||||
import SearchIcon from '@mui/icons-material/Search';
|
import SearchIcon from '@mui/icons-material/Search';
|
||||||
import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events";
|
import { executeEvent, subscribeToEvent, unsubscribeFromEvent } from "../../utils/events";
|
||||||
import { useNameSearch } from "../../hooks/useNameSearch";
|
|
||||||
|
|
||||||
function formatAddress(str) {
|
function formatAddress(str) {
|
||||||
if (str.length <= 12) return str;
|
if (str.length <= 12) return str;
|
||||||
@ -40,9 +38,6 @@ function formatAddress(str) {
|
|||||||
|
|
||||||
export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
|
export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
|
||||||
const [nameOrAddress, setNameOrAddress] = useState("");
|
const [nameOrAddress, setNameOrAddress] = useState("");
|
||||||
const [inputValue, setInputValue] = useState('');
|
|
||||||
const { results, isLoading } = useNameSearch(inputValue);
|
|
||||||
const options = useMemo(() => results?.map((item) => item.name), [results]);
|
|
||||||
const [errorMessage, setErrorMessage] = useState("");
|
const [errorMessage, setErrorMessage] = useState("");
|
||||||
const [addressInfo, setAddressInfo] = useState(null);
|
const [addressInfo, setAddressInfo] = useState(null);
|
||||||
const [isLoadingUser, setIsLoadingUser] = useState(false);
|
const [isLoadingUser, setIsLoadingUser] = useState(false);
|
||||||
@ -111,7 +106,6 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
|
|||||||
setIsOpenDrawerLookup(false)
|
setIsOpenDrawerLookup(false)
|
||||||
setNameOrAddress('')
|
setNameOrAddress('')
|
||||||
setErrorMessage('')
|
setErrorMessage('')
|
||||||
setInputValue('');
|
|
||||||
setPayments([])
|
setPayments([])
|
||||||
setIsLoadingUser(false)
|
setIsLoadingUser(false)
|
||||||
setIsLoadingPayments(false)
|
setIsLoadingPayments(false)
|
||||||
@ -140,66 +134,27 @@ export const UserLookup = ({ isOpenDrawerLookup, setIsOpenDrawerLookup }) => {
|
|||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Autocomplete
|
|
||||||
value={nameOrAddress}
|
|
||||||
onChange={(event: any, newValue: string | null) => {
|
|
||||||
if (!newValue) {
|
|
||||||
setNameOrAddress('');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setNameOrAddress(newValue);
|
|
||||||
lookupFunc(newValue);
|
|
||||||
}}
|
|
||||||
inputValue={inputValue}
|
|
||||||
onInputChange={(event, newInputValue) => {
|
|
||||||
setInputValue(newInputValue);
|
|
||||||
}}
|
|
||||||
id="controllable-states-demo"
|
|
||||||
loading={isLoading}
|
|
||||||
options={options}
|
|
||||||
sx={{ width: 300 }}
|
|
||||||
size="small"
|
|
||||||
renderInput={(params) => (
|
|
||||||
<TextField
|
<TextField
|
||||||
autoFocus
|
autoFocus
|
||||||
|
value={nameOrAddress}
|
||||||
|
onChange={(e) => setNameOrAddress(e.target.value)}
|
||||||
|
size="small"
|
||||||
|
placeholder="Address or Name"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
{...params}
|
|
||||||
label="Address or Name"
|
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === 'Enter' && nameOrAddress) {
|
if (e.key === "Enter" && nameOrAddress) {
|
||||||
lookupFunc(inputValue);
|
lookupFunc();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
sx={{
|
|
||||||
'& .MuiOutlinedInput-root': {
|
|
||||||
'& fieldset': {
|
|
||||||
borderColor: 'white',
|
|
||||||
},
|
|
||||||
'&:hover fieldset': {
|
|
||||||
borderColor: 'white',
|
|
||||||
},
|
|
||||||
'&.Mui-focused fieldset': {
|
|
||||||
borderColor: 'white',
|
|
||||||
},
|
|
||||||
'& input': {
|
|
||||||
color: 'white',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'& .MuiInputLabel-root': {
|
|
||||||
color: 'white',
|
|
||||||
},
|
|
||||||
'& .MuiInputLabel-root.Mui-focused': {
|
|
||||||
color: 'white',
|
|
||||||
},
|
|
||||||
'& .MuiAutocomplete-endAdornment svg': {
|
|
||||||
color: 'white',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
)}
|
<ButtonBase onClick={()=> {
|
||||||
/>
|
lookupFunc();
|
||||||
|
}} >
|
||||||
|
<SearchIcon sx={{
|
||||||
|
color: 'white',
|
||||||
|
marginRight: '20px'
|
||||||
|
}} />
|
||||||
|
</ButtonBase>
|
||||||
<ButtonBase sx={{
|
<ButtonBase sx={{
|
||||||
marginLeft: 'auto',
|
marginLeft: 'auto',
|
||||||
|
|
||||||
|
@ -167,9 +167,12 @@ useEffect(()=> {
|
|||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
try {
|
try {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
executeEvent("blockUserFromOutside", {
|
if(isAlreadyBlocked === true){
|
||||||
user: address
|
await removeBlockFromList(address, name)
|
||||||
})
|
} else if(isAlreadyBlocked === false) {
|
||||||
|
await addToBlockList(address, name)
|
||||||
|
}
|
||||||
|
executeEvent('updateChatMessagesWithBlocks', true)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
|
||||||
import { getBaseApiReact } from '../App';
|
|
||||||
|
|
||||||
interface NameListItem {
|
|
||||||
name: string;
|
|
||||||
address: string;
|
|
||||||
}
|
|
||||||
export const useNameSearch = (value: string, limit = 20) => {
|
|
||||||
const [nameList, setNameList] = useState<NameListItem[]>([]);
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
|
||||||
const checkIfNameExisits = useCallback(
|
|
||||||
async (name: string, listLimit: number) => {
|
|
||||||
try {
|
|
||||||
if (!name) {
|
|
||||||
setNameList([]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = await fetch(
|
|
||||||
`${getBaseApiReact()}/names/search?query=${name}&prefix=true&limit=${listLimit}`
|
|
||||||
);
|
|
||||||
const data = await res.json();
|
|
||||||
setNameList(
|
|
||||||
data?.map((item: any) => {
|
|
||||||
return {
|
|
||||||
name: item.name,
|
|
||||||
address: item.owner,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
// Debounce logic
|
|
||||||
useEffect(() => {
|
|
||||||
setIsLoading(true);
|
|
||||||
const handler = setTimeout(() => {
|
|
||||||
checkIfNameExisits(value, limit);
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
// Cleanup timeout if searchValue changes before the timeout completes
|
|
||||||
return () => {
|
|
||||||
clearTimeout(handler);
|
|
||||||
};
|
|
||||||
}, [value, limit, checkIfNameExisits]);
|
|
||||||
return {
|
|
||||||
isLoading,
|
|
||||||
results: nameList,
|
|
||||||
};
|
|
||||||
};
|
|
@ -24,7 +24,7 @@ window.addEventListener("message", (event) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export const sendMessageBackground = (action, data = {}, timeout = 240000, isExtension, appInfo, skipAuth) => {
|
export const sendMessageBackground = (action, data = {}, timeout = 180000, isExtension, appInfo, skipAuth) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const requestId = generateRequestId(); // Unique ID for each request
|
const requestId = generateRequestId(); // Unique ID for each request
|
||||||
callbackMap.set(requestId, { resolve, reject }); // Store both resolve and reject callbacks
|
callbackMap.set(requestId, { resolve, reject }); // Store both resolve and reject callbacks
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { gateways, getApiKeyFromStorage } from "./background";
|
import { gateways, getApiKeyFromStorage } from "./background";
|
||||||
import { listOfAllQortalRequests } from "./components/Apps/useQortalMessageListener";
|
import { listOfAllQortalRequests } from "./components/Apps/useQortalMessageListener";
|
||||||
import { addForeignServer, addGroupAdminRequest, addListItems, adminAction, banFromGroupRequest, buyNameRequest, cancelGroupBanRequest, cancelGroupInviteRequest, cancelSellNameRequest, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createGroupRequest, createPoll, decryptAESGCMRequest, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getArrrSyncStatus, getCrossChainServerInfo, getDaySummary, getForeignFee, getHostedData, getListItems, getNodeInfo, getNodeStatus, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getUserWalletTransactions, getWalletBalance, inviteToGroupRequest, joinGroup, kickFromGroupRequest, leaveGroupRequest, multiPaymentWithPrivateData, openNewTab, publishMultipleQDNResources, publishQDNResource, registerNameRequest, removeForeignServer, removeGroupAdminRequest, saveFile, sellNameRequest, sendChatMessage, sendCoin, setCurrentForeignServer, signForeignFees, signTransaction, transferAssetRequest, updateForeignFee, updateGroupRequest, updateNameRequest, voteOnPoll } from "./qortalRequests/get";
|
import { addForeignServer, addGroupAdminRequest, addListItems, adminAction, banFromGroupRequest, cancelGroupBanRequest, cancelGroupInviteRequest, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createGroupRequest, createPoll, decryptAESGCMRequest, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getArrrSyncStatus, getCrossChainServerInfo, getDaySummary, getForeignFee, getHostedData, getListItems, getNodeInfo, getNodeStatus, getServerConnectionHistory, getTxActivitySummary, getUserAccount, getUserWallet, getUserWalletInfo, getUserWalletTransactions, getWalletBalance, inviteToGroupRequest, joinGroup, kickFromGroupRequest, leaveGroupRequest, openNewTab, publishMultipleQDNResources, publishQDNResource, registerNameRequest, removeForeignServer, removeGroupAdminRequest, saveFile, sendChatMessage, sendCoin, setCurrentForeignServer, signTransaction, updateForeignFee, updateNameRequest, voteOnPoll } from "./qortalRequests/get";
|
||||||
import { getData, storeData } from "./utils/chromeStorage";
|
import { getData, storeData } from "./utils/chromeStorage";
|
||||||
import { executeEvent } from "./utils/events";
|
import { executeEvent } from "./utils/events";
|
||||||
|
|
||||||
@ -462,7 +462,7 @@ export const isRunningGateway = async ()=> {
|
|||||||
|
|
||||||
case "UPDATE_FOREIGN_FEE": {
|
case "UPDATE_FOREIGN_FEE": {
|
||||||
try {
|
try {
|
||||||
const res = await updateForeignFee(request.payload, isFromExtension);
|
const res = await updateForeignFee(request.payload);
|
||||||
event.source.postMessage({
|
event.source.postMessage({
|
||||||
requestId: request.requestId,
|
requestId: request.requestId,
|
||||||
action: request.action,
|
action: request.action,
|
||||||
@ -502,7 +502,7 @@ export const isRunningGateway = async ()=> {
|
|||||||
|
|
||||||
case "SET_CURRENT_FOREIGN_SERVER": {
|
case "SET_CURRENT_FOREIGN_SERVER": {
|
||||||
try {
|
try {
|
||||||
const res = await setCurrentForeignServer(request.payload, isFromExtension);
|
const res = await setCurrentForeignServer(request.payload);
|
||||||
event.source.postMessage({
|
event.source.postMessage({
|
||||||
requestId: request.requestId,
|
requestId: request.requestId,
|
||||||
action: request.action,
|
action: request.action,
|
||||||
@ -522,7 +522,7 @@ export const isRunningGateway = async ()=> {
|
|||||||
|
|
||||||
case "ADD_FOREIGN_SERVER": {
|
case "ADD_FOREIGN_SERVER": {
|
||||||
try {
|
try {
|
||||||
const res = await addForeignServer(request.payload, isFromExtension);
|
const res = await addForeignServer(request.payload);
|
||||||
event.source.postMessage({
|
event.source.postMessage({
|
||||||
requestId: request.requestId,
|
requestId: request.requestId,
|
||||||
action: request.action,
|
action: request.action,
|
||||||
@ -542,7 +542,7 @@ export const isRunningGateway = async ()=> {
|
|||||||
|
|
||||||
case "REMOVE_FOREIGN_SERVER": {
|
case "REMOVE_FOREIGN_SERVER": {
|
||||||
try {
|
try {
|
||||||
const res = await removeForeignServer(request.payload, isFromExtension);
|
const res = await removeForeignServer(request.payload);
|
||||||
event.source.postMessage({
|
event.source.postMessage({
|
||||||
requestId: request.requestId,
|
requestId: request.requestId,
|
||||||
action: request.action,
|
action: request.action,
|
||||||
@ -1206,146 +1206,6 @@ export const isRunningGateway = async ()=> {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "UPDATE_GROUP" : {
|
|
||||||
try {
|
|
||||||
const res = await updateGroupRequest(request.payload, isFromExtension)
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
payload: res,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
} catch (error) {
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
error: error?.message,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "BUY_NAME": {
|
|
||||||
try {
|
|
||||||
const res = await buyNameRequest(request.payload, isFromExtension);
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
payload: res,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
} catch (error) {
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
error: error.message,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "SELL_NAME": {
|
|
||||||
try {
|
|
||||||
const res = await sellNameRequest(request.payload, isFromExtension);
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
payload: res,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
} catch (error) {
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
error: error.message,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "CANCEL_SELL_NAME": {
|
|
||||||
try {
|
|
||||||
const res = await cancelSellNameRequest(request.payload, isFromExtension);
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
payload: res,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
} catch (error) {
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
error: error.message,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "MULTI_ASSET_PAYMENT_WITH_PRIVATE_DATA" : {
|
|
||||||
try {
|
|
||||||
const res = await multiPaymentWithPrivateData(request.payload, isFromExtension)
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
payload: res,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
} catch (error) {
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
error: error?.message,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "TRANSFER_ASSET" : {
|
|
||||||
try {
|
|
||||||
const res = await transferAssetRequest(request.payload, isFromExtension)
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
payload: res,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
} catch (error) {
|
|
||||||
event.source.postMessage({
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
error: error?.message,
|
|
||||||
type: "backgroundMessageResponse",
|
|
||||||
}, event.origin);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'SIGN_FOREIGN_FEES': {
|
|
||||||
try {
|
|
||||||
const res = await signForeignFees(request.payload, isFromExtension);
|
|
||||||
event.source.postMessage(
|
|
||||||
{
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
payload: res,
|
|
||||||
type: 'backgroundMessageResponse',
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
event.source.postMessage(
|
|
||||||
{
|
|
||||||
requestId: request.requestId,
|
|
||||||
action: request.action,
|
|
||||||
error: error.message,
|
|
||||||
type: 'backgroundMessageResponse',
|
|
||||||
},
|
|
||||||
event.origin
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,45 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
import { QORT_DECIMALS } from "../constants/constants"
|
|
||||||
import TransactionBase from "./TransactionBase"
|
|
||||||
|
|
||||||
|
|
||||||
export default class BuyNameTransacion extends TransactionBase {
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.type = 7
|
|
||||||
}
|
|
||||||
|
|
||||||
set fee(fee) {
|
|
||||||
this._fee = fee * QORT_DECIMALS
|
|
||||||
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
set name(name) {
|
|
||||||
this.nameText = name
|
|
||||||
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
|
|
||||||
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
|
|
||||||
}
|
|
||||||
|
|
||||||
set sellPrice(sellPrice) {
|
|
||||||
this._sellPrice = sellPrice * QORT_DECIMALS
|
|
||||||
this._sellPriceBytes = this.constructor.utils.int64ToBytes(this._sellPrice)
|
|
||||||
}
|
|
||||||
|
|
||||||
set recipient(recipient) {
|
|
||||||
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
|
|
||||||
this.theRecipient = recipient
|
|
||||||
}
|
|
||||||
|
|
||||||
get params() {
|
|
||||||
const params = super.params
|
|
||||||
params.push(
|
|
||||||
this._nameLength,
|
|
||||||
this._nameBytes,
|
|
||||||
this._sellPriceBytes,
|
|
||||||
this._recipient,
|
|
||||||
this._feeBytes
|
|
||||||
)
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
import { QORT_DECIMALS } from "../constants/constants"
|
|
||||||
import TransactionBase from "./TransactionBase"
|
|
||||||
|
|
||||||
|
|
||||||
export default class CancelSellNameTransacion extends TransactionBase {
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.type = 6
|
|
||||||
}
|
|
||||||
|
|
||||||
set fee(fee) {
|
|
||||||
this._fee = fee * QORT_DECIMALS
|
|
||||||
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
set name(name) {
|
|
||||||
this.nameText = name
|
|
||||||
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
|
|
||||||
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
|
|
||||||
}
|
|
||||||
|
|
||||||
get params() {
|
|
||||||
const params = super.params
|
|
||||||
params.push(
|
|
||||||
this._nameLength,
|
|
||||||
this._nameBytes,
|
|
||||||
this._feeBytes
|
|
||||||
)
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
import { QORT_DECIMALS } from "../constants/constants"
|
|
||||||
import TransactionBase from "./TransactionBase"
|
|
||||||
|
|
||||||
|
|
||||||
export default class SellNameTransacion extends TransactionBase {
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.type = 5
|
|
||||||
}
|
|
||||||
|
|
||||||
set fee(fee) {
|
|
||||||
this._fee = fee * QORT_DECIMALS
|
|
||||||
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
set name(name) {
|
|
||||||
this.nameText = name
|
|
||||||
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
|
|
||||||
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
|
|
||||||
}
|
|
||||||
|
|
||||||
set sellPrice(sellPrice) {
|
|
||||||
this.showSellPrice = sellPrice
|
|
||||||
this._sellPrice = sellPrice * QORT_DECIMALS
|
|
||||||
this._sellPriceBytes = this.constructor.utils.int64ToBytes(this._sellPrice)
|
|
||||||
}
|
|
||||||
|
|
||||||
get params() {
|
|
||||||
const params = super.params
|
|
||||||
params.push(
|
|
||||||
this._nameLength,
|
|
||||||
this._nameBytes,
|
|
||||||
this._sellPriceBytes,
|
|
||||||
this._feeBytes
|
|
||||||
)
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
import { QORT_DECIMALS } from '../constants/constants'
|
|
||||||
import TransactionBase from './TransactionBase'
|
|
||||||
|
|
||||||
export default class TransferAssetTransaction extends TransactionBase {
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.type = 12
|
|
||||||
}
|
|
||||||
|
|
||||||
set recipient(recipient) {
|
|
||||||
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
|
|
||||||
}
|
|
||||||
|
|
||||||
set amount(amount) {
|
|
||||||
this._amount = Math.round(amount * QORT_DECIMALS)
|
|
||||||
this._amountBytes = this.constructor.utils.int64ToBytes(this._amount)
|
|
||||||
}
|
|
||||||
|
|
||||||
set assetId(assetId) {
|
|
||||||
this._assetId = this.constructor.utils.int64ToBytes(assetId)
|
|
||||||
}
|
|
||||||
|
|
||||||
get params() {
|
|
||||||
const params = super.params
|
|
||||||
params.push(
|
|
||||||
this._recipient,
|
|
||||||
this._assetId,
|
|
||||||
this._amountBytes,
|
|
||||||
this._feeBytes
|
|
||||||
)
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
|
|
||||||
|
|
||||||
import { QORT_DECIMALS } from "../constants/constants";
|
|
||||||
import TransactionBase from "./TransactionBase";
|
|
||||||
|
|
||||||
export default class UpdateGroupTransaction extends TransactionBase {
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.type = 23
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set fee(fee) {
|
|
||||||
this._fee = fee * QORT_DECIMALS
|
|
||||||
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
|
|
||||||
}
|
|
||||||
set newOwner(newOwner) {
|
|
||||||
this._newOwner = newOwner instanceof Uint8Array ? newOwner : this.constructor.Base58.decode(newOwner)
|
|
||||||
}
|
|
||||||
set newIsOpen(newIsOpen) {
|
|
||||||
|
|
||||||
this._rGroupType = new Uint8Array(1)
|
|
||||||
this._rGroupType[0] = newIsOpen
|
|
||||||
}
|
|
||||||
set newDescription(newDescription) {
|
|
||||||
this._rGroupDescBytes = this.constructor.utils.stringtoUTF8Array(newDescription.toLocaleLowerCase())
|
|
||||||
this._rGroupDescLength = this.constructor.utils.int32ToBytes(this._rGroupDescBytes.length)
|
|
||||||
}
|
|
||||||
set newApprovalThreshold(newApprovalThreshold) {
|
|
||||||
this._rGroupApprovalThreshold = new Uint8Array(1)
|
|
||||||
this._rGroupApprovalThreshold[0] = newApprovalThreshold;
|
|
||||||
}
|
|
||||||
set newMinimumBlockDelay(newMinimumBlockDelay) {
|
|
||||||
this._rGroupMinimumBlockDelayBytes = this.constructor.utils.int32ToBytes(newMinimumBlockDelay)
|
|
||||||
}
|
|
||||||
set newMaximumBlockDelay(newMaximumBlockDelay) {
|
|
||||||
|
|
||||||
this._rGroupMaximumBlockDelayBytes = this.constructor.utils.int32ToBytes(newMaximumBlockDelay)
|
|
||||||
}
|
|
||||||
|
|
||||||
set _groupId(_groupId){
|
|
||||||
this._groupBytes = this.constructor.utils.int32ToBytes(_groupId)
|
|
||||||
}
|
|
||||||
get params() {
|
|
||||||
const params = super.params
|
|
||||||
params.push(
|
|
||||||
this._groupBytes,
|
|
||||||
this._newOwner,
|
|
||||||
this._rGroupDescLength,
|
|
||||||
this._rGroupDescBytes,
|
|
||||||
this._rGroupType,
|
|
||||||
this._rGroupApprovalThreshold,
|
|
||||||
this._rGroupMinimumBlockDelayBytes,
|
|
||||||
this._rGroupMaximumBlockDelayBytes,
|
|
||||||
this._feeBytes
|
|
||||||
)
|
|
||||||
return params
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,27 +20,17 @@ import DeployAtTransaction from './DeployAtTransaction.js'
|
|||||||
import RewardShareTransaction from './RewardShareTransaction.js'
|
import RewardShareTransaction from './RewardShareTransaction.js'
|
||||||
import RemoveRewardShareTransaction from './RemoveRewardShareTransaction.js'
|
import RemoveRewardShareTransaction from './RemoveRewardShareTransaction.js'
|
||||||
import UpdateNameTransaction from './UpdateNameTransaction.js'
|
import UpdateNameTransaction from './UpdateNameTransaction.js'
|
||||||
import UpdateGroupTransaction from './UpdateGroupTransaction.js'
|
|
||||||
import SellNameTransacion from './SellNameTransacion.js'
|
|
||||||
import CancelSellNameTransacion from './CancelSellNameTransacion.js'
|
|
||||||
import BuyNameTransacion from './BuyNameTransacion.js'
|
|
||||||
import TransferAssetTransaction from './TransferAssetTransaction.js'
|
|
||||||
|
|
||||||
export const transactionTypes = {
|
export const transactionTypes = {
|
||||||
3: RegisterNameTransaction,
|
3: RegisterNameTransaction,
|
||||||
4: UpdateNameTransaction,
|
4: UpdateNameTransaction,
|
||||||
2: PaymentTransaction,
|
2: PaymentTransaction,
|
||||||
5: SellNameTransacion,
|
|
||||||
6: CancelSellNameTransacion,
|
|
||||||
7: BuyNameTransacion,
|
|
||||||
8: CreatePollTransaction,
|
8: CreatePollTransaction,
|
||||||
9: VoteOnPollTransaction,
|
9: VoteOnPollTransaction,
|
||||||
12: TransferAssetTransaction,
|
|
||||||
16: DeployAtTransaction,
|
16: DeployAtTransaction,
|
||||||
18: ChatTransaction,
|
18: ChatTransaction,
|
||||||
181: GroupChatTransaction,
|
181: GroupChatTransaction,
|
||||||
22: CreateGroupTransaction,
|
22: CreateGroupTransaction,
|
||||||
23: UpdateGroupTransaction,
|
|
||||||
24: AddGroupAdminTransaction,
|
24: AddGroupAdminTransaction,
|
||||||
25: RemoveGroupAdminTransaction,
|
25: RemoveGroupAdminTransaction,
|
||||||
26: GroupBanTransaction,
|
26: GroupBanTransaction,
|
||||||
|
@ -14,18 +14,3 @@ export function decodeIfEncoded(input) {
|
|||||||
// Return input as-is if not URI-encoded
|
// Return input as-is if not URI-encoded
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isValidBase64 = (str: string): boolean => {
|
|
||||||
if (typeof str !== "string" || str.length % 4 !== 0) return false;
|
|
||||||
|
|
||||||
const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
||||||
return base64Regex.test(str);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isValidBase64WithDecode = (str: string): boolean => {
|
|
||||||
try {
|
|
||||||
return isValidBase64(str) && Boolean(atob(str));
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
Loading…
x
Reference in New Issue
Block a user