A little attempt to reorganize code

This commit is contained in:
Pavel Murygin
2021-07-21 18:26:57 +03:00
parent e3139fe515
commit de9a7c2c9d

View File

@ -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]];
@ -16,29 +21,37 @@ 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];
} }
if (opt === null) { return null; }
return opt; opt = opt[0];
}
if (opt === null) {
return null;
}
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);
@ -72,10 +85,12 @@ function App() {
return; return;
} }
var service_id = await deploy_service( var service_id = await deploy_service(
client, client,
client.relayPeerId!, wasm, rpcAddr, client.relayPeerId!,
(msg, value) => console.log(msg, value), wasm,
{ ttl: 10000 } rpcAddr,
(msg, value) => console.log(msg, value),
{ ttl: 10000 }
); );
service_id = fromOption(service_id); service_id = fromOption(service_id);
setServiceId(service_id); setServiceId(service_id);
@ -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,238 +127,253 @@ 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",
isConnected,
gotRpcAddr,
deployed
);
if (!isConnected) { return (
return (<div className="App"> <div className="App">
<header> <header>
<img src={logo} className="logo" alt="logo" /> <img src={logo} className="logo" alt="logo" />
</header> </header>
<div className="content"> <div className="content">
<> {!isConnected && <ConnectionForm connect={connect} />}
<h1>Pick a relay</h1> {isConnected && <Connected client={client!} />}
<ul> {isConnected && gotRpcAddr && !deployed && (
{relayNodes.map((x) => ( <IpfsForm
<li key={x.peerId}> rpcAddr={rpcAddr}
<span className="mono">{x.peerId}</span> setRpcAddr={setRpcAddr}
<button className="btn" onClick={async () => await connect(x.multiaddr)}> wasm={wasm}
Connect setWasm={setWasm}
</button> deployService={deployService}
</li> />
))} )}
</ul> {deployed && (
</> <Deployed
</div> setRpcAddr={setRpcAddr}
</div> rpcAddr={rpcAddr}
); setFileCID={setFileCID}
} else if (isConnected && gotRpcAddr && !deployed) { fileCID={fileCID}
return ( fileSize={fileSize}
<div className="App"> fileSizeCID={fileSizeCID}
<header> getFileSize={getFileSize}
<img src={logo} className="logo" alt="logo" /> wasm={wasm}
</header> serviceId={serviceId}
removeService={removeService}
/>
)}
</div>
</div>
);
}
<div className="content"> const Deployed = (props: {
<> setRpcAddr: React.Dispatch<React.SetStateAction<string>>;
<h1>Connected</h1> rpcAddr: string;
<table> setFileCID: React.Dispatch<React.SetStateAction<string>>;
<tr> fileCID: string;
<td className="bold">Peer id:</td> fileSize: string;
<td className="mono">{client!.selfPeerId}</td> fileSizeCID: string;
<td> getFileSize: () => Promise<void>;
<button wasm: string;
className="btn-clipboard" serviceId: string | null;
onClick={() => copyToClipboard(client!.selfPeerId)} removeService: () => {};
> }) => {
<i className="gg-clipboard"></i> return (
</button> <>
</td> <h2>Deployed</h2>
</tr> <table>
<tr> <tr>
<td className="bold">Relay peer id:</td> <td className="bold">process_files.wasm CID:</td>
<td className="mono">{client!.relayPeerId}</td> <td className="mono">{props.wasm}</td>
<td> <td>
<button <button
className="btn-clipboard" className="btn-clipboard"
onClick={() => copyToClipboard(client!.relayPeerId!)} onClick={() => copyToClipboard(props.wasm)}
> >
<i className="gg-clipboard"></i> <i className="gg-clipboard"></i>
</button> </button>
</td> </td>
</tr> </tr>
</table> <tr>
<div> <td className="bold">ProcessFiles service ID:</td>
<div className="row"> <td className="mono">{props.serviceId}</td>
<h2>Set IPFS RPC address:</h2> <button
<p className="p"> className="btn-clipboard"
Specify IPFS to download process_files.wasm from onClick={() => props.removeService()}
</p> >
<input <i className="gg-trash"></i>
className="input" </button>
type="text" </tr>
onChange={(e) => setRpcAddr(e.target.value)} <tr>
value={rpcAddr!} <td className="bold">File Size:</td>
/> <td className="mono">{props.fileSize}</td>
</div> </tr>
<div className="row"> </table>
<h2>Set process_files.wasm module CID</h2> <div>
<p className="p"> <div className="row">
To deploy a service, specify CID of WebAssembly module. <h2>Set IPFS RPC address:</h2>
</p> <p className="p">Specify IPFS to download file from</p>
<input <input
className="input" className="input"
type="text" type="text"
onChange={(e) => setWasm(e.target.value)} onChange={(e) => props.setRpcAddr(e.target.value)}
value={wasm!} value={props.rpcAddr}
/> />
</div>
</div>
<div>
<h2>Deploy ProcessFiles service</h2>
<p className="p">
process_files.wasm will be downloaded via IPFS to the Fluence node,
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!
</p>
<div className="row">
<button className="btn btn-hello" onClick={deployService}>
deploy service
</button>
</div>
</div>
</>
</div>
</div> </div>
) <h2>Get file size</h2>
} else if (deployed) { <p className="p">
return ( Upload any file to IPFS node
<div className="App"> <p>
<header> <b>{props.rpcAddr}</b>
<img src={logo} className="logo" alt="logo" /> </p>
</header> 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>
</>
);
};
<div className="content"> const IpfsForm = (props: {
<> rpcAddr: string;
<h1>Deployed</h1> setRpcAddr: React.Dispatch<React.SetStateAction<string>>;
<table> wasm: string;
<tr> setWasm: React.Dispatch<React.SetStateAction<string>>;
<td className="bold">Peer id:</td> deployService: () => Promise<void>;
<td className="mono">{client!.selfPeerId}</td> }) => {
<td> return (
<button <>
className="btn-clipboard" <div>
onClick={() => copyToClipboard(client!.selfPeerId)} <div className="row">
> <h2>Set IPFS RPC address:</h2>
<i className="gg-clipboard"></i> <p className="p">Specify IPFS to download process_files.wasm from</p>
</button> <input
</td> className="input"
</tr> type="text"
<tr> onChange={(e) => props.setRpcAddr(e.target.value)}
<td className="bold">Relay peer id:</td> value={props.rpcAddr}
<td className="mono">{client!.relayPeerId}</td> />
<td>
<button
className="btn-clipboard"
onClick={() => copyToClipboard(client!.relayPeerId!)}
>
<i className="gg-clipboard"></i>
</button>
</td>
</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>
<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>
<div className="row">
<h2>Set process_files.wasm module CID</h2>
<p className="p">
To deploy a service, specify CID of WebAssembly module.
</p>
<input
className="input"
type="text"
onChange={(e) => props.setWasm(e.target.value)}
value={props.wasm}
/>
</div> </div>
) </div>
} else { <div>
return ( <h2>Deploy ProcessFiles service</h2>
<div className="App"> <p className="p">
<header> process_files.wasm will be downloaded via IPFS to the Fluence node,
<img src={logo} className="logo" alt="logo" /> and then a service will be dynamically created from it! After that,
</header> you will be able to use that service to get sizes of IPFS files!
</p>
<div className="row">
<button className="btn btn-hello" onClick={props.deployService}>
deploy service
</button>
</div>
</div>
</>
);
};
<div className="content"> const ConnectionForm = (props: {
<> connect: (multiaddr: string) => Promise<void>;
<h2>Unimplemented! isConnected {isConnected} deployed {deployed} wasm {wasm} </h2> }) => {
</> return (
</div> <>
</div> <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>
<tr>
<td className="bold">Peer id:</td>
<td className="mono">{props.client.selfPeerId}</td>
<td>
<button
className="btn-clipboard"
onClick={() => copyToClipboard(props.client.selfPeerId)}
>
<i className="gg-clipboard"></i>
</button>
</td>
</tr>
<tr>
<td className="bold">Relay peer id:</td>
<td className="mono">{props.client.relayPeerId}</td>
<td>
<button
className="btn-clipboard"
onClick={() => copyToClipboard(props.client.relayPeerId!)}
>
<i className="gg-clipboard"></i>
</button>
</td>
</tr>
</table>
</>
);
};
export default App; export default App;