added kick and ban functionality - NEEDS TESTING PRIOR TO RELEASE.
This commit is contained in:
parent
320dd34117
commit
040d3fa184
@ -575,6 +575,7 @@ const validateMinterName = async(minterName) => {
|
|||||||
return name
|
return name
|
||||||
} catch (error){
|
} catch (error){
|
||||||
console.error(`extracting name from name info: ${minterName} failed.`, error)
|
console.error(`extracting name from name info: ${minterName} failed.`, error)
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,39 +772,6 @@ const fetchEncryptedComments = async (cardIdentifier) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// display the comments on the card, with passed cardIdentifier to identify the card --------------
|
|
||||||
// const displayEncryptedComments = async (cardIdentifier) => {
|
|
||||||
// try {
|
|
||||||
// const comments = await fetchEncryptedComments(cardIdentifier)
|
|
||||||
// const commentsContainer = document.getElementById(`comments-container-${cardIdentifier}`)
|
|
||||||
|
|
||||||
// for (const comment of comments) {
|
|
||||||
// const commentDataResponse = await qortalRequest({
|
|
||||||
// action: "FETCH_QDN_RESOURCE",
|
|
||||||
// name: comment.name,
|
|
||||||
// service: "MAIL_PRIVATE",
|
|
||||||
// identifier: comment.identifier,
|
|
||||||
// encoding: "base64"
|
|
||||||
// })
|
|
||||||
|
|
||||||
// const decryptedCommentData = await decryptAndParseObject(commentDataResponse)
|
|
||||||
// const timestampCheck = comment.updated || comment.created || 0
|
|
||||||
// const timestamp = await timestampToHumanReadableDate(timestampCheck)
|
|
||||||
// //TODO - add fetching of poll results and checking to see if the commenter has voted and display it as 'supports minter' section.
|
|
||||||
// const commentHTML = `
|
|
||||||
// <div class="comment" style="border: 1px solid gray; margin: 1vh 0; padding: 1vh; background: #1c1c1c;">
|
|
||||||
// <p><strong><u>${decryptedCommentData.creator}</strong>:</p></u>
|
|
||||||
// <p>${decryptedCommentData.content}</p>
|
|
||||||
// <p><i>${timestamp}</p></i>
|
|
||||||
// </div>
|
|
||||||
// `
|
|
||||||
// commentsContainer.insertAdjacentHTML('beforeend', commentHTML)
|
|
||||||
// }
|
|
||||||
// } catch (error) {
|
|
||||||
// console.error(`Error displaying comments (or no comments) for ${cardIdentifier}:`, error)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//TODO testing this update to the comments fetching to improve performance by leveraging promise.all
|
|
||||||
const displayEncryptedComments = async (cardIdentifier) => {
|
const displayEncryptedComments = async (cardIdentifier) => {
|
||||||
try {
|
try {
|
||||||
const comments = await fetchEncryptedComments(cardIdentifier)
|
const comments = await fetchEncryptedComments(cardIdentifier)
|
||||||
@ -943,23 +911,129 @@ const processQortalLinkForRendering = async (link) => {
|
|||||||
return link
|
return link
|
||||||
}
|
}
|
||||||
|
|
||||||
const getMinterAvatar = async (minterName) => {
|
const checkAndDisplayRemoveActions = async (adminYes, creator, cardIdentifier) => {
|
||||||
const avatarUrl = `/arbitrary/THUMBNAIL/${minterName}/qortal_avatar`
|
const latestBlockInfo = await getLatestBlockInfo()
|
||||||
try {
|
const isBlockPassed = latestBlockInfo.height >= GROUP_APPROVAL_FEATURE_TRIGGER_HEIGHT
|
||||||
const response = await fetch(avatarUrl, { method: 'HEAD' })
|
let minAdminCount = 9
|
||||||
|
const minterAdmins = await fetchMinterGroupAdmins()
|
||||||
|
|
||||||
if (response.ok) {
|
if ((minterAdmins) && (minterAdmins.length === 1)){
|
||||||
return `<img src="${avatarUrl}" alt="User Avatar" class="user-avatar" style="width: 50px; height: 50px; border-radius: 50%; align-self: center;">`
|
console.warn(`simply a double-check that there is only one MINTER group admin, in which case the group hasn't been transferred to null...keeping default minAdminCount of: ${minAdminCount}`)
|
||||||
|
|
||||||
|
} else if ((minterAdmins) && (minterAdmins.length > 1) && isBlockPassed){
|
||||||
|
const totalAdmins = minterAdmins.length
|
||||||
|
const fortyPercent = totalAdmins * 0.40
|
||||||
|
minAdminCount = Math.round(fortyPercent)
|
||||||
|
console.warn(`this is another check to ensure minterAdmin group has more than 1 admin. IF so we will calculate the 40% needed for GROUP_APPROVAL, that number is: ${minAdminCount}`)
|
||||||
|
}
|
||||||
|
//TODO verify the above functionality to calculate 40% of MINTER group admins, and use that for minAdminCount
|
||||||
|
|
||||||
|
if (adminYes >= minAdminCount && userState.isMinterAdmin && !isBlockPassed) {
|
||||||
|
const removeButtonHtml = createRemoveButtonHtml(creator, cardIdentifier)
|
||||||
|
return removeButtonHtml
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const createRemoveButtonHtml = (name, cardIdentifier) => {
|
||||||
|
return `
|
||||||
|
<div id="remove-button-container-${cardIdentifier}" style="margin-top: 1em;">
|
||||||
|
<button onclick="handleKickMinter('${name}')"
|
||||||
|
style="padding: 10px; background: rgb(134, 80, 4); color: white; border: none; cursor: pointer; border-radius: 5px;"
|
||||||
|
onmouseover="this.style.backgroundColor='rgb(47, 28, 11) '"
|
||||||
|
onmouseout="this.style.backgroundColor='rgb(134, 80, 4) '">
|
||||||
|
KICK Minter
|
||||||
|
</button>
|
||||||
|
<button onclick="handleBanMinter('${name}')"
|
||||||
|
style="padding: 10px; background:rgb(93, 7, 7); color: white; border: none; cursor: pointer; border-radius: 5px;"
|
||||||
|
onmouseover="this.style.backgroundColor='rgb(39, 9, 9) '"
|
||||||
|
onmouseout="this.style.backgroundColor='rgb(93, 7, 7) '">
|
||||||
|
BAN Minter
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleKickMinter = async (minterName) => {
|
||||||
|
try {
|
||||||
|
// Optional block check
|
||||||
|
const { height: currentHeight } = await getLatestBlockInfo()
|
||||||
|
if (currentHeight <= GROUP_APPROVAL_FEATURE_TRIGGER_HEIGHT) {
|
||||||
|
console.log(`block height is under the removal featureTrigger height`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the minter address from name info
|
||||||
|
const minterInfo = await getNameInfo(minterName)
|
||||||
|
const minterAddress = minterInfo?.owner
|
||||||
|
if (!minterAddress) {
|
||||||
|
alert(`No valid address found for minter name: ${minterName}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// The admin public key
|
||||||
|
const adminPublicKey = await getPublicKeyByName(userState.accountName)
|
||||||
|
|
||||||
|
// Create the raw remove transaction
|
||||||
|
const rawKickTransaction = await createGroupKickTransaction(minterAddress, adminPublicKey, 694, minterAddress)
|
||||||
|
|
||||||
|
// Sign the transaction
|
||||||
|
const signedKickTransaction = await qortalRequest({
|
||||||
|
action: "SIGN_TRANSACTION",
|
||||||
|
unsignedBytes: rawKickTransaction
|
||||||
|
})
|
||||||
|
|
||||||
|
// Process the transaction
|
||||||
|
const processResponse = await processTransaction(signedKickTransaction)
|
||||||
|
|
||||||
|
if (processResponse?.status === "OK") {
|
||||||
|
alert(`${minterName}'s KICK transaction has been SUCCESSFULLY PROCESSED. Please WAIT FOR CONFIRMATION...`)
|
||||||
} else {
|
} else {
|
||||||
return ''
|
alert("Failed to process the removal transaction.")
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error checking avatar availability:', error)
|
console.error("Error removing minter:", error)
|
||||||
return ''
|
alert("Error removing minter. Please try again.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleBanMinter = async (minterName) => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const { height: currentHeight } = await getLatestBlockInfo()
|
||||||
|
if (currentHeight <= GROUP_APPROVAL_FEATURE_TRIGGER_HEIGHT) {
|
||||||
|
console.log(`block height is under the removal featureTrigger height`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const minterInfo = await getNameInfo(minterName)
|
||||||
|
const minterAddress = minterInfo?.owner
|
||||||
|
if (!minterAddress) {
|
||||||
|
alert(`No valid address found for minter name: ${minterName}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const adminPublicKey = await getPublicKeyByName(userState.accountName)
|
||||||
|
|
||||||
|
const rawBanTransaction = await createGroupBanTransaction(minterAddress, adminPublicKey, 694, minterAddress)
|
||||||
|
|
||||||
|
const signedBanTransaction = await qortalRequest({
|
||||||
|
action: "SIGN_TRANSACTION",
|
||||||
|
unsignedBytes: rawBanTransaction
|
||||||
|
})
|
||||||
|
|
||||||
|
const processResponse = await processTransaction(signedBanTransaction)
|
||||||
|
|
||||||
|
if (processResponse?.status === "OK") {
|
||||||
|
alert(`${minterName}'s BAN transaction has been SUCCESSFULLY PROCESSED. Please WAIT FOR CONFIRMATION...`)
|
||||||
|
} else {
|
||||||
|
alert("Failed to process the removal transaction.")
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error removing minter:", error)
|
||||||
|
alert("Error removing minter. Please try again.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create the overall Minter Card HTML -----------------------------------------------
|
// Create the overall Minter Card HTML -----------------------------------------------
|
||||||
const createEncryptedCardHTML = async (cardData, pollResults, cardIdentifier, commentCount) => {
|
const createEncryptedCardHTML = async (cardData, pollResults, cardIdentifier, commentCount) => {
|
||||||
@ -1001,8 +1075,21 @@ const createEncryptedCardHTML = async (cardData, pollResults, cardIdentifier, co
|
|||||||
const minterGroupMembers = await fetchMinterGroupMembers()
|
const minterGroupMembers = await fetchMinterGroupMembers()
|
||||||
const minterAdmins = await fetchMinterGroupAdmins()
|
const minterAdmins = await fetchMinterGroupAdmins()
|
||||||
const { adminYes = 0, adminNo = 0, minterYes = 0, minterNo = 0, totalYes = 0, totalNo = 0, totalYesWeight = 0, totalNoWeight = 0, detailsHtml } = await processPollData(pollResults, minterGroupMembers, minterAdmins, creator, cardIdentifier)
|
const { adminYes = 0, adminNo = 0, minterYes = 0, minterNo = 0, totalYes = 0, totalNo = 0, totalYesWeight = 0, totalNoWeight = 0, detailsHtml } = await processPollData(pollResults, minterGroupMembers, minterAdmins, creator, cardIdentifier)
|
||||||
|
|
||||||
createModal('links')
|
createModal('links')
|
||||||
createModal('poll-details')
|
createModal('poll-details')
|
||||||
|
|
||||||
|
let showRemoveHtml
|
||||||
|
const verifiedName = await validateMinterName(minterName)
|
||||||
|
if (verifiedName) {
|
||||||
|
console.log(`name is validated, utilizing for removal features...${verifiedName}`)
|
||||||
|
const removeActionsHtml = await checkAndDisplayRemoveActions(adminYes, verifiedName, cardIdentifier)
|
||||||
|
showRemoveHtml = removeActionsHtml
|
||||||
|
} else {
|
||||||
|
console.log(`name could not be validated, assuming topic card (or some other issue with name validation) for removalActions`)
|
||||||
|
showRemoveHtml = ''
|
||||||
|
}
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="admin-card" style="background-color: ${cardColorCode}">
|
<div class="admin-card" style="background-color: ${cardColorCode}">
|
||||||
<div class="minter-card-header">
|
<div class="minter-card-header">
|
||||||
@ -1025,6 +1112,7 @@ const createEncryptedCardHTML = async (cardData, pollResults, cardIdentifier, co
|
|||||||
<div id="poll-details-${cardIdentifier}" style="display: none;">
|
<div id="poll-details-${cardIdentifier}" style="display: none;">
|
||||||
${detailsHtml}
|
${detailsHtml}
|
||||||
</div>
|
</div>
|
||||||
|
${showRemoveHtml}
|
||||||
<div class="admin-results">
|
<div class="admin-results">
|
||||||
<span class="admin-yes">Admin Support: ${adminYes}</span>
|
<span class="admin-yes">Admin Support: ${adminYes}</span>
|
||||||
<span class="admin-no">Admin Against: ${adminNo}</span>
|
<span class="admin-no">Admin Against: ${adminNo}</span>
|
||||||
|
@ -5,7 +5,7 @@ let isExistingCard = false
|
|||||||
let existingCardData = {}
|
let existingCardData = {}
|
||||||
let existingCardIdentifier = {}
|
let existingCardIdentifier = {}
|
||||||
const MIN_ADMIN_YES_VOTES = 9;
|
const MIN_ADMIN_YES_VOTES = 9;
|
||||||
const MINTER_INVITE_BLOCK_HEIGHT = 9999999; // Example height, update later
|
const GROUP_APPROVAL_FEATURE_TRIGGER_HEIGHT = 99999999 //TODO update this to correct featureTrigger height when known, either that, or pull from core.
|
||||||
let isApproved = false
|
let isApproved = false
|
||||||
|
|
||||||
const loadMinterBoardPage = async () => {
|
const loadMinterBoardPage = async () => {
|
||||||
@ -999,7 +999,7 @@ const generateDarkPastelBackgroundBy = (name) => {
|
|||||||
const handleInviteMinter = async (minterName) => {
|
const handleInviteMinter = async (minterName) => {
|
||||||
try {
|
try {
|
||||||
const blockInfo = await getLatestBlockInfo()
|
const blockInfo = await getLatestBlockInfo()
|
||||||
const blockHeight = toString(blockInfo.height)
|
const blockHeight = blockInfo.height
|
||||||
if (blockHeight <= MINTER_INVITE_BLOCK_HEIGHT) {
|
if (blockHeight <= MINTER_INVITE_BLOCK_HEIGHT) {
|
||||||
console.log(`block height is under the featureTrigger height`)
|
console.log(`block height is under the featureTrigger height`)
|
||||||
}
|
}
|
||||||
@ -1020,7 +1020,7 @@ const handleInviteMinter = async (minterName) => {
|
|||||||
const processResponse = await processTransaction(signedTransaction)
|
const processResponse = await processTransaction(signedTransaction)
|
||||||
|
|
||||||
if (processResponse?.status === "OK") {
|
if (processResponse?.status === "OK") {
|
||||||
alert(`${minterName} has been successfully invited!`)
|
alert(`${minterName} has been successfully invited, please WAIT FOR CONFIRMATION...`)
|
||||||
} else {
|
} else {
|
||||||
alert("Failed to process the invite transaction.")
|
alert("Failed to process the invite transaction.")
|
||||||
}
|
}
|
||||||
@ -1046,9 +1046,9 @@ const createInviteButtonHtml = (creator, cardIdentifier) => {
|
|||||||
|
|
||||||
const checkAndDisplayInviteButton = async (adminYes, creator, cardIdentifier) => {
|
const checkAndDisplayInviteButton = async (adminYes, creator, cardIdentifier) => {
|
||||||
const latestBlockInfo = await getLatestBlockInfo()
|
const latestBlockInfo = await getLatestBlockInfo()
|
||||||
const isBlockPassed = latestBlockInfo.height > MINTER_INVITE_BLOCK_HEIGHT
|
const isBlockPassed = latestBlockInfo.height >= GROUP_APPROVAL_FEATURE_TRIGGER_HEIGHT
|
||||||
|
|
||||||
if (adminYes >= 9 && userState.isMinterAdmin) {
|
if (adminYes >= 9 && userState.isMinterAdmin && !isBlockPassed) {
|
||||||
const inviteButtonHtml = createInviteButtonHtml(creator, cardIdentifier)
|
const inviteButtonHtml = createInviteButtonHtml(creator, cardIdentifier)
|
||||||
console.log(`admin votes over 9, creating invite button...`, adminYes)
|
console.log(`admin votes over 9, creating invite button...`, adminYes)
|
||||||
return inviteButtonHtml
|
return inviteButtonHtml
|
||||||
@ -1057,6 +1057,23 @@ const checkAndDisplayInviteButton = async (adminYes, creator, cardIdentifier) =>
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getMinterAvatar = async (minterName) => {
|
||||||
|
const avatarUrl = `/arbitrary/THUMBNAIL/${minterName}/qortal_avatar`
|
||||||
|
try {
|
||||||
|
const response = await fetch(avatarUrl, { method: 'HEAD' })
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
return `<img src="${avatarUrl}" alt="User Avatar" class="user-avatar" style="width: 50px; height: 50px; border-radius: 50%; align-self: center;">`
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error checking avatar availability:', error)
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create the overall Minter Card HTML -----------------------------------------------
|
// Create the overall Minter Card HTML -----------------------------------------------
|
||||||
const createCardHTML = async (cardData, pollResults, cardIdentifier, commentCount, cardUpdatedTime, BgColor) => {
|
const createCardHTML = async (cardData, pollResults, cardIdentifier, commentCount, cardUpdatedTime, BgColor) => {
|
||||||
|
@ -1202,7 +1202,7 @@ const processTransaction = async (rawTransaction) => {
|
|||||||
|
|
||||||
// Create a group invite transaction. This will utilize a default timeToLive (which is how long the tx will be alive, not the time until it IS live...) of 10 days in seconds, as the legacy UI has a bug that doesn't display invites older than 10 days.
|
// Create a group invite transaction. This will utilize a default timeToLive (which is how long the tx will be alive, not the time until it IS live...) of 10 days in seconds, as the legacy UI has a bug that doesn't display invites older than 10 days.
|
||||||
// We will also default to the MINTER group for groupId, AFTER the GROUP_APPROVAL changes, the txGroupId will need to be set for tx that require approval.
|
// We will also default to the MINTER group for groupId, AFTER the GROUP_APPROVAL changes, the txGroupId will need to be set for tx that require approval.
|
||||||
const createGroupInviteTransaction = async (recipientAddress, adminPublicKey, groupId=694, invitee, timeToLive = 864000, txGroupId = 0) => {
|
const createGroupInviteTransaction = async (recipientAddress, adminPublicKey, groupId=694, invitee, timeToLive = 864000, txGroupId = 0, fee=0.01) => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Fetch account reference correctly
|
// Fetch account reference correctly
|
||||||
@ -1217,7 +1217,7 @@ const createGroupInviteTransaction = async (recipientAddress, adminPublicKey, gr
|
|||||||
const payload = {
|
const payload = {
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
reference: accountReference,
|
reference: accountReference,
|
||||||
fee: 0.01,
|
fee: fee || 0.01,
|
||||||
txGroupId: txGroupId,
|
txGroupId: txGroupId,
|
||||||
recipient: recipientAddress,
|
recipient: recipientAddress,
|
||||||
adminPublicKey: adminPublicKey,
|
adminPublicKey: adminPublicKey,
|
||||||
@ -1251,6 +1251,103 @@ const createGroupInviteTransaction = async (recipientAddress, adminPublicKey, gr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const createGroupKickTransaction = async (recipientAddress, adminPublicKey, groupId=694, member, reason='Kicked by admins', txGroupId = 0, fee=0.01) => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch account reference correctly
|
||||||
|
const accountInfo = await getAddressInfo(recipientAddress)
|
||||||
|
const accountReference = accountInfo.reference
|
||||||
|
|
||||||
|
// Validate inputs before making the request
|
||||||
|
if (!adminPublicKey || !accountReference || !recipientAddress) {
|
||||||
|
throw new Error("Missing required parameters for group invite transaction.")
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
reference: accountReference,
|
||||||
|
fee: fee | 0.01,
|
||||||
|
txGroupId: txGroupId,
|
||||||
|
recipient: recipientAddress,
|
||||||
|
adminPublicKey: adminPublicKey,
|
||||||
|
groupId: groupId,
|
||||||
|
member: member || recipientAddress,
|
||||||
|
reason: reason
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Sending group invite transaction payload:", payload)
|
||||||
|
|
||||||
|
const response = await fetch(`${baseUrl}/groups/kick`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'text/plain',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text()
|
||||||
|
throw new Error(`Failed to create transaction: ${response.status}, ${errorText}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawTransaction = await response.text()
|
||||||
|
console.log("Raw unsigned transaction created:", rawTransaction)
|
||||||
|
return rawTransaction
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating group invite transaction:", error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const createGroupBanTransaction = async (recipientAddress, adminPublicKey, groupId=694, offender, reason='Banned by admins', txGroupId = 0, fee=0.01) => {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Fetch account reference correctly
|
||||||
|
const accountInfo = await getAddressInfo(recipientAddress)
|
||||||
|
const accountReference = accountInfo.reference
|
||||||
|
|
||||||
|
// Validate inputs before making the request
|
||||||
|
if (!adminPublicKey || !accountReference || !recipientAddress) {
|
||||||
|
throw new Error("Missing required parameters for group invite transaction.")
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
reference: accountReference,
|
||||||
|
fee: fee | 0.01,
|
||||||
|
txGroupId: txGroupId,
|
||||||
|
recipient: recipientAddress,
|
||||||
|
adminPublicKey: adminPublicKey,
|
||||||
|
groupId: groupId,
|
||||||
|
offender: offender || recipientAddress,
|
||||||
|
reason: reason
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Sending group invite transaction payload:", payload)
|
||||||
|
|
||||||
|
const response = await fetch(`${baseUrl}/groups/kick`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'text/plain',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorText = await response.text()
|
||||||
|
throw new Error(`Failed to create transaction: ${response.status}, ${errorText}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const rawTransaction = await response.text()
|
||||||
|
console.log("Raw unsigned transaction created:", rawTransaction)
|
||||||
|
return rawTransaction
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error creating group invite transaction:", error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const getLatestBlockInfo = async () => {
|
const getLatestBlockInfo = async () => {
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user