Sender SDK
The @directory/client SDK handles the full resolution flow: DNS discovery, capability fetching, address resolution, Ed25519 verification, and route matching.
Install
npm install @directory/clientBasic Usage
import { DirectoryClient } from '@directory/client';
const client = new DirectoryClient();
const result = await client.resolve('alice@gmail.com', [ { value_type: 'USDC', transfer_type: 'ethereum' }, { value_type: 'USDC', transfer_type: 'base' },]);
if (result.verification.valid && result.matchedRoutes.length > 0) { const route = result.matchedRoutes[0]; console.log(`Send ${route.value_type} on ${route.transfer_type} to ${route.destination}`);}What the SDK Does
The resolve() call performs these steps automatically:
- Discover — DNS-over-HTTPS lookup for
_drs._tcp.{domain}SRV and_drskey.{domain}TXT - Capabilities — Fetch
GET /.well-known/directory.jsonfrom the DRS - Resolve — Send
POST /resolvewith the address - Verify — Check the Ed25519 signature against the DNS-published key, check TTL
- Match — Filter the contract’s routes against the sender’s capabilities
Step-by-Step (Lower Level)
If you need more control, use the individual functions:
import { discoverDrs, fetchCapabilities, resolveAddress, verifyContract, matchRoutes,} from '@directory/client';
// 1. Find the DRS via DNSconst { baseUrl, publicKey } = await discoverDrs('gmail.com');
// 2. What does it accept?const manifest = await fetchCapabilities(baseUrl);
// 3. Resolve the addressconst contract = await resolveAddress(baseUrl, 'alice@gmail.com');
// 4. Verify the signatureconst verification = await verifyContract(contract, publicKey);if (!verification.valid) throw new Error(verification.reason);
// 5. Match against what you can sendconst senderCapabilities = [ { value_type: 'USDC', transfer_type: 'ethereum' },];const routes = matchRoutes(contract.routes, senderCapabilities);Exchange Node Resolution
When the recipient’s DRS doesn’t accept what you can send, route through an exchange node:
const result = await client.resolve('alice@gmail.com', [ { value_type: 'USDC', transfer_type: 'ethereum' },], { exchangeDomain: 'bridge.money', pathwayTo: { value_type: 'USD', transfer_type: 'ach' },});Error Handling
import { DrsDiscoveryError, DrsResolveError } from '@directory/client';
try { const result = await client.resolve('alice@unknown.com', capabilities);} catch (err) { if (err instanceof DrsDiscoveryError) { // No DRS found for domain — no SRV record } if (err instanceof DrsResolveError) { // DRS returned an error — check err.code and err.status // e.g., ADDRESS_NOT_FOUND (404), INVALID_REQUEST (400) }}Runtime Compatibility
The SDK works in:
- Node.js 20+ — native Web Crypto API
- Cloudflare Workers — native Web Crypto API
- Modern browsers — native Web Crypto API
Zero external dependencies for cryptographic operations.