mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-07-23 04:36:52 +00:00
added minting page
This commit is contained in:
70
src/App.tsx
70
src/App.tsx
@@ -44,7 +44,7 @@ import Success from "./assets/svgs/Success.svg";
|
||||
import Info from "./assets/svgs/Info.svg";
|
||||
import CloseIcon from "@mui/icons-material/Close";
|
||||
import './utils/seedPhrase/RandomSentenceGenerator';
|
||||
|
||||
import EngineeringIcon from '@mui/icons-material/Engineering';
|
||||
import {
|
||||
createAccount,
|
||||
generateRandomSentence,
|
||||
@@ -136,6 +136,8 @@ import { Tutorials } from "./components/Tutorials/Tutorials";
|
||||
import { useHandleTutorials } from "./components/Tutorials/useHandleTutorials";
|
||||
import BoundedNumericTextField from "./common/BoundedNumericTextField";
|
||||
import { useHandleUserInfo } from "./components/Group/useHandleUserInfo";
|
||||
import { Minting } from "./components/Minting/Minting";
|
||||
import { isRunningGateway } from "./qortalRequests";
|
||||
|
||||
type extStates =
|
||||
| "not-authenticated"
|
||||
@@ -406,7 +408,7 @@ function App() {
|
||||
const [isEnabledDevMode, setIsEnabledDevMode] =
|
||||
useRecoilState(enabledDevModeAtom);
|
||||
const setIsDisabledEditorEnter = useSetRecoilState(isDisabledEditorEnterAtom)
|
||||
|
||||
const [isOpenMinting, setIsOpenMinting] = useState(false)
|
||||
const { toggleFullScreen } = useAppFullScreen(setFullScreen);
|
||||
const generatorRef = useRef(null)
|
||||
const exportSeedphrase = ()=> {
|
||||
@@ -1592,6 +1594,54 @@ function App() {
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
{extState === "authenticated" && isMainWindow && (
|
||||
<MyContext.Provider
|
||||
value={{
|
||||
txList,
|
||||
setTxList,
|
||||
memberGroups,
|
||||
setMemberGroups,
|
||||
isShow,
|
||||
onCancel,
|
||||
onOk,
|
||||
show,
|
||||
userInfo,
|
||||
message,
|
||||
rootHeight,
|
||||
showInfo,
|
||||
openSnackGlobal: openSnack,
|
||||
setOpenSnackGlobal: setOpenSnack,
|
||||
infoSnackCustom: infoSnack,
|
||||
setInfoSnackCustom: setInfoSnack,
|
||||
downloadResource,
|
||||
getIndividualUserInfo
|
||||
}}
|
||||
>
|
||||
<TaskManager getUserInfo={getUserInfo} />
|
||||
</MyContext.Provider>
|
||||
)}
|
||||
<Spacer height="20px" />
|
||||
<ButtonBase onClick={async ()=> {
|
||||
try {
|
||||
const res = await isRunningGateway()
|
||||
if(res) throw new Error('Cannot view minting details on the gateway')
|
||||
setIsOpenMinting(true)
|
||||
|
||||
} catch (error) {
|
||||
setOpenSnack(true)
|
||||
setInfoSnack({
|
||||
type: 'error',
|
||||
message: error?.message
|
||||
})
|
||||
}
|
||||
}}>
|
||||
<EngineeringIcon sx={{
|
||||
color: 'var(--unread)'
|
||||
}} />
|
||||
</ButtonBase>
|
||||
|
||||
|
||||
<Spacer height="20px" />
|
||||
{(desktopViewMode === "apps" || desktopViewMode === "home") && (
|
||||
<ButtonBase onClick={()=> {
|
||||
if(desktopViewMode === "apps"){
|
||||
@@ -1705,17 +1755,7 @@ function App() {
|
||||
{!isMobile && renderProfile()}
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
position: "fixed",
|
||||
right: "25px",
|
||||
bottom: "25px",
|
||||
width: "350px",
|
||||
zIndex: 100000,
|
||||
}}
|
||||
>
|
||||
<TaskManager getUserInfo={getUserInfo} />
|
||||
</Box>
|
||||
|
||||
</MyContext.Provider>
|
||||
)}
|
||||
{isOpenSendQort && isMainWindow && (
|
||||
@@ -3273,7 +3313,9 @@ function App() {
|
||||
}} />
|
||||
</ButtonBase>
|
||||
)}
|
||||
|
||||
{isOpenMinting && (
|
||||
<Minting setIsOpenMinting={setIsOpenMinting} groups={memberGroups} myAddress={address} show={show} setTxList={setTxList} txList={txList}/>
|
||||
)}
|
||||
</AppContainer>
|
||||
);
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@ import {
|
||||
getGroupDataSingle,
|
||||
getKeyPair,
|
||||
getLTCBalance,
|
||||
getLastRef,
|
||||
getNameInfo,
|
||||
getTempPublish,
|
||||
getTimestampEnterChat,
|
||||
@@ -41,6 +42,7 @@ import {
|
||||
makeAdmin,
|
||||
notifyAdminRegenerateSecretKey,
|
||||
pauseAllQueues,
|
||||
processTransactionVersion2,
|
||||
registerName,
|
||||
removeAdmin,
|
||||
resumeAllQueues,
|
||||
@@ -56,8 +58,10 @@ import {
|
||||
} from "./background";
|
||||
import { decryptGroupEncryption, encryptAndPublishSymmetricKeyGroupChat, encryptAndPublishSymmetricKeyGroupChatForAdmins, publishGroupEncryptedResource, publishOnQDN } from "./backgroundFunctions/encryption";
|
||||
import { PUBLIC_NOTIFICATION_CODE_FIRST_SECRET_KEY } from "./constants/codes";
|
||||
import Base58 from "./deps/Base58";
|
||||
import { encryptSingle } from "./qdn/encryption/group-encryption";
|
||||
import { _createPoll, _voteOnPoll } from "./qortalRequests/get";
|
||||
import { createTransaction } from "./transactions/transactions";
|
||||
import { getData, storeData } from "./utils/chromeStorage";
|
||||
|
||||
export function versionCase(request, event) {
|
||||
@@ -1895,4 +1899,140 @@ export async function publishGroupEncryptedResourceCase(request, event) {
|
||||
event.origin
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function createRewardShareCase(request, event) {
|
||||
try {
|
||||
const {recipientPublicKey} = request.payload;
|
||||
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,
|
||||
};
|
||||
let lastRef = await getLastRef();
|
||||
|
||||
const tx = await createTransaction(38, keyPair, {
|
||||
recipientPublicKey,
|
||||
percentageShare: 0,
|
||||
lastReference: lastRef,
|
||||
});
|
||||
|
||||
const signedBytes = Base58.encode(tx.signedBytes);
|
||||
|
||||
const res = await processTransactionVersion2(signedBytes);
|
||||
if (!res?.signature)
|
||||
throw new Error("Transaction was not able to be processed");
|
||||
event.source.postMessage(
|
||||
{
|
||||
requestId: request.requestId,
|
||||
action: "createRewardShare",
|
||||
payload: res,
|
||||
type: "backgroundMessageResponse",
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} catch (error) {
|
||||
event.source.postMessage(
|
||||
{
|
||||
requestId: request.requestId,
|
||||
action: "createRewardShare",
|
||||
error: error?.message,
|
||||
type: "backgroundMessageResponse",
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function removeRewardShareCase(request, event) {
|
||||
try {
|
||||
const {rewardShareKeyPairPublicKey, recipient, percentageShare} = request.payload;
|
||||
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,
|
||||
};
|
||||
let lastRef = await getLastRef();
|
||||
|
||||
const tx = await createTransaction(381, keyPair, {
|
||||
rewardShareKeyPairPublicKey,
|
||||
recipient,
|
||||
percentageShare,
|
||||
lastReference: lastRef,
|
||||
});
|
||||
|
||||
const signedBytes = Base58.encode(tx.signedBytes);
|
||||
|
||||
const res = await processTransactionVersion2(signedBytes);
|
||||
if (!res?.signature)
|
||||
throw new Error("Transaction was not able to be processed");
|
||||
event.source.postMessage(
|
||||
{
|
||||
requestId: request.requestId,
|
||||
action: "removeRewardShare",
|
||||
payload: res,
|
||||
type: "backgroundMessageResponse",
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} catch (error) {
|
||||
event.source.postMessage(
|
||||
{
|
||||
requestId: request.requestId,
|
||||
action: "removeRewardShare",
|
||||
error: error?.message,
|
||||
type: "backgroundMessageResponse",
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getRewardSharePrivateKeyCase(request, event) {
|
||||
try {
|
||||
const {recipientPublicKey} = request.payload;
|
||||
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,
|
||||
};
|
||||
let lastRef = await getLastRef();
|
||||
|
||||
const tx = await createTransaction(38, keyPair, {
|
||||
recipientPublicKey,
|
||||
percentageShare: 0,
|
||||
lastReference: lastRef,
|
||||
});
|
||||
|
||||
event.source.postMessage(
|
||||
{
|
||||
requestId: request.requestId,
|
||||
action: "getRewardSharePrivateKey",
|
||||
payload: tx?._base58RewardShareSeed,
|
||||
type: "backgroundMessageResponse",
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
} catch (error) {
|
||||
event.source.postMessage(
|
||||
{
|
||||
requestId: request.requestId,
|
||||
action: "getRewardSharePrivateKey",
|
||||
error: error?.message,
|
||||
type: "backgroundMessageResponse",
|
||||
},
|
||||
event.origin
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -47,6 +47,7 @@ import {
|
||||
clearAllNotificationsCase,
|
||||
createGroupCase,
|
||||
createPollCase,
|
||||
createRewardShareCase,
|
||||
decryptDirectCase,
|
||||
decryptGroupEncryptionCase,
|
||||
decryptSingleCase,
|
||||
@@ -61,6 +62,7 @@ import {
|
||||
getEnteredQmailTimestampCase,
|
||||
getGroupDataSingleCase,
|
||||
getGroupNotificationTimestampCase,
|
||||
getRewardSharePrivateKeyCase,
|
||||
getTempPublishCase,
|
||||
getThreadActivityCase,
|
||||
getTimestampEnterChatCase,
|
||||
@@ -82,6 +84,7 @@ import {
|
||||
publishOnQDNCase,
|
||||
registerNameCase,
|
||||
removeAdminCase,
|
||||
removeRewardShareCase,
|
||||
resumeAllQueuesCase,
|
||||
saveTempPublishCase,
|
||||
sendChatDirectCase,
|
||||
@@ -1105,7 +1108,7 @@ export const sendQortFee = async (): Promise<number> => {
|
||||
return qortFee;
|
||||
};
|
||||
|
||||
async function getNameOrAddress(receiver) {
|
||||
export async function getNameOrAddress(receiver) {
|
||||
try {
|
||||
const isAddress = validateAddress(receiver);
|
||||
if (isAddress) {
|
||||
@@ -3046,6 +3049,15 @@ function setupMessageListener() {
|
||||
case "setupGroupWebsocket":
|
||||
setupGroupWebsocketCase(request, event);
|
||||
break;
|
||||
case "createRewardShare":
|
||||
createRewardShareCase(request, event);
|
||||
break;
|
||||
case "getRewardSharePrivateKey":
|
||||
getRewardSharePrivateKeyCase(request, event);
|
||||
break;
|
||||
case "removeRewardShare" :
|
||||
removeRewardShareCase(request, event);
|
||||
break;
|
||||
case "addEnteredQmailTimestamp":
|
||||
addEnteredQmailTimestampCase(request, event);
|
||||
break;
|
||||
|
1191
src/components/Minting/Minting.tsx
Normal file
1191
src/components/Minting/Minting.tsx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,7 @@ import TaskAltIcon from "@mui/icons-material/TaskAlt";
|
||||
import ExpandLess from "@mui/icons-material/ExpandLess";
|
||||
import ExpandMore from "@mui/icons-material/ExpandMore";
|
||||
import { MyContext, getBaseApiReact, isMobile } from "../../App";
|
||||
import { executeEvent } from "../../utils/events";
|
||||
|
||||
export const TaskManager = ({ getUserInfo }) => {
|
||||
const { txList, setTxList, memberGroups } = useContext(MyContext);
|
||||
@@ -39,7 +40,7 @@ export const TaskManager = ({ getUserInfo }) => {
|
||||
await new Promise((res) =>
|
||||
setTimeout(() => {
|
||||
res(null);
|
||||
}, 300000)
|
||||
}, 60000)
|
||||
);
|
||||
setTxList((prev) => {
|
||||
let previousData = [...prev];
|
||||
@@ -62,7 +63,7 @@ export const TaskManager = ({ getUserInfo }) => {
|
||||
}
|
||||
};
|
||||
|
||||
intervals.current[signature] = setInterval(getAnswer, 120000);
|
||||
intervals.current[signature] = setInterval(getAnswer, 60000);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -96,7 +97,15 @@ export const TaskManager = ({ getUserInfo }) => {
|
||||
}
|
||||
});
|
||||
|
||||
prev.forEach((tx) => {
|
||||
|
||||
|
||||
return previousData;
|
||||
});
|
||||
}, [memberGroups, getUserInfo]);
|
||||
|
||||
useEffect(()=> {
|
||||
|
||||
txList.forEach((tx) => {
|
||||
if (
|
||||
["created-common-secret", "joined-group-request", "join-request-accept"].includes(
|
||||
tx?.type
|
||||
@@ -113,11 +122,17 @@ export const TaskManager = ({ getUserInfo }) => {
|
||||
getStatus({ signature: tx.signature }, getUserInfo);
|
||||
}
|
||||
}
|
||||
if((tx?.type === "remove-rewardShare" || tx?.type === "add-rewardShare") && tx?.signature && !tx.done){
|
||||
if (!intervals.current[tx.signature]) {
|
||||
const sendEventForRewardShare = ()=> {
|
||||
executeEvent('refresh-rewardshare-list', {})
|
||||
}
|
||||
getStatus({ signature: tx.signature }, sendEventForRewardShare);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return previousData;
|
||||
});
|
||||
}, [memberGroups, getUserInfo]);
|
||||
}, [txList])
|
||||
|
||||
if (isMobile || txList?.length === 0 || txList.every((item) => item?.done))
|
||||
return null;
|
||||
@@ -128,9 +143,9 @@ export const TaskManager = ({ getUserInfo }) => {
|
||||
<IconButton
|
||||
onClick={handleClick}
|
||||
sx={{
|
||||
position: "fixed",
|
||||
bottom: 16,
|
||||
right: 16,
|
||||
// position: "fixed",
|
||||
// bottom: 16,
|
||||
// right: 16,
|
||||
bgcolor: "primary.main",
|
||||
color: "white",
|
||||
":hover": { bgcolor: "primary.dark" },
|
||||
|
46
src/transactions/RemoveRewardShareTransaction.ts
Normal file
46
src/transactions/RemoveRewardShareTransaction.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { DYNAMIC_FEE_TIMESTAMP } from "../constants/constants"
|
||||
import Base58 from "../deps/Base58"
|
||||
import publicKeyToAddress from "../utils/generateWallet/publicKeyToAddress"
|
||||
import TransactionBase from "./TransactionBase"
|
||||
|
||||
|
||||
export default class RemoveRewardShareTransaction extends TransactionBase {
|
||||
constructor() {
|
||||
super()
|
||||
this.type = 38
|
||||
}
|
||||
|
||||
|
||||
set rewardShareKeyPairPublicKey(rewardShareKeyPairPublicKey) {
|
||||
this._rewardShareKeyPairPublicKey = Base58.decode(rewardShareKeyPairPublicKey)
|
||||
}
|
||||
|
||||
set recipient(recipient) {
|
||||
const _address = publicKeyToAddress(this._keyPair.publicKey)
|
||||
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
|
||||
|
||||
if (new Date(this._timestamp).getTime() >= DYNAMIC_FEE_TIMESTAMP) {
|
||||
this.fee = _address === recipient ? 0 : 0.01
|
||||
} else {
|
||||
this.fee = _address === recipient ? 0 : 0.001
|
||||
}
|
||||
}
|
||||
|
||||
set percentageShare(share) {
|
||||
this._percentageShare = share * 100
|
||||
this._percentageShareBytes = this.constructor.utils.int64ToBytes(this._percentageShare)
|
||||
}
|
||||
|
||||
get params() {
|
||||
const params = super.params
|
||||
params.push(
|
||||
this._recipient,
|
||||
this._rewardShareKeyPairPublicKey,
|
||||
this._percentageShareBytes,
|
||||
this._feeBytes
|
||||
)
|
||||
return params
|
||||
}
|
||||
}
|
60
src/transactions/RewardShareTransaction.ts
Normal file
60
src/transactions/RewardShareTransaction.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import TransactionBase from './TransactionBase'
|
||||
|
||||
import { Sha256 } from 'asmcrypto.js'
|
||||
import nacl from '../deps/nacl-fast'
|
||||
import ed2curve from '../deps/ed2curve'
|
||||
import { DYNAMIC_FEE_TIMESTAMP } from '../constants/constants'
|
||||
import publicKeyToAddress from '../utils/generateWallet/publicKeyToAddress'
|
||||
|
||||
export default class RewardShareTransaction extends TransactionBase {
|
||||
constructor() {
|
||||
super()
|
||||
this.type = 38
|
||||
}
|
||||
|
||||
|
||||
|
||||
set recipientPublicKey(recipientPublicKey) {
|
||||
this._base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? this.constructor.Base58.encode(recipientPublicKey) : recipientPublicKey
|
||||
this._recipientPublicKey = this.constructor.Base58.decode(this._base58RecipientPublicKey)
|
||||
this.recipient = publicKeyToAddress(this._recipientPublicKey)
|
||||
|
||||
const convertedPrivateKey = ed2curve.convertSecretKey(this._keyPair.privateKey)
|
||||
const convertedPublicKey = ed2curve.convertPublicKey(this._recipientPublicKey)
|
||||
const sharedSecret = new Uint8Array(32)
|
||||
|
||||
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
|
||||
|
||||
this._rewardShareSeed = new Sha256().process(sharedSecret).finish().result
|
||||
this._base58RewardShareSeed = this.constructor.Base58.encode(this._rewardShareSeed)
|
||||
this._rewardShareKeyPair = nacl.sign.keyPair.fromSeed(this._rewardShareSeed)
|
||||
|
||||
if (new Date(this._timestamp).getTime() >= DYNAMIC_FEE_TIMESTAMP) {
|
||||
this.fee = (recipientPublicKey === this.constructor.Base58.encode(this._keyPair.publicKey) ? 0 : 0.01)
|
||||
} else {
|
||||
this.fee = (recipientPublicKey === this.constructor.Base58.encode(this._keyPair.publicKey) ? 0 : 0.001)
|
||||
}
|
||||
}
|
||||
|
||||
set recipient(recipient) {
|
||||
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
|
||||
}
|
||||
|
||||
set percentageShare(share) {
|
||||
this._percentageShare = share * 100
|
||||
this._percentageShareBytes = this.constructor.utils.int64ToBytes(this._percentageShare)
|
||||
}
|
||||
|
||||
get params() {
|
||||
const params = super.params
|
||||
params.push(
|
||||
this._recipient,
|
||||
this._rewardShareKeyPair.publicKey,
|
||||
this._percentageShareBytes,
|
||||
this._feeBytes
|
||||
)
|
||||
return params
|
||||
}
|
||||
}
|
@@ -17,6 +17,8 @@ import RegisterNameTransaction from './RegisterNameTransaction.js'
|
||||
import VoteOnPollTransaction from './VoteOnPollTransaction.js'
|
||||
import CreatePollTransaction from './CreatePollTransaction.js'
|
||||
import DeployAtTransaction from './DeployAtTransaction.js'
|
||||
import RewardShareTransaction from './RewardShareTransaction.js'
|
||||
import RemoveRewardShareTransaction from './RemoveRewardShareTransaction.js'
|
||||
|
||||
|
||||
export const transactionTypes = {
|
||||
@@ -36,14 +38,14 @@ export const transactionTypes = {
|
||||
29: GroupInviteTransaction,
|
||||
30: CancelGroupInviteTransaction,
|
||||
31: JoinGroupTransaction,
|
||||
32: LeaveGroupTransaction
|
||||
32: LeaveGroupTransaction,
|
||||
38: RewardShareTransaction,
|
||||
381: RemoveRewardShareTransaction
|
||||
}
|
||||
|
||||
|
||||
export const createTransaction = (type, keyPair, params) => {
|
||||
|
||||
const tx = new transactionTypes[type]()
|
||||
|
||||
tx.keyPair = keyPair
|
||||
Object.keys(params).forEach(param => {
|
||||
|
||||
|
Reference in New Issue
Block a user