mirror of
https://github.com/fluencelabs/examples
synced 2025-06-25 15:51:33 +00:00
A little attempt to reorganize code
This commit is contained in:
@ -5,9 +5,14 @@ import "./App.scss";
|
|||||||
import { createClient, FluenceClient } from "@fluencelabs/fluence";
|
import { createClient, FluenceClient } from "@fluencelabs/fluence";
|
||||||
import { get_external_api_multiaddr } from "@fluencelabs/aqua-ipfs";
|
import { get_external_api_multiaddr } from "@fluencelabs/aqua-ipfs";
|
||||||
import { stage } from "@fluencelabs/fluence-network-environment";
|
import { stage } from "@fluencelabs/fluence-network-environment";
|
||||||
import { deploy_service, put_file_size, remove_service, provideFile } from "@fluencelabs/ipfs-execution";
|
import {
|
||||||
import { Multiaddr, protocols } from 'multiaddr';
|
deploy_service,
|
||||||
const { create, globSource, urlSource, CID } = require('ipfs-http-client');
|
put_file_size,
|
||||||
|
remove_service,
|
||||||
|
provideFile,
|
||||||
|
} from "@fluencelabs/ipfs-execution";
|
||||||
|
import { Multiaddr, protocols } from "multiaddr";
|
||||||
|
const { create, globSource, urlSource, CID } = require("ipfs-http-client");
|
||||||
|
|
||||||
const relayNodes = [stage[0], stage[1], stage[2]];
|
const relayNodes = [stage[0], stage[1], stage[2]];
|
||||||
|
|
||||||
@ -17,28 +22,36 @@ const copyToClipboard = (text: string) => {
|
|||||||
|
|
||||||
function fromOption<T>(opt: T | T[] | null): T | null {
|
function fromOption<T>(opt: T | T[] | null): T | null {
|
||||||
if (Array.isArray(opt)) {
|
if (Array.isArray(opt)) {
|
||||||
if (opt.length === 0) { return null; }
|
if (opt.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
opt = opt[0];
|
opt = opt[0];
|
||||||
}
|
}
|
||||||
if (opt === null) { return null; }
|
if (opt === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
|
|
||||||
function decapsulateP2P(rpcAddr: string): string {
|
function decapsulateP2P(rpcAddr: string): string {
|
||||||
return new Multiaddr(rpcAddr).decapsulateCode(protocols.names.p2p.code).toString();
|
return new Multiaddr(rpcAddr)
|
||||||
|
.decapsulateCode(protocols.names.p2p.code)
|
||||||
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [client, setClient] = useState<FluenceClient | null>(null);
|
const [client, setClient] = useState<FluenceClient | null>(null);
|
||||||
const [serviceId, setServiceId] = useState<string | null>(null);
|
const [serviceId, setServiceId] = useState<string | null>(null);
|
||||||
|
|
||||||
const [wasm, setWasm] = useState<string | null>("Qmf8fH2cDZXGKS9uDGBcHxv5uQ51ChrigdZKe3QxS2C1AF");
|
const [wasm, setWasm] = useState<string>(
|
||||||
const [rpcAddr, setRpcAddr] = useState<string | null>("");
|
"Qmf8fH2cDZXGKS9uDGBcHxv5uQ51ChrigdZKe3QxS2C1AF"
|
||||||
|
);
|
||||||
|
const [rpcAddr, setRpcAddr] = useState<string>("");
|
||||||
const [fileCID, setFileCID] = useState<string>("");
|
const [fileCID, setFileCID] = useState<string>("");
|
||||||
const [fileSize, setFileSize] = useState<string | null>(null);
|
const [fileSize, setFileSize] = useState<string>("");
|
||||||
const [fileSizeCID, setFileSizeCID] = useState<string | null>(null);
|
const [fileSizeCID, setFileSizeCID] = useState<string>("");
|
||||||
|
|
||||||
const isConnected = client !== null;
|
const isConnected = client !== null;
|
||||||
const gotRpcAddr = rpcAddr !== null;
|
const gotRpcAddr = rpcAddr !== null;
|
||||||
@ -64,7 +77,7 @@ function App() {
|
|||||||
console.log("getRpcAddr result", result);
|
console.log("getRpcAddr result", result);
|
||||||
let rpcAddr = result.multiaddr;
|
let rpcAddr = result.multiaddr;
|
||||||
setRpcAddr(decapsulateP2P(rpcAddr));
|
setRpcAddr(decapsulateP2P(rpcAddr));
|
||||||
}
|
};
|
||||||
|
|
||||||
const deployService = async () => {
|
const deployService = async () => {
|
||||||
console.log("wasm %s rpcAddr %s", wasm, rpcAddr);
|
console.log("wasm %s rpcAddr %s", wasm, rpcAddr);
|
||||||
@ -73,7 +86,9 @@ function App() {
|
|||||||
}
|
}
|
||||||
var service_id = await deploy_service(
|
var service_id = await deploy_service(
|
||||||
client,
|
client,
|
||||||
client.relayPeerId!, wasm, rpcAddr,
|
client.relayPeerId!,
|
||||||
|
wasm,
|
||||||
|
rpcAddr,
|
||||||
(msg, value) => console.log(msg, value),
|
(msg, value) => console.log(msg, value),
|
||||||
{ ttl: 10000 }
|
{ ttl: 10000 }
|
||||||
);
|
);
|
||||||
@ -88,8 +103,11 @@ function App() {
|
|||||||
|
|
||||||
var putResult = await put_file_size(
|
var putResult = await put_file_size(
|
||||||
client,
|
client,
|
||||||
client.relayPeerId!, fileCID, rpcAddr, serviceId,
|
client.relayPeerId!,
|
||||||
size => setFileSize(size.toString()),
|
fileCID,
|
||||||
|
rpcAddr,
|
||||||
|
serviceId,
|
||||||
|
(size) => setFileSize(size.toString()),
|
||||||
(label, error) => setFileSize("Error: " + label + ": " + error),
|
(label, error) => setFileSize("Error: " + label + ": " + error),
|
||||||
{ ttl: 10000 }
|
{ ttl: 10000 }
|
||||||
);
|
);
|
||||||
@ -109,36 +127,19 @@ function App() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await remove_service(client, client.relayPeerId!, serviceId, { ttl: 10000 });
|
await remove_service(client, client.relayPeerId!, serviceId, {
|
||||||
|
ttl: 10000,
|
||||||
|
});
|
||||||
setServiceId(null);
|
setServiceId(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("isConnected gotRpcAddr deployed\n", isConnected, gotRpcAddr, deployed);
|
console.log(
|
||||||
|
"isConnected gotRpcAddr deployed\n",
|
||||||
if (!isConnected) {
|
isConnected,
|
||||||
return (<div className="App">
|
gotRpcAddr,
|
||||||
<header>
|
deployed
|
||||||
<img src={logo} className="logo" alt="logo" />
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className="content">
|
|
||||||
<>
|
|
||||||
<h1>Pick a relay</h1>
|
|
||||||
<ul>
|
|
||||||
{relayNodes.map((x) => (
|
|
||||||
<li key={x.peerId}>
|
|
||||||
<span className="mono">{x.peerId}</span>
|
|
||||||
<button className="btn" onClick={async () => await connect(x.multiaddr)}>
|
|
||||||
Connect
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
} else if (isConnected && gotRpcAddr && !deployed) {
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<header>
|
<header>
|
||||||
@ -146,45 +147,146 @@ function App() {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className="content">
|
<div className="content">
|
||||||
|
{!isConnected && <ConnectionForm connect={connect} />}
|
||||||
|
{isConnected && <Connected client={client!} />}
|
||||||
|
{isConnected && gotRpcAddr && !deployed && (
|
||||||
|
<IpfsForm
|
||||||
|
rpcAddr={rpcAddr}
|
||||||
|
setRpcAddr={setRpcAddr}
|
||||||
|
wasm={wasm}
|
||||||
|
setWasm={setWasm}
|
||||||
|
deployService={deployService}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{deployed && (
|
||||||
|
<Deployed
|
||||||
|
setRpcAddr={setRpcAddr}
|
||||||
|
rpcAddr={rpcAddr}
|
||||||
|
setFileCID={setFileCID}
|
||||||
|
fileCID={fileCID}
|
||||||
|
fileSize={fileSize}
|
||||||
|
fileSizeCID={fileSizeCID}
|
||||||
|
getFileSize={getFileSize}
|
||||||
|
wasm={wasm}
|
||||||
|
serviceId={serviceId}
|
||||||
|
removeService={removeService}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const Deployed = (props: {
|
||||||
|
setRpcAddr: React.Dispatch<React.SetStateAction<string>>;
|
||||||
|
rpcAddr: string;
|
||||||
|
setFileCID: React.Dispatch<React.SetStateAction<string>>;
|
||||||
|
fileCID: string;
|
||||||
|
fileSize: string;
|
||||||
|
fileSizeCID: string;
|
||||||
|
getFileSize: () => Promise<void>;
|
||||||
|
wasm: string;
|
||||||
|
serviceId: string | null;
|
||||||
|
removeService: () => {};
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Connected</h1>
|
<h2>Deployed</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="bold">Peer id:</td>
|
<td className="bold">process_files.wasm CID:</td>
|
||||||
<td className="mono">{client!.selfPeerId}</td>
|
<td className="mono">{props.wasm}</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
className="btn-clipboard"
|
className="btn-clipboard"
|
||||||
onClick={() => copyToClipboard(client!.selfPeerId)}
|
onClick={() => copyToClipboard(props.wasm)}
|
||||||
>
|
>
|
||||||
<i className="gg-clipboard"></i>
|
<i className="gg-clipboard"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="bold">Relay peer id:</td>
|
<td className="bold">ProcessFiles service ID:</td>
|
||||||
<td className="mono">{client!.relayPeerId}</td>
|
<td className="mono">{props.serviceId}</td>
|
||||||
<td>
|
|
||||||
<button
|
<button
|
||||||
className="btn-clipboard"
|
className="btn-clipboard"
|
||||||
onClick={() => copyToClipboard(client!.relayPeerId!)}
|
onClick={() => props.removeService()}
|
||||||
>
|
>
|
||||||
<i className="gg-clipboard"></i>
|
<i className="gg-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td className="bold">File Size:</td>
|
||||||
|
<td className="mono">{props.fileSize}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div>
|
<div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<h2>Set IPFS RPC address:</h2>
|
<h2>Set IPFS RPC address:</h2>
|
||||||
<p className="p">
|
<p className="p">Specify IPFS to download file from</p>
|
||||||
Specify IPFS to download process_files.wasm from
|
|
||||||
</p>
|
|
||||||
<input
|
<input
|
||||||
className="input"
|
className="input"
|
||||||
type="text"
|
type="text"
|
||||||
onChange={(e) => setRpcAddr(e.target.value)}
|
onChange={(e) => props.setRpcAddr(e.target.value)}
|
||||||
value={rpcAddr!}
|
value={props.rpcAddr}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<h2>Get file size</h2>
|
||||||
|
<p className="p">
|
||||||
|
Upload any file to IPFS node
|
||||||
|
<p>
|
||||||
|
<b>{props.rpcAddr}</b>
|
||||||
|
</p>
|
||||||
|
paste CID here and get the size of that file via ProcessFiles service
|
||||||
|
you have just deployed
|
||||||
|
</p>
|
||||||
|
<div className="row">
|
||||||
|
<label className="label bold">IPFS CID</label>
|
||||||
|
<input
|
||||||
|
className="input"
|
||||||
|
type="text"
|
||||||
|
onChange={(e) => props.setFileCID(e.target.value)}
|
||||||
|
value={props.fileCID}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<button className="btn btn-hello" onClick={props.getFileSize}>
|
||||||
|
get size
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<label className="label bold">File Size:</label>
|
||||||
|
<label className="mono">{props.fileSize}</label>
|
||||||
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<label className="label bold">
|
||||||
|
File size is uploaded to IPFS as CID:
|
||||||
|
</label>
|
||||||
|
<label className="mono">{props.fileSizeCID}</label>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const IpfsForm = (props: {
|
||||||
|
rpcAddr: string;
|
||||||
|
setRpcAddr: React.Dispatch<React.SetStateAction<string>>;
|
||||||
|
wasm: string;
|
||||||
|
setWasm: React.Dispatch<React.SetStateAction<string>>;
|
||||||
|
deployService: () => Promise<void>;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>
|
||||||
|
<div className="row">
|
||||||
|
<h2>Set IPFS RPC address:</h2>
|
||||||
|
<p className="p">Specify IPFS to download process_files.wasm from</p>
|
||||||
|
<input
|
||||||
|
className="input"
|
||||||
|
type="text"
|
||||||
|
onChange={(e) => props.setRpcAddr(e.target.value)}
|
||||||
|
value={props.rpcAddr}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
@ -195,8 +297,8 @@ function App() {
|
|||||||
<input
|
<input
|
||||||
className="input"
|
className="input"
|
||||||
type="text"
|
type="text"
|
||||||
onChange={(e) => setWasm(e.target.value)}
|
onChange={(e) => props.setWasm(e.target.value)}
|
||||||
value={wasm!}
|
value={props.wasm}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -204,38 +306,54 @@ function App() {
|
|||||||
<h2>Deploy ProcessFiles service</h2>
|
<h2>Deploy ProcessFiles service</h2>
|
||||||
<p className="p">
|
<p className="p">
|
||||||
process_files.wasm will be downloaded via IPFS to the Fluence node,
|
process_files.wasm will be downloaded via IPFS to the Fluence node,
|
||||||
and then a service will be dynamically created from it!
|
and then a service will be dynamically created from it! After that,
|
||||||
|
you will be able to use that service to get sizes of IPFS files!
|
||||||
After that, you will be able to use that service to get sizes of IPFS files!
|
|
||||||
</p>
|
</p>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<button className="btn btn-hello" onClick={deployService}>
|
<button className="btn btn-hello" onClick={props.deployService}>
|
||||||
deploy service
|
deploy service
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
</div>
|
);
|
||||||
</div>
|
};
|
||||||
)
|
|
||||||
} else if (deployed) {
|
|
||||||
return (
|
|
||||||
<div className="App">
|
|
||||||
<header>
|
|
||||||
<img src={logo} className="logo" alt="logo" />
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className="content">
|
const ConnectionForm = (props: {
|
||||||
|
connect: (multiaddr: string) => Promise<void>;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Deployed</h1>
|
<h1>Pick a relay</h1>
|
||||||
|
<ul>
|
||||||
|
{relayNodes.map((x) => (
|
||||||
|
<li key={x.peerId}>
|
||||||
|
<span className="mono">{x.peerId}</span>
|
||||||
|
<button
|
||||||
|
className="btn"
|
||||||
|
onClick={async () => await props.connect(x.multiaddr)}
|
||||||
|
>
|
||||||
|
Connect
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Connected = (props: { client: FluenceClient }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<h1>Connected</h1>
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="bold">Peer id:</td>
|
<td className="bold">Peer id:</td>
|
||||||
<td className="mono">{client!.selfPeerId}</td>
|
<td className="mono">{props.client.selfPeerId}</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
className="btn-clipboard"
|
className="btn-clipboard"
|
||||||
onClick={() => copyToClipboard(client!.selfPeerId)}
|
onClick={() => copyToClipboard(props.client.selfPeerId)}
|
||||||
>
|
>
|
||||||
<i className="gg-clipboard"></i>
|
<i className="gg-clipboard"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -243,104 +361,19 @@ function App() {
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="bold">Relay peer id:</td>
|
<td className="bold">Relay peer id:</td>
|
||||||
<td className="mono">{client!.relayPeerId}</td>
|
<td className="mono">{props.client.relayPeerId}</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
className="btn-clipboard"
|
className="btn-clipboard"
|
||||||
onClick={() => copyToClipboard(client!.relayPeerId!)}
|
onClick={() => copyToClipboard(props.client.relayPeerId!)}
|
||||||
>
|
>
|
||||||
<i className="gg-clipboard"></i>
|
<i className="gg-clipboard"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td className="bold">process_files.wasm CID:</td>
|
|
||||||
<td className="mono">{wasm}</td>
|
|
||||||
<td>
|
|
||||||
<button
|
|
||||||
className="btn-clipboard"
|
|
||||||
onClick={() => copyToClipboard(wasm!)}
|
|
||||||
>
|
|
||||||
<i className="gg-clipboard"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className="bold">ProcessFiles service ID:</td>
|
|
||||||
<td className="mono">{serviceId}</td>
|
|
||||||
<button
|
|
||||||
className="btn-clipboard"
|
|
||||||
onClick={() => removeService()}
|
|
||||||
>
|
|
||||||
<i className="gg-trash"></i>
|
|
||||||
</button>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className="bold">File Size:</td>
|
|
||||||
<td className="mono">{fileSize}</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
<div>
|
|
||||||
<div className="row">
|
|
||||||
<h2>Set IPFS RPC address:</h2>
|
|
||||||
<p className="p">
|
|
||||||
Specify IPFS to download file from
|
|
||||||
</p>
|
|
||||||
<input
|
|
||||||
className="input"
|
|
||||||
type="text"
|
|
||||||
onChange={(e) => setRpcAddr(e.target.value)}
|
|
||||||
value={rpcAddr!}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<h2>Get file size</h2>
|
|
||||||
<p className="p">
|
|
||||||
Upload any file to IPFS node
|
|
||||||
<p><b>{ rpcAddr }</b></p>
|
|
||||||
paste CID here and get the size of that file via ProcessFiles service you have just deployed
|
|
||||||
</p>
|
|
||||||
<div className="row">
|
|
||||||
<label className="label bold">IPFS CID</label>
|
|
||||||
<input
|
|
||||||
className="input"
|
|
||||||
type="text"
|
|
||||||
onChange={(e) => setFileCID(e.target.value)}
|
|
||||||
value={fileCID}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<button className="btn btn-hello" onClick={getFileSize} >
|
|
||||||
get size
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<label className="label bold">File Size:</label>
|
|
||||||
<label className="mono">{fileSize}</label>
|
|
||||||
</div>
|
|
||||||
<div className="row">
|
|
||||||
<label className="label bold">File size is uploaded to IPFS as CID:</label>
|
|
||||||
<label className="mono">{fileSizeCID}</label>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
</div>
|
);
|
||||||
</div>
|
};
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<div className="App">
|
|
||||||
<header>
|
|
||||||
<img src={logo} className="logo" alt="logo" />
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className="content">
|
|
||||||
<>
|
|
||||||
<h2>Unimplemented! isConnected {isConnected} deployed {deployed} wasm {wasm} </h2>
|
|
||||||
</>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
Reference in New Issue
Block a user