Hive MCP Server
by gluneau
Verified
- src
- tools
// Cryptography tools implementation
import { PrivateKey, PublicKey, Signature, cryptoUtils } from '@hiveio/dhive';
import config from '../config';
import { Response } from '../utils/response';
import { handleError } from '../utils/error';
import { successJson, errorResponse } from '../utils/response';
// Sign a message using a private key
export async function signMessage(
params: {
message: string;
key_type: 'posting' | 'active' | 'memo' | 'owner';
}
): Promise<Response> {
try {
// Get the private key from environment variables
let keyEnvVar: string | undefined;
switch (params.key_type) {
case 'posting':
keyEnvVar = config.hive.postingKey;
break;
case 'active':
keyEnvVar = config.hive.activeKey;
break;
case 'memo':
keyEnvVar = config.hive.memoKey;
break;
case 'owner':
keyEnvVar = config.hive.ownerKey;
break;
default:
return errorResponse(`Error: Invalid key_type: ${params.key_type}`);
}
// Check if the key is available
if (!keyEnvVar) {
return errorResponse(`Error: HIVE_${params.key_type.toUpperCase()}_KEY environment variable is not set`);
}
// Create PrivateKey object
let privateKey: PrivateKey;
try {
privateKey = PrivateKey.fromString(keyEnvVar);
} catch (error) {
return errorResponse(`Error: Invalid ${params.key_type} key format`);
}
// Hash the message with sha256 before signing
const messageHash = cryptoUtils.sha256(params.message);
// Sign the message hash
let signature: string;
try {
signature = privateKey.sign(messageHash).toString();
} catch (error) {
return errorResponse(`Error signing message: ${error instanceof Error ? error.message : String(error)}`);
}
// Get the public key
const publicKey = privateKey.createPublic().toString();
return successJson({
success: true,
message_hash: messageHash.toString('hex'),
signature,
public_key: publicKey,
});
} catch (error) {
return errorResponse(handleError(error, 'sign_message'));
}
}
// Verify a message signature
export async function verifySignature(
params: {
message_hash: string;
signature: string;
public_key: string;
}
): Promise<Response> {
try {
// Parse the public key (handling keys with or without the STM prefix)
let publicKey;
try {
publicKey = params.public_key.startsWith('STM')
? params.public_key
: `STM${params.public_key}`;
publicKey = PublicKey.fromString(publicKey);
} catch (error) {
return errorResponse('Error: Invalid public key format');
}
// Parse the signature
let signatureObj;
try {
signatureObj = Signature.fromString(params.signature);
} catch (error) {
return errorResponse('Error: Invalid signature format');
}
// Validate and parse the message hash
let messageHashBuffer;
try {
if (!/^[0-9a-fA-F]{64}$/.test(params.message_hash)) {
throw new Error('Message hash must be a 64-character hex string');
}
messageHashBuffer = Buffer.from(params.message_hash, 'hex');
} catch (error) {
return errorResponse('Error: Invalid message hash format - must be a 64-character hex string');
}
// Verify the signature against the hash
const isValid = publicKey.verify(messageHashBuffer, signatureObj);
return successJson({
success: true,
is_valid: isValid,
message_hash: params.message_hash,
public_key: publicKey.toString(),
});
} catch (error) {
return errorResponse(handleError(error, 'verify_signature'));
}
}