> mkdir IPFS
> cd IPFS
IPFS> npx create-react-app ipfs-web --template typescript
IPFS> cd .\ipfs-web\
IPFS\ipfs-web> npm install --save ipfs-core ipfs-core-types util
「[[https://github.com/ipfs/js-ipfs|ipfs-core]]」は JavaScript で IPFS を操作するためのライブラリ js-ipfs の一部です。
===== 参考 =====
* [[https://github.com/ipfs-examples/js-ipfs-examples|js-ipfs-examples]]
* [[https://github.com/ipfs/js-ipfs/tree/master/docs/core-api|IPFS Core API]]
===== IPFSUploader.tsx の実装 =====
IPFS にファイルをアップロードする機能を提供する IPFSUploader.tsx コンポーネントを実装します。
IPFS\ipfs-web> mkdir src\components
IPFS\ipfs-web> code src\components\IPFSUploader.tsx
import React, { useState, useEffect } from 'react';
import type { IPFS } from 'ipfs-core-types';
import * as IPFSCore from 'ipfs-core';
let ipfs: IPFS;
function IPFSUploader() {
const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs))
const [version, setVersion] = useState("");
const [cid, setCID] = useState("");
useEffect(() => {
startIpfs();
return function cleanup () {
if (ipfs && ipfs.stop) {
console.log('Stopping IPFS');
ipfs.stop().catch((err: any) => console.error(err));
//ipfs = undefined;
setIpfsReady(false);
}
}
}, []);
const startIpfs = async () => {
if(ipfs){
console.log('IPFS already started');
/*
} else if (window.ipfs && window.ipfs.enable) {
console.log('Found window.ipfs')
ipfs = await window.ipfs.enable({ commands: ['id'] })
*/
} else {
ipfs = await IPFSCore.create();
console.log("IPFS Started");
const _version = await ipfs.version();
setVersion(_version.version);
}
setIpfsReady(Boolean(ipfs));
};
const fileSelected = async (event: React.ChangeEvent) => {
if(!isIpfsReady) return;
const targetFile = event.target.files?.[0];
if(targetFile){
const _result = await ipfs.add(targetFile);
//const _result = await ipfs.add('Hello world');
setCID(_result.path);
}
};
return (
IPFS File Uploader
IPFS(ipfs-core) Version: { version }
);
}
export default IPFSUploader;
===== App.tsx に IPFSUploader を追加 =====
IPFS\ipfs-web> code src\App.tsx
不要な記述を削除し、IPFSUploader コンポーネントを追加します。
import React from 'react';
import './App.css';
import IPFSUploader from './components/IPFSUploader';
function App() {
return (
);
}
export default App;
===== 実行 =====
IPFS\ipfs-web> npm start
===== IPFSDirectoryUploader =====
MFS を利用してファイルをアップロードする。
IPFS\ipfs-web> code src\components\IPFSDirectoryUploader.tsx
import React, { useState, useEffect } from 'react';
import type { IPFS } from 'ipfs-core-types';
import * as IPFSCore from 'ipfs-core';
import { MFSEntry } from 'ipfs-core-types/dist/src/files/index';
let ipfs: IPFS;
function IPFSDirectoryUploader() {
const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs))
const [version, setVersion] = useState("");
const [MFSEntlies, setMFSEntlies] = useState();
useEffect(() => {
startIpfs();
return function cleanup () {
if (ipfs && ipfs.stop) {
console.log('Stopping IPFS');
ipfs.stop().catch((err: any) => console.error(err));
//ipfs = undefined;
setIpfsReady(false);
}
}
}, []);
const startIpfs = async () => {
if(ipfs){
console.log('IPFS already started');
/*
} else if (window.ipfs && window.ipfs.enable) {
console.log('Found window.ipfs')
ipfs = await window.ipfs.enable({ commands: ['id'] })
*/
} else {
ipfs = await IPFSCore.create();
console.log("IPFS Started");
const _version = await ipfs.version();
setVersion(_version.version);
const lsResult = await ipfs.files.ls("/");
let uploadDirectoryExist = false;
for await (const file of lsResult){
if(file.name === "upload-directory"){
console.log("/upload-directory is already exist.");
uploadDirectoryExist = true;
}
}
if(!uploadDirectoryExist){
console.log("mkdir /upload-directory");
await ipfs.files.mkdir("/upload-directory");
}
}
setIpfsReady(Boolean(ipfs));
};
const fileSelected = async (event: React.ChangeEvent) => {
if(!isIpfsReady) return;
const targetFile = event.target.files?.[0];
if(targetFile){
const fileReader = new window.FileReader();
fileReader.readAsArrayBuffer(targetFile);
fileReader.onloadend = async () => {
let ab = fileReader.result as ArrayBuffer;
const u8a = new Uint8Array(ab);
console.log(`upload /upload-directory/${targetFile.name}`);
await ipfs.files.write(`/upload-directory/${targetFile.name}`, u8a, {create: true});
await ls("/upload-directory");
};
}
};
const ls = async (path: string) => {
const lsResult = await ipfs.files.ls(path);
for await (const file of lsResult){
console.log(`${file.name}: ${file.cid.toString()}`);
}
};
const MFSStat = async () => {
if(!isIpfsReady) return;
const lsResult = await ipfs.files.ls('/upload-directory');
let _mfs_entlies: MFSEntry[] = [];
for await (const file of lsResult){
console.log(`${file.name}: ${file.cid.toString()}`);
_mfs_entlies.push(file);
}
setMFSEntlies(_mfs_entlies);
};
return (
IPFS File Uploader
IPFS(ipfs-core) Version: { version }
{ MFSEntlies?.map((file) => (
{file.name}: {file.cid.toString()}
))}
);
}
export default IPFSDirectoryUploader;
App.tsx に IPFSDirectoryUploader コンポーネントを記述する。