/**
* DAT Tools Local Test Script
*
* Tests all DAT (Data Anchoring Token) tools against the local MCP server.
*
* Usage:
* npx tsx test-dat-local.ts
*
* Prerequisites:
* 1. Start the MCP server: npx smithery dev
* 2. Set PRIVATE_KEY environment variable or edit the script
* 3. Ensure wallet has LazAI testnet funds from https://faucet.lazai.network/
*/
const SERVER_URL = 'http://localhost:8081/mcp';
const PRIVATE_KEY = process.env.PRIVATE_KEY || 'YOUR_PRIVATE_KEY_HERE';
const TEST_FILE_URL = `https://example.com/test-dat-${Date.now()}.json`;
const EXISTING_FILE_ID = process.env.FILE_ID || '2678'; // Use existing file ID for testing
const WALLET_ADDRESS = '0x0E17561FEd60D7966Ab9d22A32D7B01dB9F02818';
let sessionId: string | null = null;
let fileId: string | null = null;
let walletAddress: string | null = null;
// Helper to make MCP requests
async function mcpRequest(method: string, params: any = {}, id = 1): Promise<any> {
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'Accept': 'application/json, text/event-stream',
};
if (sessionId) {
headers['mcp-session-id'] = sessionId;
}
const response = await fetch(SERVER_URL, {
method: 'POST',
headers,
body: JSON.stringify({
jsonrpc: '2.0',
method,
params,
id,
}),
});
// Capture session ID from response headers
const newSessionId = response.headers.get('mcp-session-id');
if (newSessionId) {
sessionId = newSessionId;
}
const text = await response.text();
// Handle SSE format
if (text.includes('event:')) {
const lines = text.split('\n');
for (const line of lines) {
if (line.startsWith('data:')) {
try {
return JSON.parse(line.slice(5));
} catch {
continue;
}
}
}
}
return JSON.parse(text);
}
// Helper to call a tool
async function callTool(name: string, args: Record<string, any> = {}): Promise<any> {
return mcpRequest('tools/call', { name, arguments: args });
}
// Test functions
async function test(name: string, fn: () => Promise<void>) {
try {
await fn();
console.log(`â
${name}`);
} catch (error) {
console.log(`â ${name}: ${error instanceof Error ? error.message : error}`);
}
}
async function runTests() {
console.log('\nđ§Ş DAT Tools Local Test Suite\n');
console.log(`Server: ${SERVER_URL}`);
console.log(`Test File URL: ${TEST_FILE_URL}\n`);
console.log('â'.repeat(60) + '\n');
// 1. Initialize session
await test('Initialize Session', async () => {
const result = await mcpRequest('initialize', {
protocolVersion: '2024-11-05',
capabilities: {},
clientInfo: { name: 'dat-test', version: '1.0' },
});
if (!sessionId) throw new Error('No session ID received');
console.log(` Session: ${sessionId}`);
});
// 2. Import wallet
await test('Import Wallet', async () => {
if (PRIVATE_KEY === 'YOUR_PRIVATE_KEY_HERE') {
throw new Error('Set PRIVATE_KEY environment variable');
}
const result = await callTool('import_wallet', {
privateKey: PRIVATE_KEY,
name: 'DATTest'
});
const text = result?.result?.content?.[0]?.text || '';
if (text.includes('Error')) throw new Error(text);
// Extract wallet address from response
const addrMatch = text.match(/Address:\s*(0x[a-fA-F0-9]+)/);
if (addrMatch) walletAddress = addrMatch[1];
console.log(` ${text.split('\n')[0]}`);
});
// 3. Get DAT Contract
await test('Get DAT Contract', async () => {
const result = await callTool('get_dat_contract', {});
const text = result?.result?.content?.[0]?.text || '';
if (text.includes('Error')) throw new Error(text);
console.log(` ${text.split('\n').find((l: string) => l.includes('Address')) || text.slice(0, 80)}`);
});
// 4. Register DAT File (or use existing)
await test('Register DAT File', async () => {
const result = await callTool('register_dat_file', { url: TEST_FILE_URL });
const text = result?.result?.content?.[0]?.text || '';
if (text.includes('Error')) {
// If registration fails, use existing file ID for subsequent tests
console.log(` â ď¸ Registration failed, using existing File ID: ${EXISTING_FILE_ID}`);
fileId = EXISTING_FILE_ID;
return;
}
const match = text.match(/File ID:\s*(\d+)/);
if (match) fileId = match[1];
console.log(` File ID: ${fileId}`);
});
// 5. Get DAT File Info (use existing file if no new one)
await test('Get DAT File Info', async () => {
const testFileId = fileId || EXISTING_FILE_ID;
const result = await callTool('get_dat_file_info', { fileId: testFileId });
const text = result?.result?.content?.[0]?.text || '';
if (text.includes('Error') && !text.includes('File ID')) throw new Error(text);
console.log(` ${text.split('\n').find((l: string) => l.includes('URL')) || 'OK'}`);
// Extract proofs count
const proofsMatch = text.match(/Proofs:\s*(\d+)/);
if (proofsMatch) console.log(` Proofs: ${proofsMatch[1]}`);
});
// 6. Request DAT Proof
await test('Request DAT Proof', async () => {
const testFileId = fileId || EXISTING_FILE_ID;
const result = await callTool('request_dat_proof', { fileId: testFileId });
const text = result?.result?.content?.[0]?.text || '';
if (text.includes('reverted')) {
// Proof might already be pending for this file
console.log(` â ď¸ Proof already requested (or requires more gas)`);
} else if (text.includes('Error')) {
throw new Error(text);
} else {
console.log(` ${text.split('\n').find((l: string) => l.includes('Job ID')) || 'Submitted'}`);
}
});
// 7. Get DAT Balance (requires account + tokenId)
await test('Get DAT Balance', async () => {
const addr = walletAddress || WALLET_ADDRESS;
const testFileId = fileId || EXISTING_FILE_ID;
// Token ID is typically the file ID for DAT tokens
const result = await callTool('get_dat_balance', { account: addr, tokenId: testFileId });
const text = result?.result?.content?.[0]?.text || '';
if (text.includes('error') || text.includes('Error')) {
console.log(` â ď¸ ${text.slice(0, 60)}`);
} else {
console.log(` ${text.split('\n')[0] || 'OK'}`);
}
});
// 8. Get DAT URI
await test('Get DAT URI', async () => {
const testTokenId = fileId || EXISTING_FILE_ID;
const result = await callTool('get_dat_uri', { tokenId: testTokenId });
const text = result?.result?.content?.[0]?.text || '';
if (text.includes('Error') || text.includes('error')) {
console.log(` â ď¸ ${text.slice(0, 60)}`);
} else {
console.log(` ${text.split('\n')[0] || 'OK'}`);
}
});
// 9. Claim DAT Reward (expected to fail if proofs = 0)
await test('Claim DAT Reward (may fail if proofs pending)', async () => {
const testFileId = fileId || EXISTING_FILE_ID;
const result = await callTool('claim_dat_reward', { fileId: testFileId });
const text = result?.result?.content?.[0]?.text || '';
console.log(` ${text.slice(0, 80)}...`);
});
console.log('\n' + 'â'.repeat(60));
console.log('\n⨠Test suite complete!\n');
if (fileId) {
console.log(`đ Your File ID: ${fileId}`);
console.log(' Use this to check status and claim reward later.\n');
}
}
runTests().catch(console.error);