🌳
pt0/deployF/staticSiteF/ensApplyAI.mts
1import fs from 'fs/promises'
2import path from 'path'
10export const doEnsApply = async ({uploadDir, ensName, getWallet, ipfsApiUrl, ipfsGatewayUrl}: {uploadDir: string, ensName: string, getWallet: () => any, ipfsApiUrl?: string, ipfsGatewayUrl?: string}) => {
11 if (!ipfsApiUrl) console.warn(`⚠️ No ipfsApiUrl specified - content may not be pinned`)
12 const currentContenthash = await ensGetContenthash({ensName})
13 const oldCid = currentContenthash ? contenthashToCid(currentContenthash) : null
15 const {rootCid, fileCids} = await ipfsUploadDir({dirPath: uploadDir, apiUrl: ipfsApiUrl})
16 let cid = rootCid
18 const mediaExts = new Set(mediaFileExtA)
19 const mediaManifest: Record<string, string> = {}
20 for (const {relativePath, cid: fileCid} of fileCids) {
21 const ext = path.extname(relativePath).toLowerCase()
22 if (mediaExts.has(ext)) mediaManifest[relativePath] = fileCid
23 }
24 if (Object.keys(mediaManifest).length) {
25 await fs.writeFile(path.join(uploadDir, 'media-manifest.json'), JSON.stringify(mediaManifest, null, 2))
26 const mediaFallbackJs = `fetch('/media-manifest.json').then(r=>r.ok?r.json():null).then(m=>{if(!m)return;document.querySelectorAll('[src],[href]').forEach(el=>{const a=el.src?'src':el.href?'href':null;if(!a)return;const k=new URL(el[a],location.origin).pathname.replace(/^\\//,'');if(!m[k])return;el.addEventListener('error',()=>{if(el.dataset.fb)return;el.dataset.fb=1;el[a]='/ipfs/'+m[k]+'?filename='+encodeURIComponent(k.split('/').pop())},{once:true})})})`
27 await fs.writeFile(path.join(uploadDir, 'media-fallback.js'), mediaFallbackJs)
28 const allHtmlFiles = (await getFilesRec(uploadDir)).filter(f => f.endsWith('.html'))
29 let injected = 0
30 for (const fp of allHtmlFiles) {
31 const html = await fs.readFile(fp, 'utf8')
32 if (html.includes('media-fallback.js')) continue
33 await fs.writeFile(fp, html.replace('</body>', '<script defer src="/media-fallback.js"></script></body>'))
34 injected++
35 }
36 console.log(`Wrote media-manifest.json (${Object.keys(mediaManifest).length} files) + media-fallback.js (injected into ${injected} html) — re-uploading...`)
37 const withManifest = await ipfsUploadDir({dirPath: uploadDir, apiUrl: ipfsApiUrl})
38 cid = withManifest.rootCid
39 console.log(`Pinned (with manifest): ${cid}`)
40 }
42 const newContenthash = cidToContenthash(cid)
43 await pinCid(cid)
44 if (currentContenthash === newContenthash) {
45 console.log(`\nNo changes - contenthash already set`)
46 console.log(`IPFS gateway: ${ipfsGatewayLink(cid, ipfsGatewayUrl)}`)
47 return
48 }
50 const wallet = getWallet()
51 betLog({walletAddress: wallet.address})
52 await ensSetContenthash({ensName, ipfsCid: cid, wallet})
54 if (oldCid && oldCid !== cid) {
55 await unpinCid(oldCid)
56 console.log(`Unpinned old: ${oldCid}`)
57 }
59 console.log(`\nSite live at: https://${ensName.replace('.eth', '')}.eth.limo`)
60 console.log(`IPFS gateway: ${ipfsGatewayLink(cid, ipfsGatewayUrl)}`)
63export const doEnsInfo = async ({ensName}: {ensName: string}) => {
64 const contenthash = await ensGetContenthash({ensName})
65 betLog({ensName, contenthash})
66 if (contenthash) console.log(`Gateway: https://${ensName.replace('.eth', '')}.eth.limo`)