Skip to main content
Glama

Grove's MCP Server for Pocket Network

domain-resolver.test.ts10.9 kB
import { describe, it, expect, beforeEach, vi } from 'vitest'; import { DomainResolverService } from '../domain-resolver.js'; import { BlockchainRPCService } from '../blockchain-service.js'; import type { BlockchainService, RPCMethod } from '../../types.js'; describe('DomainResolverService', () => { let domainResolver: DomainResolverService; let mockBlockchainService: BlockchainRPCService; beforeEach(() => { const mockServicesData = { methodAliases: {}, services: [ { id: 'ethereum-mainnet', name: 'Ethereum Mainnet', blockchain: 'ethereum', network: 'mainnet', rpcUrl: 'https://ethereum.rpc.grove.city/v1/test-app-id', protocol: 'json-rpc', category: 'evm', supportedMethods: [] as RPCMethod[], }, { id: 'polygon-mainnet', name: 'Polygon Mainnet', blockchain: 'polygon', network: 'mainnet', rpcUrl: 'https://polygon.rpc.grove.city/v1/test-app-id', protocol: 'json-rpc', category: 'layer2', supportedMethods: [] as RPCMethod[], }, ] as BlockchainService[], }; mockBlockchainService = new BlockchainRPCService(mockServicesData); domainResolver = new DomainResolverService(mockBlockchainService); vi.restoreAllMocks(); }); describe('resolveDomain - ENS', () => { it('should resolve ENS domain successfully', async () => { // Mock resolver address call vi.spyOn(mockBlockchainService, 'callRPCMethod') .mockResolvedValueOnce({ success: true, data: '0x000000000000000000000000231b0ee14048e9dccd1d247744d114a4eb5e8e63', }) // Mock address resolution call .mockResolvedValueOnce({ success: true, data: '0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045', }); const result = await domainResolver.resolveDomain('vitalik.eth'); expect(result.success).toBe(true); expect(result.data?.domain).toBe('vitalik.eth'); expect(result.data?.type).toBe('ENS'); expect(result.data?.address).toMatch(/^0x[a-fA-F0-9]{40}$/); }); it('should handle ENS domain with no resolver', async () => { vi.spyOn(mockBlockchainService, 'callRPCMethod').mockResolvedValueOnce({ success: true, data: '0x0000000000000000000000000000000000000000000000000000000000000000', }); const result = await domainResolver.resolveDomain('nonexistent.eth'); expect(result.success).toBe(false); expect(result.error).toContain('No resolver set'); }); it('should handle ENS domain with no address set', async () => { vi.spyOn(mockBlockchainService, 'callRPCMethod') .mockResolvedValueOnce({ success: true, data: '0x000000000000000000000000231b0ee14048e9dccd1d247744d114a4eb5e8e63', }) .mockResolvedValueOnce({ success: true, data: '0x0000000000000000000000000000000000000000000000000000000000000000', }); const result = await domainResolver.resolveDomain('test.eth'); expect(result.success).toBe(false); expect(result.error).toContain('No address set'); }); it('should handle resolver lookup failure', async () => { vi.spyOn(mockBlockchainService, 'callRPCMethod').mockResolvedValueOnce({ success: false, error: 'RPC error', }); const result = await domainResolver.resolveDomain('test.eth'); expect(result.success).toBe(false); expect(result.error).toContain('Failed to get resolver'); }); }); describe('resolveDomain - Unstoppable Domains', () => { it('should resolve Unstoppable Domain successfully', async () => { const mockAddress = '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028307864386461366266323639363461663964376565643965303365353334313564333761613936303435000000000000000000000000000000000000000000000000'; vi.spyOn(mockBlockchainService, 'callRPCMethod').mockResolvedValueOnce({ success: true, data: mockAddress, }); const result = await domainResolver.resolveDomain('brad.crypto'); expect(result.success).toBe(true); expect(result.data?.domain).toBe('brad.crypto'); expect(result.data?.type).toBe('Unstoppable Domains'); }); it('should handle Unstoppable Domain with no address', async () => { vi.spyOn(mockBlockchainService, 'callRPCMethod').mockResolvedValueOnce({ success: true, data: '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000', }); const result = await domainResolver.resolveDomain('test.crypto'); expect(result.success).toBe(false); expect(result.error).toContain('No address set'); }); it('should recognize various Unstoppable Domain TLDs', async () => { const udTLDs = ['.crypto', '.nft', '.blockchain', '.bitcoin', '.wallet']; for (const tld of udTLDs) { vi.spyOn(mockBlockchainService, 'callRPCMethod').mockResolvedValueOnce({ success: false, error: 'test', }); const result = await domainResolver.resolveDomain(`test${tld}`); expect(result.success).toBe(false); } }); }); describe('resolveDomain - Unsupported', () => { it('should reject unsupported domain types', async () => { const result = await domainResolver.resolveDomain('test.com'); expect(result.success).toBe(false); expect(result.error).toContain('Unsupported domain type'); }); }); describe('reverseResolve', () => { it('should reverse resolve ENS successfully', async () => { const mockNameData = '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000007746573742e6574680000000000000000000000000000000000000000000000000'; vi.spyOn(mockBlockchainService, 'callRPCMethod') // Mock reverse name lookup .mockResolvedValueOnce({ success: true, data: mockNameData, }) // Mock forward resolution verification - resolver .mockResolvedValueOnce({ success: true, data: '0x000000000000000000000000231b0ee14048e9dccd1d247744d114a4eb5e8e63', }) // Mock forward resolution verification - address .mockResolvedValueOnce({ success: true, data: '0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045', }); const result = await domainResolver.reverseResolve( '0xd8da6bf26964af9d7eed9e03e53415d37aa96045' ); expect(result.success).toBe(true); expect(result.data?.address).toBe('0xd8da6bf26964af9d7eed9e03e53415d37aa96045'); expect(result.data?.type).toBe('ENS'); expect(result.data?.verified).toBe(true); }); it('should handle no reverse record', async () => { vi.spyOn(mockBlockchainService, 'callRPCMethod').mockResolvedValueOnce({ success: false, error: 'No record', }); const result = await domainResolver.reverseResolve('0x123'); expect(result.success).toBe(false); expect(result.error).toContain('No reverse record'); }); it('should reject mismatched forward resolution', async () => { const mockNameData = '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000007746573742e6574680000000000000000000000000000000000000000000000000'; vi.spyOn(mockBlockchainService, 'callRPCMethod') .mockResolvedValueOnce({ success: true, data: mockNameData, }) .mockResolvedValueOnce({ success: true, data: '0x000000000000000000000000231b0ee14048e9dccd1d247744d114a4eb5e8e63', }) .mockResolvedValueOnce({ success: true, data: '0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff', }); const result = await domainResolver.reverseResolve( '0xd8da6bf26964af9d7eed9e03e53415d37aa96045' ); expect(result.success).toBe(false); expect(result.error).toContain('forward resolution mismatch'); }); }); describe('getDomainRecords', () => { it('should get ENS text records', async () => { const mockEmailRecord = '0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d746573744074657374676d61696c2e636f6d000000000000000000000000000000'; vi.spyOn(mockBlockchainService, 'callRPCMethod') // Resolver lookup .mockResolvedValueOnce({ success: true, data: '0x000000000000000000000000231b0ee14048e9dccd1d247744d114a4eb5e8e63', }) // Email record .mockResolvedValueOnce({ success: true, data: mockEmailRecord, }) // Twitter record .mockResolvedValueOnce({ success: true, data: '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000', }); const result = await domainResolver.getDomainRecords( 'test.eth', ['email', 'com.twitter'] ); expect(result.success).toBe(true); expect(result.data?.records).toHaveLength(2); expect(result.data?.records[0].key).toBe('email'); }); it('should reject non-ENS domains', async () => { const result = await domainResolver.getDomainRecords('test.com', ['email']); expect(result.success).toBe(false); expect(result.error).toContain('only supported for ENS'); }); it('should handle resolver lookup failure', async () => { vi.spyOn(mockBlockchainService, 'callRPCMethod').mockResolvedValueOnce({ success: false, error: 'Failed', }); const result = await domainResolver.getDomainRecords('test.eth', ['email']); expect(result.success).toBe(false); expect(result.error).toContain('Failed to get resolver'); }); it('should handle no resolver set', async () => { vi.spyOn(mockBlockchainService, 'callRPCMethod').mockResolvedValueOnce({ success: true, data: '0x0000000000000000000000000000000000000000000000000000000000000000', }); const result = await domainResolver.getDomainRecords('test.eth', ['email']); expect(result.success).toBe(false); expect(result.error).toContain('No resolver set'); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/buildwithgrove/mcp-pocket'

If you have feedback or need assistance with the MCP directory API, please join our Discord server