added purchasing name qortalRequests

This commit is contained in:
PhilReact 2025-04-10 10:49:31 +03:00
parent 63c96f5ea0
commit 7e7e914cf9
13 changed files with 432 additions and 10 deletions

View File

@ -42,7 +42,11 @@ export const sortablePinnedAppsAtom = atom({
{ {
name: 'Q-Wallets', name: 'Q-Wallets',
service: 'APP' service: 'APP'
} },
{
name: 'Q-Search',
service: 'APP'
},
], ],
}); });

View File

@ -2309,6 +2309,110 @@ export async function createGroup({
throw new Error(res?.message || "Transaction was not able to be processed"); 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,
};
console.log('tester', {
fee: feeres.fee,
name,
sellPrice,
recipient: sellerAddress,
lastReference: lastReference,
})
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({ export async function updateGroup({
groupId, groupId,
newOwner, newOwner,

View File

@ -41,7 +41,8 @@ const officialAppList = [
"q-trade", "q-trade",
"q-support", "q-support",
"q-manager", "q-manager",
"q-wallets" "q-wallets",
"q-search"
]; ];
const ScrollerStyled = styled('div')({ const ScrollerStyled = styled('div')({

View File

@ -49,7 +49,8 @@ const officialAppList = [
"q-trade", "q-trade",
"q-support", "q-support",
"q-manager", "q-manager",
"q-wallets" "q-wallets",
"q-search"
]; ];
const ScrollerStyled = styled("div")({ const ScrollerStyled = styled("div")({

View File

@ -43,7 +43,8 @@ const officialAppList = [
"q-trade", "q-trade",
"q-support", "q-support",
"q-manager", "q-manager",
"q-wallets" "q-wallets",
"q-search"
]; ];
const ScrollerStyled = styled('div')({ const ScrollerStyled = styled('div')({

View File

@ -59,7 +59,8 @@ const officialAppList = [
"q-support", "q-support",
"q-manager", "q-manager",
"q-mintership", "q-mintership",
"q-wallets" "q-wallets",
"q-search"
]; ];
const ScrollerStyled = styled("div")({ const ScrollerStyled = styled("div")({

View File

@ -256,7 +256,10 @@ export const listOfAllQortalRequests = [
'GET_NODE_STATUS', 'GET_NODE_STATUS',
'GET_ARRR_SYNC_STATUS', 'GET_ARRR_SYNC_STATUS',
'SHOW_PDF_READER', 'SHOW_PDF_READER',
'UPDATE_GROUP' 'UPDATE_GROUP',
'SELL_NAME',
'CANCEL_SELL_NAME',
'BUY_NAME'
] ]
export const UIQortalRequests = [ export const UIQortalRequests = [
@ -313,7 +316,10 @@ export const UIQortalRequests = [
'GET_NODE_STATUS', 'GET_NODE_STATUS',
'GET_ARRR_SYNC_STATUS', 'GET_ARRR_SYNC_STATUS',
'SHOW_PDF_READER', 'SHOW_PDF_READER',
'UPDATE_GROUP' 'UPDATE_GROUP',
'SELL_NAME',
'CANCEL_SELL_NAME',
'BUY_NAME'
]; ];

View File

@ -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, cancelGroupBanRequest, cancelGroupInviteRequest, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createGroupRequest, createPoll, createSellOrder, decryptAESGCMRequest, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getNodeInfo, getNodeStatus, getForeignFee, getHostedData, getListItems, 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, getArrrSyncStatus, updateGroupRequest } from "./qortalRequests/get"; import { addForeignServer, addGroupAdminRequest, addListItems, adminAction, banFromGroupRequest, cancelGroupBanRequest, cancelGroupInviteRequest, cancelSellOrder, createAndCopyEmbedLink, createBuyOrder, createGroupRequest, createPoll, createSellOrder, decryptAESGCMRequest, decryptData, decryptDataWithSharingKey, decryptQortalGroupData, deleteHostedData, deleteListItems, deployAt, encryptData, encryptDataWithSharingKey, encryptQortalGroupData, getCrossChainServerInfo, getDaySummary, getNodeInfo, getNodeStatus, getForeignFee, getHostedData, getListItems, 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, getArrrSyncStatus, updateGroupRequest, buyNameRequest, sellNameRequest, cancelSellNameRequest } 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";
@ -1257,6 +1257,63 @@ export const isRunningGateway = async ()=> {
} }
break; 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;
}
default: default:
break; break;
} }

View File

@ -31,6 +31,10 @@ import {
cancelInvitationToGroup, cancelInvitationToGroup,
createGroup, createGroup,
updateGroup, updateGroup,
sellName,
cancelSellName,
buyName,
getBaseApi,
} from "../background"; } from "../background";
import { getNameInfo, uint8ArrayToObject } from "../backgroundFunctions/encryption"; import { getNameInfo, uint8ArrayToObject } from "../backgroundFunctions/encryption";
import { showSaveFilePicker } from "../components/Apps/useQortalMessageListener"; import { showSaveFilePicker } from "../components/Apps/useQortalMessageListener";
@ -4686,3 +4690,122 @@ export const decryptAESGCMRequest = async (data, isFromExtension) => {
throw new Error("Failed to decrypt the message. Ensure the data and keys are correct."); throw new Error("Failed to decrypt the message. Ensure the data and keys are correct.");
} }
}; };
export const sellNameRequest = async (data, isFromExtension) => {
const requiredFields = ["salePrice", "nameForSale"];
const missingFields: string[] = [];
requiredFields.forEach((field) => {
if (data[field] !== undefined && data[field] !== null) {
missingFields.push(field);
}
});
const name = data.nameForSale
const sellPrice = +data.salePrice
const validApi = await getBaseApi();
const response = await fetch(validApi + "/names/" + name);
const nameData = await response.json();
if(!nameData) throw new Error("This name does not exist")
if(nameData?.isForSale) throw new Error("This name is already for sale")
const fee = await getFee("SELL_NAME");
const resPermission = await getUserPermission(
{
text1: `Do you give this application permission to create a sell name transaction?`,
highlightedText: `Sell ${name} for ${sellPrice} QORT`,
fee: fee.fee,
},
isFromExtension
);
const { accepted } = resPermission;
if (accepted) {
const response = await sellName({
name,
sellPrice
})
return response
} else {
throw new Error("User declined request");
}
};
export const cancelSellNameRequest = async (data, isFromExtension) => {
const requiredFields = ["nameForSale"];
const missingFields: string[] = [];
requiredFields.forEach((field) => {
if (data[field] !== undefined && data[field] !== null) {
missingFields.push(field);
}
});
const name = data.nameForSale
const validApi = await getBaseApi();
const response = await fetch(validApi + "/names/" + name);
const nameData = await response.json();
if(!nameData?.isForSale) throw new Error("This name is not for sale")
const fee = await getFee("CANCEL_SELL_NAME");
const resPermission = await getUserPermission(
{
text1: `Do you give this application permission to cancel the selling of a name?`,
highlightedText: `Name: ${name}`,
fee: fee.fee,
},
isFromExtension
);
const { accepted } = resPermission;
if (accepted) {
const response = await cancelSellName({
name
})
return response
} else {
throw new Error("User declined request");
}
};
export const buyNameRequest = async (data, isFromExtension) => {
const requiredFields = ["nameForSale"];
const missingFields: string[] = [];
requiredFields.forEach((field) => {
if (data[field] !== undefined && data[field] !== null) {
missingFields.push(field);
}
});
const name = data.nameForSale
const validApi = await getBaseApi();
const response = await fetch(validApi + "/names/" + name);
const nameData = await response.json();
if(!nameData?.isForSale) throw new Error("This name is not for sale")
const sellerAddress = nameData.owner
const sellPrice = +nameData.salePrice
const fee = await getFee("BUY_NAME");
const resPermission = await getUserPermission(
{
text1: `Do you give this application permission to buy a name?`,
highlightedText: `Buying ${name} for ${sellPrice} QORT`,
fee: fee.fee,
},
isFromExtension
);
const { accepted } = resPermission;
if (accepted) {
const response = await buyName({
name,
sellerAddress,
sellPrice
})
return response
} else {
throw new Error("User declined request");
}
};

View File

@ -0,0 +1,45 @@
// @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
}
}

View File

@ -0,0 +1,33 @@
// @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
}
}

View File

@ -0,0 +1,40 @@
// @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
}
}

View File

@ -21,12 +21,18 @@ 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 UpdateGroupTransaction from './UpdateGroupTransaction.js'
import SellNameTransacion from './SellNameTransacion.js'
import CancelSellNameTransacion from './CancelSellNameTransacion.js'
import BuyNameTransacion from './BuyNameTransacion.js'
export const transactionTypes = { export const transactionTypes = {
2: PaymentTransaction,
3: RegisterNameTransaction, 3: RegisterNameTransaction,
4: UpdateNameTransaction, 4: UpdateNameTransaction,
2: PaymentTransaction, 5: SellNameTransacion,
6: CancelSellNameTransacion,
7: BuyNameTransacion,
8: CreatePollTransaction, 8: CreatePollTransaction,
9: VoteOnPollTransaction, 9: VoteOnPollTransaction,
16: DeployAtTransaction, 16: DeployAtTransaction,