ipfs/src/hooks/use-ipfs-api.tsx

90 lines
2.4 KiB
TypeScript
Raw Normal View History

2021-09-12 16:41:30 +02:00
import { useCallback, useEffect, useState } from 'react'
2021-09-12 21:19:07 +02:00
import { create } from 'ipfs-http-client'
import type { IPFSHTTPClient } from 'ipfs-http-client'
2021-09-12 20:57:02 +02:00
import type { CIDVersion } from 'multiformats/cid'
2021-09-12 21:19:07 +02:00
import { ipfsNodeUri } from '../../site.config'
2021-09-12 16:41:30 +02:00
import { formatBytes } from '../utils'
2021-09-12 21:19:07 +02:00
import type { FileIpfs } from '../@types/ipfs'
2021-09-13 21:09:46 +02:00
import { FileWithPath } from 'react-dropzone'
2019-10-20 01:40:55 +02:00
2021-09-12 16:41:30 +02:00
export interface IpfsApiValue {
ipfs: IPFSHTTPClient | undefined
version: string | undefined
isIpfsReady: boolean
ipfsError: string | undefined
2021-09-13 21:09:46 +02:00
addFiles: (files: FileWithPath[]) => Promise<FileIpfs[] | undefined>
2021-09-12 16:41:30 +02:00
}
2019-10-20 01:40:55 +02:00
2021-09-12 21:19:07 +02:00
const { hostname, port, protocol } = new URL(ipfsNodeUri)
const ipfsConfig = {
protocol: protocol.replace(':', ''),
host: hostname,
port: Number(port) || 443
}
export default function useIpfsApi(): IpfsApiValue {
2021-09-12 16:41:30 +02:00
const [ipfs, setIpfs] = useState<IPFSHTTPClient>()
const [version, setVersion] = useState<string>()
2019-10-20 01:40:55 +02:00
const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs))
2021-09-12 16:41:30 +02:00
const [ipfsError, setIpfsError] = useState<string>()
const addFiles = useCallback(
2021-09-13 21:09:46 +02:00
async (files: FileWithPath[]): Promise<FileIpfs[] | undefined> => {
2021-09-12 16:41:30 +02:00
if (!ipfs || !files?.length) return
const ipfsFiles = [
2021-09-13 21:09:46 +02:00
...files.map((file: FileWithPath) => {
2021-09-12 16:41:30 +02:00
return { path: file.path, content: file }
})
]
const options = {
wrapWithDirectory: true,
2021-09-12 20:57:02 +02:00
cidVersion: 1 as CIDVersion,
2021-09-12 19:19:21 +02:00
hashAlg: 'sha2-256',
2021-09-12 16:41:30 +02:00
progress: (length: number) => formatBytes(length, 0)
}
const results: FileIpfs[] = []
for await (const result of ipfs.addAll(ipfsFiles, options)) {
console.log(result)
results.push(result)
}
return results
},
[ipfs]
)
2019-10-20 01:40:55 +02:00
useEffect(() => {
2021-09-12 16:41:30 +02:00
if (ipfs) return
2019-10-20 01:40:55 +02:00
2021-09-12 16:41:30 +02:00
async function initIpfs() {
2019-10-20 01:40:55 +02:00
try {
2021-09-12 21:19:07 +02:00
const ipfs = create(ipfsConfig)
2021-09-12 16:41:30 +02:00
setIpfs(ipfs)
2019-10-20 01:40:55 +02:00
const version = await ipfs.version()
2021-09-12 16:41:30 +02:00
setVersion(version.version)
2021-09-13 23:55:29 +02:00
setIpfsReady(ipfs?.isOnline())
2021-09-12 16:41:30 +02:00
} catch (e) {
setIpfsError(`IPFS connection error: ${(e as Error).message}`)
2019-10-20 01:40:55 +02:00
setIpfsReady(false)
return
}
}
initIpfs()
2021-09-12 16:41:30 +02:00
return () => {
2019-10-20 01:40:55 +02:00
if (ipfs) {
setIpfsReady(false)
2021-09-12 16:41:30 +02:00
setIpfs(undefined)
setVersion(undefined)
setIpfsError(undefined)
2019-10-20 01:40:55 +02:00
}
}
2021-09-12 21:19:07 +02:00
}, [ipfs])
2019-10-20 01:40:55 +02:00
2021-09-12 16:41:30 +02:00
return { ipfs, version, isIpfsReady, ipfsError, addFiles }
2019-10-20 01:40:55 +02:00
}