mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-11-16 21:07:07 +00:00
added get account groups and group members messages
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
handleAddressGroupInvitesMessage,
|
||||
handleGroupBansMessage,
|
||||
handleGroupJoinRequestsMessage,
|
||||
handleGroupMembersMessage,
|
||||
handleGroupsMessage,
|
||||
handleLastReference,
|
||||
handleNamesMessage,
|
||||
@@ -18,12 +19,14 @@ import { getRandomClient } from '../peerService';
|
||||
import { MessageType } from '../protocol/messageTypes';
|
||||
import {
|
||||
createGetAccountBalancePayload,
|
||||
createGetAccountGroupsPayload,
|
||||
createGetAccountMessagePayload,
|
||||
createGetAddressGroupInvitesPayload,
|
||||
createGetAddressNamesPayload,
|
||||
createGetBansPayload,
|
||||
createGetGroupInvitesPayload,
|
||||
createGetGroupJoinRequestsPayload,
|
||||
createGetGroupMembersPayload,
|
||||
createGetGroupPayload,
|
||||
createGetGroupsPayload,
|
||||
createGetLastReferencePayload,
|
||||
@@ -73,7 +76,25 @@ export async function getGroups(
|
||||
createGetGroupsPayload(limit, offset, reverse)
|
||||
);
|
||||
|
||||
return handleGroupsMessage(res);
|
||||
return handleGroupsMessage(res, false);
|
||||
}
|
||||
|
||||
export async function getGroupMembers(
|
||||
groupId: number,
|
||||
onlyAdmins: boolean,
|
||||
limit: number,
|
||||
offset: number,
|
||||
reverse: boolean
|
||||
): Promise<any> {
|
||||
const client = getRandomClient();
|
||||
if (!client) throw new Error('No available peers');
|
||||
|
||||
const res: Buffer = await client.sendRequest(
|
||||
MessageType.GET_GROUP_MEMBERS,
|
||||
createGetGroupMembersPayload(groupId, onlyAdmins, limit, offset, reverse)
|
||||
);
|
||||
|
||||
return handleGroupMembersMessage(res);
|
||||
}
|
||||
|
||||
export async function getGroup(groupId: number): Promise<any> {
|
||||
@@ -85,7 +106,7 @@ export async function getGroup(groupId: number): Promise<any> {
|
||||
createGetGroupPayload(groupId)
|
||||
);
|
||||
|
||||
const data = handleGroupsMessage(res);
|
||||
const data = handleGroupsMessage(res, false);
|
||||
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
return data[0];
|
||||
@@ -120,6 +141,18 @@ export async function getAddressGroupInvites(address: string): Promise<any> {
|
||||
return handleAddressGroupInvitesMessage(res);
|
||||
}
|
||||
|
||||
export async function getAccountGroups(address: string): Promise<any> {
|
||||
const client = getRandomClient();
|
||||
if (!client) throw new Error('No available peers');
|
||||
|
||||
const res: Buffer = await client.sendRequest(
|
||||
MessageType.GET_ACCOUNT_GROUPS,
|
||||
createGetAccountGroupsPayload(address)
|
||||
);
|
||||
|
||||
return handleGroupsMessage(res, true);
|
||||
}
|
||||
|
||||
export async function getGroupInvites(groupId: number): Promise<any> {
|
||||
const client = getRandomClient();
|
||||
if (!client) throw new Error('No available peers');
|
||||
|
||||
@@ -4,11 +4,13 @@ import { WebSocketServer } from 'ws';
|
||||
import {
|
||||
getAccount,
|
||||
getAccountBalance,
|
||||
getAccountGroups,
|
||||
getAddressGroupInvites,
|
||||
getBans,
|
||||
getGroup,
|
||||
getGroupInvites,
|
||||
getGroupJoinRequests,
|
||||
getGroupMembers,
|
||||
getGroups,
|
||||
getLastReference,
|
||||
getNameInfo,
|
||||
@@ -83,9 +85,9 @@ export async function createHttpServer() {
|
||||
|
||||
app.get('/groups', async (req, res) => {
|
||||
try {
|
||||
const limit = req.query.limit || 100;
|
||||
const offset = req.query.offset || 0;
|
||||
const reverse = req.query.reverse || false;
|
||||
const limit = req.query.limit ?? 100;
|
||||
const offset = req.query.offset ?? 0;
|
||||
const reverse = req.query.reverse ?? false;
|
||||
|
||||
const groups = await getGroups(limit, offset, reverse);
|
||||
res.json(groups);
|
||||
@@ -135,6 +137,36 @@ export async function createHttpServer() {
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/groups/member/:address', async (req, res) => {
|
||||
const address = req.params.address;
|
||||
try {
|
||||
const groups = await getAccountGroups(address);
|
||||
res.json(groups);
|
||||
} catch (err: any) {
|
||||
res.status(500).type('text').send(`Error: ${err.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/groups/members/:groupId', async (req, res) => {
|
||||
const groupId = req.params.groupId;
|
||||
const onlyAdmins = req.query.onlyAdmins ?? false;
|
||||
const limit = req.query.limit ?? 100;
|
||||
const offset = req.query.offset ?? 0;
|
||||
const reverse = req.query.reverse ?? false;
|
||||
try {
|
||||
const members = await getGroupMembers(
|
||||
groupId,
|
||||
onlyAdmins,
|
||||
limit,
|
||||
offset,
|
||||
reverse
|
||||
);
|
||||
res.json(members);
|
||||
} catch (err: any) {
|
||||
res.status(500).type('text').send(`Error: ${err.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/groups/joinrequests/:groupId', async (req, res) => {
|
||||
const groupId = req.params.groupId;
|
||||
try {
|
||||
|
||||
@@ -347,7 +347,7 @@ export function handleUnitFee(payload: Buffer): bigint {
|
||||
return unitFee;
|
||||
}
|
||||
|
||||
export function handleGroupsMessage(buffer) {
|
||||
export function handleGroupsMessage(buffer, includeAdmin) {
|
||||
let offset = 0;
|
||||
|
||||
const { value: count, size: countSize } = readInt(buffer, offset);
|
||||
@@ -423,14 +423,14 @@ export function handleGroupsMessage(buffer) {
|
||||
const { value: isAdminFlag, size: s12 } = readInt(buffer, offset);
|
||||
offset += s12;
|
||||
|
||||
let isAdmin = null;
|
||||
let isAdmin = false;
|
||||
if (isAdminFlag === 1) isAdmin = false;
|
||||
if (isAdminFlag === 2) isAdmin = true;
|
||||
|
||||
const { value: memberCount, size: s13 } = readInt(buffer, offset);
|
||||
offset += s13;
|
||||
|
||||
groups.push({
|
||||
const groupData: any = {
|
||||
groupId,
|
||||
owner,
|
||||
groupName,
|
||||
@@ -442,7 +442,13 @@ export function handleGroupsMessage(buffer) {
|
||||
minimumBlockDelay,
|
||||
maximumBlockDelay,
|
||||
memberCount,
|
||||
});
|
||||
};
|
||||
|
||||
if (includeAdmin) {
|
||||
groupData.isAdmin = isAdmin;
|
||||
}
|
||||
|
||||
groups.push(groupData);
|
||||
}
|
||||
|
||||
return groups;
|
||||
@@ -574,3 +580,59 @@ export function handleGroupJoinRequestsMessage(buffer) {
|
||||
|
||||
return joinRequests;
|
||||
}
|
||||
|
||||
export function handleGroupMembersMessage(buffer) {
|
||||
let offset = 0;
|
||||
|
||||
// Read memberCount
|
||||
const { value: memberCount, size: s1 } = readInt(buffer, offset);
|
||||
offset += s1;
|
||||
|
||||
// Read adminCount
|
||||
const { value: adminCount, size: s2 } = readInt(buffer, offset);
|
||||
offset += s2;
|
||||
|
||||
// Read members count
|
||||
const { value: membersCount, size: s3 } = readInt(buffer, offset);
|
||||
offset += s3;
|
||||
|
||||
const members = [];
|
||||
|
||||
for (let i = 0; i < membersCount; i++) {
|
||||
// member (25 bytes base58 address)
|
||||
const memberBytes = buffer.subarray(offset, offset + 25);
|
||||
const member = bs58.encode(memberBytes);
|
||||
offset += 25;
|
||||
|
||||
// joined (nullable long)
|
||||
const { value: hasJoined, size: s4 } = readInt(buffer, offset);
|
||||
offset += s4;
|
||||
|
||||
let joined = null;
|
||||
if (hasJoined === 1) {
|
||||
const { value: joinedValue, size: s5 } = readLong(buffer, offset);
|
||||
joined = joinedValue;
|
||||
offset += s5;
|
||||
}
|
||||
|
||||
// isAdmin (nullable flag: 0 = null, 1 = false, 2 = true)
|
||||
const { value: isAdminFlag, size: s6 } = readInt(buffer, offset);
|
||||
offset += s6;
|
||||
|
||||
let isAdmin = false;
|
||||
if (isAdminFlag === 1) isAdmin = false;
|
||||
if (isAdminFlag === 2) isAdmin = true;
|
||||
|
||||
members.push({
|
||||
member,
|
||||
joined,
|
||||
isAdmin,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
memberCount,
|
||||
adminCount,
|
||||
members,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -36,4 +36,7 @@ export enum MessageType {
|
||||
GET_GROUP_INVITES = 317,
|
||||
GROUP_JOIN_REQUESTS = 318,
|
||||
GET_GROUP_JOIN_REQUESTS = 319,
|
||||
GET_ACCOUNT_GROUPS = 320,
|
||||
GROUP_MEMBERS = 321,
|
||||
GET_GROUP_MEMBERS = 322,
|
||||
}
|
||||
|
||||
@@ -66,6 +66,17 @@ export function createGetAddressGroupInvitesPayload(address: string): Buffer {
|
||||
return Buffer.from(addressBytes); // ✅ Just raw payload
|
||||
}
|
||||
|
||||
export function createGetAccountGroupsPayload(address: string): Buffer {
|
||||
const addressBytes = bs58.decode(address);
|
||||
if (addressBytes.length !== ADDRESS_LENGTH) {
|
||||
throw new Error(
|
||||
`Invalid address length. Expected ${ADDRESS_LENGTH}, got ${addressBytes.length}`
|
||||
);
|
||||
}
|
||||
|
||||
return Buffer.from(addressBytes); // ✅ Just raw payload
|
||||
}
|
||||
|
||||
export function createProcessTransactionMessagePayload(
|
||||
signedBytes: string
|
||||
): Buffer {
|
||||
@@ -135,6 +146,37 @@ export function createGetGroupsPayload(
|
||||
return Buffer.concat([limitBuffer, offsetBuffer, reverseBuffer]);
|
||||
}
|
||||
|
||||
export function createGetGroupMembersPayload(
|
||||
groupId: number,
|
||||
onlyAdmins: boolean,
|
||||
limit: number,
|
||||
offset: number,
|
||||
reverse: boolean
|
||||
): Buffer {
|
||||
const groupIdBuffer = Buffer.alloc(4);
|
||||
groupIdBuffer.writeInt32BE(groupId);
|
||||
|
||||
const onlyAdminsBuffer = Buffer.alloc(4);
|
||||
onlyAdminsBuffer.writeInt32BE(onlyAdmins ? 1 : 0);
|
||||
|
||||
const limitBuffer = Buffer.alloc(4);
|
||||
limitBuffer.writeInt32BE(limit);
|
||||
|
||||
const offsetBuffer = Buffer.alloc(4);
|
||||
offsetBuffer.writeInt32BE(offset);
|
||||
|
||||
const reverseBuffer = Buffer.alloc(4);
|
||||
reverseBuffer.writeInt32BE(reverse ? 1 : 0);
|
||||
|
||||
return Buffer.concat([
|
||||
groupIdBuffer,
|
||||
onlyAdminsBuffer,
|
||||
limitBuffer,
|
||||
offsetBuffer,
|
||||
reverseBuffer,
|
||||
]);
|
||||
}
|
||||
|
||||
export function createGetGroupPayload(groupId: number): Buffer {
|
||||
const groupIdBuffer = Buffer.alloc(4);
|
||||
groupIdBuffer.writeInt32BE(groupId);
|
||||
|
||||
Reference in New Issue
Block a user