added create poll and vote qortalrequest actions
This commit is contained in:
parent
3bf9fbd7d1
commit
247f35de66
@ -1014,7 +1014,13 @@
|
|||||||
"rewarddialog6": "On pressing confirm, the rewardshare will be removed and the minting key will become invalid.",
|
"rewarddialog6": "On pressing confirm, the rewardshare will be removed and the minting key will become invalid.",
|
||||||
"deployAtdialog1": "You are deploying the AT",
|
"deployAtdialog1": "You are deploying the AT",
|
||||||
"deployAtdialog2": "On pressing confirm, the AT will be deployed!",
|
"deployAtdialog2": "On pressing confirm, the AT will be deployed!",
|
||||||
"deployAtdialog3": "Initial amount balance"
|
"deployAtdialog3": "Initial amount balance",
|
||||||
|
"votedialog1": "You are requesting to vote on the poll below:",
|
||||||
|
"votedialog2": "On pressing confirm, the vote request will be sent!",
|
||||||
|
"votedialog3": "You are requesting to create the poll below:",
|
||||||
|
"votedialog4": "Poll Description",
|
||||||
|
"votedialog5": "Options",
|
||||||
|
"votedialog6": "On pressing confirm, the poll will be created!"
|
||||||
},
|
},
|
||||||
"sponsorshipspage": {
|
"sponsorshipspage": {
|
||||||
"schange1": "Active Sponsorships",
|
"schange1": "Active Sponsorships",
|
||||||
|
103
crypto/api/transactions/polls/CreatePollTransaction.js
Normal file
103
crypto/api/transactions/polls/CreatePollTransaction.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
'use strict'
|
||||||
|
import TransactionBase from '../TransactionBase.js'
|
||||||
|
import { QORT_DECIMALS } from '../../constants.js'
|
||||||
|
|
||||||
|
export default class CreatePollTransaction extends TransactionBase {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.type = 8
|
||||||
|
this._options = []
|
||||||
|
}
|
||||||
|
|
||||||
|
render(html) {
|
||||||
|
return html`
|
||||||
|
${this._votedialog3}
|
||||||
|
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
|
||||||
|
<span style="color: #000;">${this._rPollName}</span>
|
||||||
|
</div>
|
||||||
|
${this._votedialog4}
|
||||||
|
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
|
||||||
|
<span style="color: #000;">${this._rPollDesc}</span>
|
||||||
|
</div>
|
||||||
|
${this._votedialog5}
|
||||||
|
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
|
||||||
|
<span style="color: #000;">${this._pollOptions.join(', ')}</span>
|
||||||
|
</div>
|
||||||
|
${this._votedialog6}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
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 votedialog3(votedialog3) {
|
||||||
|
this._votedialog3 = votedialog3
|
||||||
|
}
|
||||||
|
|
||||||
|
set votedialog4(votedialog4) {
|
||||||
|
this._votedialog4 = votedialog4
|
||||||
|
}
|
||||||
|
set votedialog5(votedialog5) {
|
||||||
|
this._votedialog5 = votedialog5
|
||||||
|
}
|
||||||
|
set votedialog6(votedialog6) {
|
||||||
|
this._votedialog6 = votedialog6
|
||||||
|
}
|
||||||
|
|
||||||
|
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.toLocaleLowerCase())
|
||||||
|
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
|
||||||
|
console.log('this._options', this._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
|
||||||
|
}
|
||||||
|
}
|
57
crypto/api/transactions/polls/VoteOnPollTransaction.js
Normal file
57
crypto/api/transactions/polls/VoteOnPollTransaction.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
'use strict'
|
||||||
|
import TransactionBase from '../TransactionBase.js'
|
||||||
|
import { QORT_DECIMALS } from '../../constants.js'
|
||||||
|
|
||||||
|
export default class VoteOnPollTransaction extends TransactionBase {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.type = 9
|
||||||
|
}
|
||||||
|
|
||||||
|
render(html) {
|
||||||
|
return html`
|
||||||
|
${this._votedialog1}
|
||||||
|
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
|
||||||
|
<span style="color: #000;">${this._rPollName}</span>
|
||||||
|
</div>
|
||||||
|
${this._votedialog2}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
set votedialog1(votedialog1) {
|
||||||
|
this._votedialog1 = votedialog1
|
||||||
|
}
|
||||||
|
|
||||||
|
set votedialog2(votedialog2) {
|
||||||
|
this._votedialog2 = votedialog2
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,8 @@ import RewardShareTransaction from './reward-share/RewardShareTransaction.js'
|
|||||||
import RemoveRewardShareTransaction from './reward-share/RemoveRewardShareTransaction.js'
|
import RemoveRewardShareTransaction from './reward-share/RemoveRewardShareTransaction.js'
|
||||||
import TransferPrivsTransaction from './TransferPrivsTransaction.js'
|
import TransferPrivsTransaction from './TransferPrivsTransaction.js'
|
||||||
import DeployAtTransaction from './DeployAtTransaction.js'
|
import DeployAtTransaction from './DeployAtTransaction.js'
|
||||||
|
import VoteOnPollTransaction from './polls/VoteOnPollTransaction.js'
|
||||||
|
import CreatePollTransaction from './polls/CreatePollTransaction.js'
|
||||||
|
|
||||||
export const transactionTypes = {
|
export const transactionTypes = {
|
||||||
2: PaymentTransaction,
|
2: PaymentTransaction,
|
||||||
@ -31,6 +33,8 @@ export const transactionTypes = {
|
|||||||
5: SellNameTransacion,
|
5: SellNameTransacion,
|
||||||
6: CancelSellNameTransacion,
|
6: CancelSellNameTransacion,
|
||||||
7: BuyNameTransacion,
|
7: BuyNameTransacion,
|
||||||
|
8: CreatePollTransaction,
|
||||||
|
9: VoteOnPollTransaction,
|
||||||
16: DeployAtTransaction,
|
16: DeployAtTransaction,
|
||||||
17: MessageTransaction,
|
17: MessageTransaction,
|
||||||
18: ChatTransaction,
|
18: ChatTransaction,
|
||||||
|
@ -60,3 +60,9 @@ export const NOTIFICATIONS_PERMISSION = 'NOTIFICATIONS_PERMISSION'
|
|||||||
|
|
||||||
//SEND_LOCAL_NOTIFICATION
|
//SEND_LOCAL_NOTIFICATION
|
||||||
export const SEND_LOCAL_NOTIFICATION = 'SEND_LOCAL_NOTIFICATION'
|
export const SEND_LOCAL_NOTIFICATION = 'SEND_LOCAL_NOTIFICATION'
|
||||||
|
|
||||||
|
//VOTE_ON_POLL
|
||||||
|
export const VOTE_ON_POLL= 'VOTE_ON_POLL'
|
||||||
|
|
||||||
|
//CREATE_POLL
|
||||||
|
export const CREATE_POLL= 'CREATE_POLL'
|
File diff suppressed because one or more lines are too long
@ -496,6 +496,33 @@ class WebBrowser extends LitElement {
|
|||||||
return qortFee
|
return qortFee
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async unitVoteFee() {
|
||||||
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||||
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
|
const url = `${nodeUrl}/transactions/unitfee?txType=VOTE_ON_POLL`
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Error when fetching vote fee');
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json()
|
||||||
|
const joinFee = (Number(data) / 1e8).toFixed(8)
|
||||||
|
return joinFee
|
||||||
|
}
|
||||||
|
async unitCreatePollFee() {
|
||||||
|
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
||||||
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
|
const url = `${nodeUrl}/transactions/unitfee?txType=CREATE_POLL`
|
||||||
|
const response = await fetch(url)
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Error when fetching vote fee');
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json()
|
||||||
|
const joinFee = (Number(data) / 1e8).toFixed(8)
|
||||||
|
return joinFee
|
||||||
|
}
|
||||||
|
|
||||||
async _joinGroup(groupId, groupName) {
|
async _joinGroup(groupId, groupName) {
|
||||||
const joinFeeInput = await this.unitJoinFee()
|
const joinFeeInput = await this.unitJoinFee()
|
||||||
const getLastRef = async () => {
|
const getLastRef = async () => {
|
||||||
@ -610,6 +637,118 @@ class WebBrowser extends LitElement {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _voteOnPoll(pollName, optionIndex) {
|
||||||
|
const voteFeeInput = await this.unitVoteFee()
|
||||||
|
const getLastRef = async () => {
|
||||||
|
let myRef = await parentEpml.request('apiCall', {
|
||||||
|
type: 'api',
|
||||||
|
url: `/addresses/lastreference/${this.selectedAddress.address}`
|
||||||
|
})
|
||||||
|
return myRef
|
||||||
|
};
|
||||||
|
|
||||||
|
const validateReceiver = async () => {
|
||||||
|
let lastRef = await getLastRef();
|
||||||
|
let myTransaction = await makeTransactionRequest(lastRef)
|
||||||
|
const res = getTxnRequestResponse(myTransaction)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
const makeTransactionRequest = async (lastRef) => {
|
||||||
|
let votedialog1 = get("transactions.votedialog1")
|
||||||
|
let votedialog2 = get("transactions.votedialog2")
|
||||||
|
|
||||||
|
let myTxnrequest = await parentEpml.request('transaction', {
|
||||||
|
type: 9,
|
||||||
|
nonce: this.selectedAddress.nonce,
|
||||||
|
params: {
|
||||||
|
fee: voteFeeInput,
|
||||||
|
voterAddress: this.selectedAddress.address,
|
||||||
|
rPollName: pollName,
|
||||||
|
rOptionIndex: optionIndex,
|
||||||
|
lastReference: lastRef,
|
||||||
|
votedialog1: votedialog1,
|
||||||
|
votedialog2: votedialog2
|
||||||
|
},
|
||||||
|
apiVersion: 2
|
||||||
|
})
|
||||||
|
return myTxnrequest
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTxnRequestResponse = (txnResponse) => {
|
||||||
|
if (txnResponse.success === false && txnResponse.message) {
|
||||||
|
throw new Error(txnResponse.message)
|
||||||
|
} else if (txnResponse.success === true && !txnResponse.data.error) {
|
||||||
|
return txnResponse.data
|
||||||
|
} else if (txnResponse.data && txnResponse.data.message) {
|
||||||
|
throw new Error(txnResponse.data.message)
|
||||||
|
} else {
|
||||||
|
throw new Error('Server error. Could not perform action.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const voteRes = await validateReceiver()
|
||||||
|
return voteRes
|
||||||
|
|
||||||
|
}
|
||||||
|
async _createPoll(pollName, pollDescription, options, pollOwnerAddress) {
|
||||||
|
const voteFeeInput = await this.unitCreatePollFee()
|
||||||
|
const getLastRef = async () => {
|
||||||
|
let myRef = await parentEpml.request('apiCall', {
|
||||||
|
type: 'api',
|
||||||
|
url: `/addresses/lastreference/${this.selectedAddress.address}`
|
||||||
|
})
|
||||||
|
return myRef
|
||||||
|
};
|
||||||
|
|
||||||
|
const validateReceiver = async () => {
|
||||||
|
let lastRef = await getLastRef();
|
||||||
|
let myTransaction = await makeTransactionRequest(lastRef)
|
||||||
|
const res = getTxnRequestResponse(myTransaction)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
const makeTransactionRequest = async (lastRef) => {
|
||||||
|
let votedialog3 = get("transactions.votedialog3")
|
||||||
|
let votedialog4 = get("transactions.votedialog4")
|
||||||
|
let votedialog5 = get("transactions.votedialog5")
|
||||||
|
let votedialog6 = get("transactions.votedialog6")
|
||||||
|
|
||||||
|
let myTxnrequest = await parentEpml.request('transaction', {
|
||||||
|
type: 8,
|
||||||
|
nonce: this.selectedAddress.nonce,
|
||||||
|
params: {
|
||||||
|
fee: voteFeeInput,
|
||||||
|
ownerAddress: pollOwnerAddress,
|
||||||
|
rPollName: pollName,
|
||||||
|
rPollDesc: pollDescription,
|
||||||
|
rOptions: options,
|
||||||
|
lastReference: lastRef,
|
||||||
|
votedialog3: votedialog3,
|
||||||
|
votedialog4: votedialog4,
|
||||||
|
votedialog5: votedialog5,
|
||||||
|
votedialog6: votedialog6,
|
||||||
|
},
|
||||||
|
apiVersion: 2
|
||||||
|
})
|
||||||
|
return myTxnrequest
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTxnRequestResponse = (txnResponse) => {
|
||||||
|
if (txnResponse.success === false && txnResponse.message) {
|
||||||
|
throw new Error(txnResponse.message)
|
||||||
|
} else if (txnResponse.success === true && !txnResponse.data.error) {
|
||||||
|
return txnResponse.data
|
||||||
|
} else if (txnResponse.data && txnResponse.data.message) {
|
||||||
|
throw new Error(txnResponse.data.message)
|
||||||
|
} else {
|
||||||
|
throw new Error('Server error. Could not perform action.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const voteRes = await validateReceiver()
|
||||||
|
return voteRes
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
this.changeTheme();
|
this.changeTheme();
|
||||||
this.changeLanguage();
|
this.changeLanguage();
|
||||||
@ -1324,6 +1463,103 @@ class WebBrowser extends LitElement {
|
|||||||
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
// If they decline, send back JSON that includes an `error` key, such as `{"error": "User declined request"}`
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case actions.VOTE_ON_POLL: {
|
||||||
|
const requiredFields = ['pollName', 'optionIndex'];
|
||||||
|
const missingFields = [];
|
||||||
|
|
||||||
|
requiredFields.forEach((field) => {
|
||||||
|
if (!data[field]) {
|
||||||
|
missingFields.push(field);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (missingFields.length > 0) {
|
||||||
|
const missingFieldsString = missingFields.join(', ');
|
||||||
|
const errorMsg = `Missing fields: ${missingFieldsString}`
|
||||||
|
let data = {};
|
||||||
|
data['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(data);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const pollName = data.pollName;
|
||||||
|
const optionIndex = data.optionIndex;
|
||||||
|
|
||||||
|
|
||||||
|
let pollInfo = null
|
||||||
|
try {
|
||||||
|
pollInfo = await parentEpml.request("apiCall", {
|
||||||
|
type: "api",
|
||||||
|
url: `/polls/${pollName}`,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
const errorMsg = (error && error.message) || 'Poll not found';
|
||||||
|
let obj = {};
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pollInfo || pollInfo.error) {
|
||||||
|
const errorMsg = (pollInfo && pollInfo.message) || 'Poll not found';
|
||||||
|
let obj = {};
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.loader.show();
|
||||||
|
const resVoteOnPoll = await this._voteOnPoll(pollName, optionIndex)
|
||||||
|
response = JSON.stringify(resVoteOnPoll);
|
||||||
|
} catch (error) {
|
||||||
|
const obj = {};
|
||||||
|
const errorMsg = error.message || 'Failed to vote on the poll.';
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
} finally {
|
||||||
|
this.loader.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case actions.CREATE_POLL: {
|
||||||
|
const requiredFields = ['pollName', 'pollDescription', 'pollOptions', 'pollOwnerAddress'];
|
||||||
|
const missingFields = [];
|
||||||
|
|
||||||
|
requiredFields.forEach((field) => {
|
||||||
|
if (!data[field]) {
|
||||||
|
missingFields.push(field);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (missingFields.length > 0) {
|
||||||
|
const missingFieldsString = missingFields.join(', ');
|
||||||
|
const errorMsg = `Missing fields: ${missingFieldsString}`
|
||||||
|
let data = {};
|
||||||
|
data['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(data);
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const pollName = data.pollName;
|
||||||
|
const pollDescription = data.pollDescription
|
||||||
|
const pollOptions = data.pollOptions
|
||||||
|
const pollOwnerAddress = data.pollOwnerAddress
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.loader.show();
|
||||||
|
const resCreatePoll = await this._createPoll(pollName, pollDescription, pollOptions, pollOwnerAddress)
|
||||||
|
response = JSON.stringify(resCreatePoll);
|
||||||
|
} catch (error) {
|
||||||
|
const obj = {};
|
||||||
|
const errorMsg = error.message || 'Failed to created poll.';
|
||||||
|
obj['error'] = errorMsg;
|
||||||
|
response = JSON.stringify(obj);
|
||||||
|
} finally {
|
||||||
|
this.loader.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case actions.OPEN_NEW_TAB: {
|
case actions.OPEN_NEW_TAB: {
|
||||||
if(!data.qortalLink){
|
if(!data.qortalLink){
|
||||||
const obj = {};
|
const obj = {};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user