feat: Add IPNS support

This commit is contained in:
2025-07-26 13:57:13 +10:00
parent a7d18d529e
commit 2ba2ef3bef
4 changed files with 121 additions and 23 deletions

View File

@@ -9,7 +9,8 @@ const {
LOCAL_RESOLVER_HOST,
LOCAL_RESOLVER_PORT,
CACHE_ENABLED,
CACHE_TTL_SECONDS
CACHE_TTL_SECONDS,
IPFS_GATEWAY
} = config;
// Setup cache
@@ -18,6 +19,12 @@ const cache = new NodeCache({
checkperiod: CACHE_TTL_SECONDS * 0.2,
});
// Setup separate cache for IPNS with shorter TTL (IPNS can change more frequently)
const ipnsCache = new NodeCache({
stdTTL: Math.min(CACHE_TTL_SECONDS, 300), // Max 5 minutes for IPNS
checkperiod: 60,
});
/**
* Resolve a Handshake domain to an IPFS CID
* @param {string} domain - The Handshake domain to resolve
@@ -299,14 +306,14 @@ async function resolveLocal(domain) {
/**
* Extract IPFS CID from DNS TXT records
* @param {string[][]} records - Array of TXT record arrays
* @returns {string|null} - IPFS CID or null
* @returns {Promise<string|null>} - IPFS CID or IPNS hash or null
*/
function extractCidFromRecords(records) {
async function extractCidFromRecords(records) {
if (!records || !records.length) {
return null;
}
// Flatten and look for ipfs= or ip6= prefixes
// Flatten and look for ipfs=, ip6=, or ipns= prefixes
for (const recordSet of records) {
for (const record of recordSet) {
// Support multiple formats
@@ -319,6 +326,18 @@ function extractCidFromRecords(records) {
if (record.startsWith('ip6=')) {
return record.substring(4);
}
if (record.startsWith('ipns=')) {
const ipnsName = record.substring(5);
console.log(`Found IPNS record: ${ipnsName}`);
// Return IPNS hash prefixed with 'ipns:' to distinguish from IPFS CID
return `ipns:${ipnsName}`;
}
if (record.startsWith('ipns:')) {
const ipnsName = record.substring(5);
console.log(`Found IPNS record: ${ipnsName}`);
// Return IPNS hash prefixed with 'ipns:' to distinguish from IPFS CID
return `ipns:${ipnsName}`;
}
// Log the record for debugging
console.log(`Found TXT record: ${record}`);
@@ -328,7 +347,6 @@ function extractCidFromRecords(records) {
return null;
}
/**
* Clear the cache for a specific domain
* @param {string} domain - The Handshake domain to clear from cache
@@ -340,7 +358,46 @@ function clearCache(domain) {
}
}
/**
* Clear IPNS cache for a specific IPNS name (keeping for API compatibility)
* @param {string} ipnsName - The IPNS name to clear from cache
*/
function clearIpnsCache(ipnsName) {
// Since we're not caching IPNS resolutions anymore, just log
console.log(`IPNS cache clear requested for ${ipnsName} (no-op)`);
}
/**
* Clear the cache for a specific domain
* @param {string} domain - The Handshake domain to clear from cache
*/
function clearCache(domain) {
if (CACHE_ENABLED) {
cache.del(`hns:${domain}`);
// Also clear any IPNS cache entries that might be related
const keys = ipnsCache.keys();
keys.forEach(key => {
if (key.includes(domain)) {
ipnsCache.del(key);
}
});
console.log(`Cache cleared for ${domain}`);
}
}
/**
* Clear IPNS cache for a specific IPNS name
* @param {string} ipnsName - The IPNS name to clear from cache
*/
function clearIpnsCache(ipnsName) {
if (CACHE_ENABLED) {
ipnsCache.del(`ipns:${ipnsName}`);
console.log(`IPNS cache cleared for ${ipnsName}`);
}
}
module.exports = {
resolveHandshake,
clearCache
clearCache,
clearIpnsCache
};