JavaScript OS에 IPFS 추가
20343 단어 cloudjavascriptwebdevweb3
첫 번째 단계로 ipfs native url 지원을 추가하기로 결정했습니다. 이 지원을 Browser ( Demo ), Run Dialog , Shortcuts & Terminal 에 추가했습니다. 대부분의 주요 ipfs 기능을 마이그레이션했습니다utils/ipfs.ts.
이것이 작동하는 방식에 대한 기본 개념은 ipfs 기본 URL을 가져 와서 ipfs gateway을 사용하는 URL로 변환하는 것입니다. 제 경우에는 official ipfs gateways을 폴백으로 추가하고 Cloudflare gateways을 기본으로 추가했습니다.
const IPFS_GATEWAY_URLS = [
"https://<CID>.ipfs.cf-ipfs.com/",
"https://<CID>.ipfs.dweb.link/",
"https://cloudflare-ipfs.com/ipfs/<CID>/",
"https://gateway.ipfs.io/ipfs/<CID>/",
];
URL을 만들 때 CORS 친화적이지 않은 CID v0과 혼동하지 않도록 최신CID v1 format을 사용하려고 합니다. 대소문자를 구분하지 않는 base32 형식을 사용하는 이 형식으로 변환하기 위해 라이브러리multiformats를 사용했습니다.
let IPFS_GATEWAY_URL = "";
const getIpfsGatewayUrl = async (
ipfsUrl: string,
notCurrent?: boolean
): Promise<string> => {
if (!IPFS_GATEWAY_URL || notCurrent) {
const urlList = notCurrent
? IPFS_GATEWAY_URLS.filter((url) => url !== IPFS_GATEWAY_URL)
: IPFS_GATEWAY_URLS;
for (const url of urlList) {
if (await isIpfsGatewayAvailable(url)) {
IPFS_GATEWAY_URL = url;
break;
}
}
if (!IPFS_GATEWAY_URL) return "";
}
const { pathname, protocol, search } = new URL(ipfsUrl);
if (protocol !== "ipfs:") return "";
const [cid = "", ...path] = pathname.split("/").filter(Boolean);
const { CID } = await import("multiformats/cid");
return `${IPFS_GATEWAY_URL.replace(
"<CID>",
CID.parse(cid).toV1().toString()
)}${path.join("/")}${search}`;
};
사용할 게이트웨이를 찾기 위해 초기 검사를 수행할 때 가용성 검사기를 public-gateway-checker에서 가져온 코드에 기반했습니다.
const isIpfsGatewayAvailable = (gatewayUrl: string): Promise<boolean> =>
new Promise((resolve) => {
const timeoutId = window.setTimeout(
() => resolve(false),
1000
);
const img = new Image();
img.addEventListener("load", () => {
window.clearTimeout(timeoutId);
resolve(true);
});
img.addEventListener("error", () => {
window.clearTimeout(timeoutId);
resolve(false);
});
img.src = `${gatewayUrl.replace(
"<CID>",
// https://github.com/ipfs/public-gateway-checker/blob/master/src/constants.ts
"bafybeibwzifw52ttrkqlikfzext5akxu7lz4xiwjgwzmqcpdzmp3n5vnbe"
)}?now=${Date.now()}&filename=1x1.png#x-ipfs-companion-no-redirect`;
});
실제로 요청을 수행할 때 새 ipfs 게이트웨이 URL에 필요한 것은 일반
fetch()
명령뿐입니다.const getIpfsResource = async (ipfsUrl: string): Promise<Buffer> => {
let response: Response | null = null;
const requestOptions = {
cache: "no-cache",
credentials: "omit",
keepalive: false,
mode: "cors",
priority: "high",
referrerPolicy: "no-referrer",
window: null,
} as RequestInit;
try {
response = await fetch(await getIpfsGatewayUrl(ipfsUrl), requestOptions);
} catch (error) {
if ((error as Error).message === "Failed to fetch") {
response = await fetch(
await getIpfsGatewayUrl(ipfsUrl, true),
requestOptions
);
}
}
return response instanceof Response
? Buffer.from(await response.arrayBuffer())
: Buffer.from("");
};
또한 올바른 앱에서 URL을 열려고 시도할 수 있도록 파일 유형 감지를 추가했습니다. 이것은 라이브러리file-type를 사용하여 수행됩니다.
const getIpfsFileName = async (
ipfsUrl: string,
ipfsData: Buffer
): Promise<string> => {
const { pathname, searchParams } = new URL(ipfsUrl);
const fileName = searchParams.get("filename");
if (fileName) return fileName;
const { fileTypeFromBuffer } = await import("file-type");
const { ext = "" } = (await fileTypeFromBuffer(ipfsData)) || {};
return `${pathname.split("/").filter(Boolean).join("_")}${
ext ? `.${ext}` : ""
}`;
};
나는 게이트웨이의 신뢰성이 꽤 좋다는 것을 알았지만 때때로 요청이 시작되기 전에 많은 양의 지연이 있었습니다.
내 기사를 읽어 주셔서 감사합니다. 내 개인 웹사이트이기도 한 daedalOSdustinbrett.com에서 일부 ipfs URL을 사용해 보십시오.
이 모든 ipfs 마법의 클라이언트인 daedalOS에 대해 더 알고 싶다면 ipfs를 포함한 다양한 기능을 살펴보는 제 비디오를 확인하십시오. 감사!
Reference
이 문제에 관하여(JavaScript OS에 IPFS 추가), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dustinbrett/adding-ipfs-to-my-javascript-os-14ag텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)