added qortalrequset for polls

This commit is contained in:
PhilReact 2024-10-15 19:47:08 +03:00
parent 68940c5c25
commit 470b554822
8 changed files with 302 additions and 6 deletions

View File

@ -729,7 +729,7 @@ async function storeFilesInIndexedDB(obj) {
const UIQortalRequests = ['GET_USER_ACCOUNT', 'ENCRYPT_DATA', 'DECRYPT_DATA', 'SEND_COIN', 'GET_LIST_ITEMS', 'ADD_LIST_ITEMS', 'DELETE_LIST_ITEM']
const UIQortalRequests = ['GET_USER_ACCOUNT', 'ENCRYPT_DATA', 'DECRYPT_DATA', 'SEND_COIN', 'GET_LIST_ITEMS', 'ADD_LIST_ITEMS', 'DELETE_LIST_ITEM', 'VOTE_ON_POLL', 'CREATE_POLL']
if (!window.hasAddedQortalListener) {
console.log("Listener added");

View File

@ -1931,11 +1931,9 @@ function App() {
>
<TextP
sx={{
textAlign: "center",
lineHeight: 1.2,
fontSize: "16px",
fontWeight: "normal",
maxWidth: "90%",
}}
>
{messageQortalRequest?.text4}

View File

@ -1059,7 +1059,7 @@ const processTransactionVersion2Chat = async (body: any, customApi) => {
});
};
const processTransactionVersion2 = async (body: any) => {
export const processTransactionVersion2 = async (body: any) => {
const url = await createEndpoint(`/transactions/process?apiVersion=2`);
try {
@ -1141,7 +1141,7 @@ const makeTransactionRequest = async (
return myTxnrequest;
};
const getLastRef = async () => {
export const getLastRef = async () => {
const wallet = await getSaveWallet();
const address = wallet.address0;
const validApi = await getBaseApi();

View File

@ -1,4 +1,4 @@
import { addListItems, decryptData, deleteListItems, encryptData, getListItems, getUserAccount, publishMultipleQDNResources, publishQDNResource, sendCoin } from "./qortalRequests/get";
import { addListItems, createPoll, decryptData, deleteListItems, encryptData, getListItems, getUserAccount, publishMultipleQDNResources, publishQDNResource, sendCoin, voteOnPoll } from "./qortalRequests/get";
@ -166,6 +166,32 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
break;
}
case "VOTE_ON_POLL": {
const data = request.payload;
voteOnPoll(data)
.then((res) => {
sendResponse(res);
})
.catch((error) => {
sendResponse({ error: error.message });
});
break;
}
case "CREATE_POLL": {
const data = request.payload;
createPoll(data)
.then((res) => {
sendResponse(res);
})
.catch((error) => {
sendResponse({ error: error.message });
});
break;
}
case "SEND_COIN": {
const data = request.payload;
const requiredFields = ["coin", "destinationAddress", "amount"];

View File

@ -2,7 +2,9 @@ import {
createEndpoint,
getFee,
getKeyPair,
getLastRef,
getSaveWallet,
processTransactionVersion2,
removeDuplicateWindow,
} from "../background";
import { getNameInfo } from "../backgroundFunctions/encryption";
@ -17,8 +19,98 @@ import {
} from "../qdn/encryption/group-encryption";
import { publishData } from "../qdn/publish/pubish";
import { getPermission, setPermission } from "../qortalRequests";
import { createTransaction } from "../transactions/transactions";
import { fileToBase64 } from "../utils/fileReading";
const _createPoll = async (pollName, pollDescription, options) => {
const fee = await getFee("CREATE_POLL");
const resPermission = await getUserPermission({
text1: "You are requesting to create the poll below:",
text2: `Poll: ${pollName}`,
text3: `Description: ${pollDescription}`,
text4: `Options: ${options?.join(', ')}`,
fee: fee.fee,
});
const { accepted } = resPermission;
if(accepted){
const wallet = await getSaveWallet();
const address = wallet.address0;
const resKeyPair = await getKeyPair();
const parsedData = JSON.parse(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(8, keyPair, {
fee: fee.fee,
ownerAddress: address,
rPollName: pollName,
rPollDesc: pollDescription,
rOptions: options,
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");
return res;
} else {
throw new Error("User declined request");
}
}
const _voteOnPoll =async (pollName, optionIndex, optionName)=> {
const fee = await getFee("VOTE_ON_POLL");
const resPermission = await getUserPermission({
text1: "You are being requested to vote on the poll below:",
text2: `Poll: ${pollName}`,
text3: `Option: ${optionName}`,
fee: fee.fee,
});
const { accepted } = resPermission;
if(accepted){
const wallet = await getSaveWallet();
const address = wallet.address0;
const resKeyPair = await getKeyPair();
const parsedData = JSON.parse(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(9, keyPair, {
fee: fee.fee,
voterAddress: address,
rPollName: pollName,
rOptionIndex: optionIndex,
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");
return res;
} else {
throw new Error("User declined request");
}
}
function getFileFromContentScript(fileId, sender) {
console.log('sender', sender)
return new Promise((resolve, reject) => {
@ -724,6 +816,71 @@ export const publishMultipleQDNResources = async (data: any, sender) => {
return true;
};
export const voteOnPoll = async (data) => {
const requiredFields = ['pollName', 'optionIndex']
const missingFields: string[] = []
requiredFields.forEach((field) => {
if (!data[field] && data[field] !== 0) {
missingFields.push(field)
}
})
if (missingFields.length > 0) {
const missingFieldsString = missingFields.join(', ')
const errorMsg = `Missing fields: ${missingFieldsString}`
throw new Error(errorMsg)
}
const pollName = data.pollName
const optionIndex = data.optionIndex
let pollInfo = null
try {
const url = await createEndpoint(`/polls/${encodeURIComponent(pollName)}`);
const response = await fetch(url);
if (!response.ok) throw new Error("Failed to fetch poll");
pollInfo = await response.json();
} catch (error) {
const errorMsg = (error && error.message) || 'Poll not found'
throw new Error(errorMsg)
}
if (!pollInfo || pollInfo.error) {
const errorMsg = (pollInfo && pollInfo.message) || 'Poll not found'
throw new Error(errorMsg)
}
try {
const optionName = pollInfo.pollOptions[optionIndex].optionName
const resVoteOnPoll = await _voteOnPoll(pollName, optionIndex, optionName)
return resVoteOnPoll
} catch (error) {
throw new Error(error?.message || 'Failed to vote on the poll.')
}
};
export const createPoll = async (data) => {
const requiredFields = ['pollName', 'pollDescription', 'pollOptions', 'pollOwnerAddress']
const missingFields: string[] = []
requiredFields.forEach((field) => {
if (!data[field]) {
missingFields.push(field)
}
})
if (missingFields.length > 0) {
const missingFieldsString = missingFields.join(', ')
const errorMsg = `Missing fields: ${missingFieldsString}`
throw new Error(errorMsg)
}
const pollName = data.pollName
const pollDescription = data.pollDescription
const pollOptions = data.pollOptions
const pollOwnerAddress = data.pollOwnerAddress
try {
const resCreatePoll = await _createPoll(pollName, pollDescription, pollOptions, pollOwnerAddress)
return resCreatePoll
} catch (error) {
throw new Error(error?.message || 'Failed to created poll.')
}
};
export const sendCoin = async () => {
try {
const wallet = await getSaveWallet();

View File

@ -0,0 +1,73 @@
// @ts-nocheck
import { QORT_DECIMALS } from '../constants/constants'
import TransactionBase from './TransactionBase'
export default class CreatePollTransaction extends TransactionBase {
constructor() {
super()
this.type = 8
this._options = []
}
addOption(option) {
const optionBytes = this.constructor.utils.stringtoUTF8Array(option)
const optionLength = this.constructor.utils.int32ToBytes(optionBytes.length)
this._options.push({ length: optionLength, bytes: optionBytes })
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set ownerAddress(ownerAddress) {
this._ownerAddress = ownerAddress instanceof Uint8Array ? ownerAddress : this.constructor.Base58.decode(ownerAddress)
}
set rPollName(rPollName) {
this._rPollName = rPollName
this._rPollNameBytes = this.constructor.utils.stringtoUTF8Array(this._rPollName)
this._rPollNameLength = this.constructor.utils.int32ToBytes(this._rPollNameBytes.length)
}
set rPollDesc(rPollDesc) {
this._rPollDesc = rPollDesc
this._rPollDescBytes = this.constructor.utils.stringtoUTF8Array(this._rPollDesc)
this._rPollDescLength = this.constructor.utils.int32ToBytes(this._rPollDescBytes.length)
}
set rOptions(rOptions) {
const optionsArray = rOptions[0].split(', ').map(opt => opt.trim())
this._pollOptions = optionsArray
for (let i = 0; i < optionsArray.length; i++) {
this.addOption(optionsArray[i])
}
this._rNumberOfOptionsBytes = this.constructor.utils.int32ToBytes(optionsArray.length)
}
get params() {
const params = super.params
params.push(
this._ownerAddress,
this._rPollNameLength,
this._rPollNameBytes,
this._rPollDescLength,
this._rPollDescBytes,
this._rNumberOfOptionsBytes
)
// Push the dynamic options
for (let i = 0; i < this._options.length; i++) {
params.push(this._options[i].length, this._options[i].bytes)
}
params.push(this._feeBytes)
return params
}
}

View File

@ -0,0 +1,38 @@
// @ts-nocheck
import { QORT_DECIMALS } from '../constants/constants'
import TransactionBase from './TransactionBase'
export default class VoteOnPollTransaction extends TransactionBase {
constructor() {
super()
this.type = 9
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set rPollName(rPollName) {
this._rPollName = rPollName
this._rPollNameBytes = this.constructor.utils.stringtoUTF8Array(this._rPollName)
this._rPollNameLength = this.constructor.utils.int32ToBytes(this._rPollNameBytes.length)
}
set rOptionIndex(rOptionIndex) {
this._rOptionIndex = rOptionIndex
this._rOptionIndexBytes = this.constructor.utils.int32ToBytes(this._rOptionIndex)
}
get params() {
const params = super.params
params.push(
this._rPollNameLength,
this._rPollNameBytes,
this._rOptionIndexBytes,
this._feeBytes
)
return params
}
}

View File

@ -14,11 +14,15 @@ import JoinGroupTransaction from './JoinGroupTransaction.js'
import AddGroupAdminTransaction from './AddGroupAdminTransaction.js'
import RemoveGroupAdminTransaction from './RemoveGroupAdminTransaction.js'
import RegisterNameTransaction from './RegisterNameTransaction.js'
import VoteOnPollTransaction from './VoteOnPollTransaction.js'
import CreatePollTransaction from './CreatePollTransaction.js'
export const transactionTypes = {
3: RegisterNameTransaction,
2: PaymentTransaction,
8: CreatePollTransaction,
9: VoteOnPollTransaction,
18: ChatTransaction,
181: GroupChatTransaction,
22: CreateGroupTransaction,