feat!: Replace old fluence-js with JS Client (#425)
6
.github/workflows/test-js-projects.yml
vendored
@ -13,9 +13,9 @@ jobs:
|
|||||||
working-directory: [
|
working-directory: [
|
||||||
"./quickstart/1-browser-to-browser",
|
"./quickstart/1-browser-to-browser",
|
||||||
"./quickstart/3-browser-to-service",
|
"./quickstart/3-browser-to-service",
|
||||||
"./fluence-js-examples/hello-world",
|
"./js-client-examples/hello-world",
|
||||||
"./fluence-js-examples/browser-example",
|
"./js-client-examples/browser-example",
|
||||||
"./fluence-js-examples/node-example",
|
"./js-client-examples/node-example",
|
||||||
"./aqua-examples/echo-greeter/client-peer",
|
"./aqua-examples/echo-greeter/client-peer",
|
||||||
"./aqua-examples/price-oracle/client-peer",
|
"./aqua-examples/price-oracle/client-peer",
|
||||||
"./aqua-examples/price-oracle/web"
|
"./aqua-examples/price-oracle/web"
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import logo from "./logo.svg";
|
|
||||||
import "./App.scss";
|
|
||||||
|
|
||||||
import { Fluence } from "@fluencelabs/fluence";
|
|
||||||
import { krasnodar } from "@fluencelabs/fluence-network-environment";
|
|
||||||
import { getRelayTime } from "./_aqua/getting-started";
|
|
||||||
|
|
||||||
const relayNode = krasnodar[0];
|
|
||||||
|
|
||||||
function App() {
|
|
||||||
const [relayTime, setRelayTime] = useState<Date | null>(null);
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
Fluence.start({ connectTo: relayNode })
|
|
||||||
.catch((err) => console.log("Client initialization failed", err));
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onGetRelayTimeBtnClick = async () => {
|
|
||||||
if (!Fluence.getStatus().isConnected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const time = await getRelayTime(relayNode.peerId);
|
|
||||||
setRelayTime(new Date(time));
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="App">
|
|
||||||
<header>
|
|
||||||
<img src={logo} className="logo" alt="logo" />
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div className="content">
|
|
||||||
<h1>Status: <span id="status">{Fluence.getStatus().isConnected ? "Connected" : "Disconnected"}</span></h1>
|
|
||||||
<button id="btn" className="btn" onClick={onGetRelayTimeBtnClick}>
|
|
||||||
Get relay time
|
|
||||||
</button>
|
|
||||||
{relayTime && (
|
|
||||||
<>
|
|
||||||
<h2>Relay time:</h2>
|
|
||||||
<div id="relayTime">{relayTime?.toLocaleString() || ""}</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default App;
|
|
@ -1,12 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import './index.css';
|
|
||||||
import App from './App';
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<React.StrictMode>
|
|
||||||
<App />
|
|
||||||
</React.StrictMode>,
|
|
||||||
document.getElementById('root')
|
|
||||||
);
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
preset: 'ts-jest',
|
|
||||||
testEnvironment: 'node',
|
|
||||||
testPathIgnorePatterns: ['dist'],
|
|
||||||
};
|
|
13620
fluence-js-examples/hello-world/package-lock.json
generated
@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "hello-world",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"prestart": "npm run compile-aqua",
|
|
||||||
"prebuild": "npm run compile-aqua",
|
|
||||||
"start": "node -r ts-node/register src/index.ts",
|
|
||||||
"build": "tsc",
|
|
||||||
"test": "jest",
|
|
||||||
"compile-aqua": "aqua --import . -i ./aqua/ -o ./src/_aqua",
|
|
||||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
|
||||||
},
|
|
||||||
"author": "",
|
|
||||||
"license": "ISC",
|
|
||||||
"devDependencies": {
|
|
||||||
"@fluencelabs/aqua": "0.9.4",
|
|
||||||
"@fluencelabs/aqua-lib": "0.6.0",
|
|
||||||
"chokidar-cli": "^3.0.0",
|
|
||||||
"ts-node": "^10.6.0",
|
|
||||||
"typescript": "^4.6.3",
|
|
||||||
"@types/jest": "^27.0.3",
|
|
||||||
"jest": "^27.4.0",
|
|
||||||
"ts-jest": "^27.0.7"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@fluencelabs/fluence": "^0.28.0",
|
|
||||||
"@fluencelabs/fluence-network-environment": "^1.0.13"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
import { main } from './main';
|
|
||||||
|
|
||||||
main();
|
|
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": [
|
|
||||||
"es2015",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
"outDir": "./dist/",
|
|
||||||
"target": "es5",
|
|
||||||
"module": "commonjs",
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": false,
|
|
||||||
"sourceMap": true,
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"include": [
|
|
||||||
"src"
|
|
||||||
],
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
preset: 'ts-jest',
|
|
||||||
testEnvironment: 'node',
|
|
||||||
testPathIgnorePatterns: ['dist'],
|
|
||||||
};
|
|
13619
fluence-js-examples/node-example/package-lock.json
generated
@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "node-example",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"prestart": "npm run compile-aqua",
|
|
||||||
"prebuild": "npm run compile-aqua",
|
|
||||||
"start": "node -r ts-node/register src/index.ts",
|
|
||||||
"test": "jest",
|
|
||||||
"build": "tsc",
|
|
||||||
"compile-aqua": "aqua --import . -i ./aqua/ -o ./src/_aqua",
|
|
||||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
|
||||||
},
|
|
||||||
"author": "",
|
|
||||||
"license": "ISC",
|
|
||||||
"devDependencies": {
|
|
||||||
"@fluencelabs/aqua": "0.9.4",
|
|
||||||
"@types/jest": "^27.0.3",
|
|
||||||
"chokidar-cli": "^3.0.0",
|
|
||||||
"jest": "^27.4.0",
|
|
||||||
"ts-jest": "^27.0.7",
|
|
||||||
"ts-node": "^10.7.0",
|
|
||||||
"typescript": "^4.6.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@fluencelabs/fluence": "^0.28.0",
|
|
||||||
"@fluencelabs/fluence-network-environment": "^1.0.13"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
#! /bin/bash
|
|
||||||
|
|
||||||
npx aqua run --input ./aqua/demo-calculation.aqua --func 'demoCalculation()' --addr /dns4/stage.fluence.dev/tcp/19001/wss/p2p/12D3KooWHCJbJKGDfCgHSoCuK9q4STyRnVveqLoXAPBbXHTZx9Cv
|
|
@ -1,3 +0,0 @@
|
|||||||
import { runServer, waitForKeypressAndStop } from './main';
|
|
||||||
|
|
||||||
runServer().then(waitForKeypressAndStop);
|
|
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": [
|
|
||||||
"es2015",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
"outDir": "./dist/",
|
|
||||||
"target": "es5",
|
|
||||||
"module": "commonjs",
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"skipLibCheck": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": false,
|
|
||||||
"sourceMap": true,
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"include": [
|
|
||||||
"src"
|
|
||||||
],
|
|
||||||
}
|
|
@ -3,6 +3,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@fluencelabs/js-client.api": "0.11.2",
|
||||||
"@fluencelabs/fluence-network-environment": "1.0.14",
|
"@fluencelabs/fluence-network-environment": "1.0.14",
|
||||||
"@testing-library/jest-dom": "^5.14.1",
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
"@testing-library/react": "^11.2.7",
|
"@testing-library/react": "^11.2.7",
|
||||||
@ -19,7 +20,6 @@
|
|||||||
"web-vitals": "^1.1.2"
|
"web-vitals": "^1.1.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "copy-marine public",
|
|
||||||
"prestart": "npm run compile-aqua",
|
"prestart": "npm run compile-aqua",
|
||||||
"prebuild": "npm run compile-aqua",
|
"prebuild": "npm run compile-aqua",
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
@ -27,8 +27,8 @@
|
|||||||
"test": "jest --config=jest.config.js",
|
"test": "jest --config=jest.config.js",
|
||||||
"_test": "react-scripts test",
|
"_test": "react-scripts test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
@ -51,14 +51,12 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fluencelabs/aqua": "0.9.4",
|
"@fluencelabs/cli": "0.2.41",
|
||||||
"@fluencelabs/aqua-lib": "0.6.0",
|
"@fluencelabs/aqua-lib": "0.6.0",
|
||||||
"@fluencelabs/fluence": "0.28.0",
|
|
||||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||||
"@types/puppeteer": "^5.4.4",
|
"@types/puppeteer": "^5.4.4",
|
||||||
"chokidar-cli": "^2.1.0",
|
|
||||||
"jest-puppeteer": "^6.0.2",
|
"jest-puppeteer": "^6.0.2",
|
||||||
"node-sass": "^6.0.1",
|
"sass": "^1.58.3",
|
||||||
"serve": "^13.0.2",
|
"serve": "^13.0.2",
|
||||||
"ts-jest": "^27.1.3"
|
"ts-jest": "^27.1.3"
|
||||||
}
|
}
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@ -22,6 +22,8 @@
|
|||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>Fluence getting started</title>
|
<title>Fluence getting started</title>
|
||||||
|
<script src='https://cdn.jsdelivr.net/npm/@fluencelabs/js-client.web.standalone@0.13.3/dist/js-client.min.js'
|
||||||
|
async></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
60
js-client-examples/browser-example/src/App.tsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import logo from './logo.svg';
|
||||||
|
import './App.scss';
|
||||||
|
|
||||||
|
import { Fluence } from '@fluencelabs/js-client.api';
|
||||||
|
import type { ConnectionState } from '@fluencelabs/js-client.api';
|
||||||
|
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
||||||
|
import { getRelayTime } from './_aqua/getting-started';
|
||||||
|
|
||||||
|
const relayNode = krasnodar[0];
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
|
||||||
|
const [relayTime, setRelayTime] = useState<Date | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
Fluence.onConnectionStateChange((state) => {
|
||||||
|
setConnectionState(state);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onGetRelayTimeBtnClick = async () => {
|
||||||
|
if (connectionState !== 'connected') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const time = await getRelayTime(relayNode.peerId);
|
||||||
|
setRelayTime(new Date(time));
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="App">
|
||||||
|
<header>
|
||||||
|
<img src={logo} className="logo" alt="logo" />
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div className="content">
|
||||||
|
<h1>
|
||||||
|
Connection state: <span id="status">{connectionState}</span>
|
||||||
|
</h1>
|
||||||
|
<button
|
||||||
|
id="btn"
|
||||||
|
className="btn"
|
||||||
|
onClick={onGetRelayTimeBtnClick}
|
||||||
|
disabled={connectionState !== 'connected'}
|
||||||
|
>
|
||||||
|
Get relay time
|
||||||
|
</button>
|
||||||
|
{relayTime && (
|
||||||
|
<>
|
||||||
|
<h2>Relay time:</h2>
|
||||||
|
<div id="relayTime">{relayTime?.toLocaleString() || ''}</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
18
js-client-examples/browser-example/src/index.tsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import './index.css';
|
||||||
|
import App from './App';
|
||||||
|
|
||||||
|
import { Fluence } from '@fluencelabs/js-client.api';
|
||||||
|
import { randomKras } from '@fluencelabs/fluence-network-environment';
|
||||||
|
|
||||||
|
const relayNode = randomKras();
|
||||||
|
|
||||||
|
Fluence.connect(relayNode);
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>,
|
||||||
|
document.getElementById('root'),
|
||||||
|
);
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
16
js-client-examples/hello-world/jest.config.cjs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||||
|
module.exports = {
|
||||||
|
extensionsToTreatAsEsm: ['.ts'],
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^(\\.{1,2}/.*)\\.js$': '$1',
|
||||||
|
},
|
||||||
|
testPathIgnorePatterns: ['dist'],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.tsx?$': [
|
||||||
|
'ts-jest',
|
||||||
|
{
|
||||||
|
useESM: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
48867
js-client-examples/hello-world/package-lock.json
generated
Normal file
32
js-client-examples/hello-world/package.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "hello-world",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"type": "module",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"prestart": "npm run compile-aqua",
|
||||||
|
"prebuild": "npm run compile-aqua",
|
||||||
|
"start": "node --loader ts-node/esm ./src/index.ts",
|
||||||
|
"build": "tsc",
|
||||||
|
"test": "jest",
|
||||||
|
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||||
|
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@fluencelabs/cli": "0.2.41",
|
||||||
|
"@fluencelabs/aqua-lib": "0.6.0",
|
||||||
|
"ts-node": "10.9.1",
|
||||||
|
"typescript": "^4.6.3",
|
||||||
|
"@types/jest": "29.4.0",
|
||||||
|
"jest": "29.4.1",
|
||||||
|
"ts-jest": "29.0.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fluencelabs/js-client.api": "0.11.2",
|
||||||
|
"@fluencelabs/js-client.node": "0.6.4",
|
||||||
|
"@fluencelabs/fluence-network-environment": "1.0.14"
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { main } from '../main';
|
import { main } from '../main.js';
|
||||||
|
|
||||||
describe('smoke test', () => {
|
describe('smoke test', () => {
|
||||||
it('should work', async () => {
|
it('should work', async () => {
|
3
js-client-examples/hello-world/src/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { main } from './main.js';
|
||||||
|
|
||||||
|
main().catch((e) => console.error('error: ', e));
|
@ -1,9 +1,10 @@
|
|||||||
import { Fluence } from '@fluencelabs/fluence';
|
import '@fluencelabs/js-client.node';
|
||||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
import { Fluence } from '@fluencelabs/js-client.api';
|
||||||
import { registerHelloWorld, sayHello, getRelayTime, tellFortune } from './_aqua/hello-world';
|
import { randomKras } from '@fluencelabs/fluence-network-environment';
|
||||||
|
import { registerHelloWorld, sayHello, getRelayTime, tellFortune } from './_aqua/hello-world.js';
|
||||||
|
|
||||||
export async function main() {
|
export async function main() {
|
||||||
await Fluence.start({ connectTo: krasnodar[0] });
|
await Fluence.connect(randomKras());
|
||||||
|
|
||||||
registerHelloWorld({
|
registerHelloWorld({
|
||||||
hello: (str) => {
|
hello: (str) => {
|
||||||
@ -25,5 +26,5 @@ export async function main() {
|
|||||||
|
|
||||||
console.log('The relay time is: ', new Date(relayTime).toLocaleString());
|
console.log('The relay time is: ', new Date(relayTime).toLocaleString());
|
||||||
|
|
||||||
await Fluence.stop();
|
await Fluence.disconnect();
|
||||||
}
|
}
|
18
js-client-examples/hello-world/tsconfig.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["es2015", "dom"],
|
||||||
|
"outDir": "./dist/",
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": false,
|
||||||
|
"sourceMap": true,
|
||||||
|
"moduleResolution": "nodenext"
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "dist"],
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
@ -28,3 +28,4 @@ yarn-error.log*
|
|||||||
# fluence
|
# fluence
|
||||||
|
|
||||||
src/_aqua/*
|
src/_aqua/*
|
||||||
|
.fluence/
|
16
js-client-examples/node-example/jest.config.cjs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
||||||
|
module.exports = {
|
||||||
|
extensionsToTreatAsEsm: ['.ts'],
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^(\\.{1,2}/.*)\\.js$': '$1',
|
||||||
|
},
|
||||||
|
testPathIgnorePatterns: ['dist'],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.tsx?$': [
|
||||||
|
'ts-jest',
|
||||||
|
{
|
||||||
|
useESM: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
48855
js-client-examples/node-example/package-lock.json
generated
Normal file
30
js-client-examples/node-example/package.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "node-example",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"prestart": "npm run compile-aqua",
|
||||||
|
"prebuild": "npm run compile-aqua",
|
||||||
|
"start": "node --loader ts-node/esm ./src/index.ts",
|
||||||
|
"build": "tsc",
|
||||||
|
"test": "jest",
|
||||||
|
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||||
|
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@fluencelabs/cli": "0.2.41",
|
||||||
|
"ts-node": "10.9.1",
|
||||||
|
"@types/jest": "29.4.0",
|
||||||
|
"jest": "29.4.1",
|
||||||
|
"ts-jest": "29.0.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@fluencelabs/js-client.api": "0.11.2",
|
||||||
|
"@fluencelabs/js-client.node": "0.6.4",
|
||||||
|
"@fluencelabs/fluence-network-environment": "1.0.14"
|
||||||
|
}
|
||||||
|
}
|
3
js-client-examples/node-example/run_calculation.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
npx fluence run -i ./aqua/demo-calculation.aqua -f 'demoCalculation()'
|
@ -1,5 +1,5 @@
|
|||||||
import { justStop, runServer } from '../main';
|
import { justStop, runServer } from '../main.js';
|
||||||
import { demoCalculation } from '../_aqua/demo-calculation';
|
import { demoCalculation } from '../_aqua/demo-calculation.js';
|
||||||
|
|
||||||
describe('smoke test', () => {
|
describe('smoke test', () => {
|
||||||
it('should work', async () => {
|
it('should work', async () => {
|
5
js-client-examples/node-example/src/index.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { runServer, waitForKeypressAndStop } from './main.js';
|
||||||
|
|
||||||
|
runServer()
|
||||||
|
.then(waitForKeypressAndStop)
|
||||||
|
.catch((e) => console.error('error: ', e));
|
@ -1,6 +1,7 @@
|
|||||||
import { Fluence, KeyPair } from '@fluencelabs/fluence';
|
import '@fluencelabs/js-client.node';
|
||||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
import { Fluence } from '@fluencelabs/js-client.api';
|
||||||
import { registerCalc, CalcDef } from './_aqua/calc';
|
import { kras } from '@fluencelabs/fluence-network-environment';
|
||||||
|
import { registerCalc, CalcDef } from './_aqua/calc.js';
|
||||||
|
|
||||||
class Calc implements CalcDef {
|
class Calc implements CalcDef {
|
||||||
private _state: number = 0;
|
private _state: number = 0;
|
||||||
@ -30,33 +31,40 @@ class Calc implements CalcDef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const relay = krasnodar[0];
|
const relay = kras[0];
|
||||||
|
|
||||||
// generated with `npx aqua create_keypair`
|
// generated with `npx aqua create_keypair`
|
||||||
const skBytes = 'tOpsT08fvYMnRypj3VtSoqWMN5W/AptKsP39yanlkg4=';
|
const skBase64 = 'tOpsT08fvYMnRypj3VtSoqWMN5W/AptKsP39yanlkg4=';
|
||||||
|
|
||||||
export async function runServer() {
|
export async function runServer() {
|
||||||
await Fluence.start({
|
const skBytes = Buffer.from(skBase64, 'base64');
|
||||||
connectTo: relay,
|
|
||||||
KeyPair: await KeyPair.fromEd25519SK(Buffer.from(skBytes, 'base64')),
|
await Fluence.connect(relay, {
|
||||||
|
keyPair: {
|
||||||
|
type: 'Ed25519',
|
||||||
|
source: Uint8Array.from(skBytes),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
registerCalc(new Calc());
|
registerCalc(new Calc());
|
||||||
|
|
||||||
|
const client = await Fluence.getClient();
|
||||||
|
|
||||||
console.log('application started');
|
console.log('application started');
|
||||||
console.log('peer id is: ', Fluence.getStatus().peerId);
|
console.log('peer id is: ', client.getPeerId());
|
||||||
console.log('relay is: ', Fluence.getStatus().relayPeerId);
|
console.log('relay is: ', client.getRelayPeerId());
|
||||||
console.log('press any key to quit...');
|
console.log('press any key to quit...');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function justStop() {
|
export async function justStop() {
|
||||||
await Fluence.stop();
|
await Fluence.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function waitForKeypressAndStop() {
|
export async function waitForKeypressAndStop() {
|
||||||
process.stdin.setRawMode(true);
|
process.stdin.setRawMode(true);
|
||||||
process.stdin.resume();
|
process.stdin.resume();
|
||||||
process.stdin.on('data', async () => {
|
process.stdin.on('data', async () => {
|
||||||
await Fluence.stop();
|
await Fluence.disconnect();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
18
js-client-examples/node-example/tsconfig.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["es2015", "dom"],
|
||||||
|
"outDir": "./dist/",
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": false,
|
||||||
|
"sourceMap": true,
|
||||||
|
"moduleResolution": "nodenext"
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "dist"],
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
@ -6,5 +6,5 @@ service HelloPeer("HelloPeer"):
|
|||||||
|
|
||||||
func sayHello(targetPeerId: PeerId, targetRelayPeerId: PeerId) -> string:
|
func sayHello(targetPeerId: PeerId, targetRelayPeerId: PeerId) -> string:
|
||||||
on targetPeerId via targetRelayPeerId:
|
on targetPeerId via targetRelayPeerId:
|
||||||
res <- HelloPeer.hello(%init_peer_id%)
|
res <- HelloPeer.hello(INIT_PEER_ID)
|
||||||
<- res
|
<- res
|
||||||
|
24548
quickstart/1-browser-to-browser/package-lock.json
generated
@ -3,7 +3,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluencelabs/fluence": "0.28.0",
|
"@fluencelabs/js-client.api": "0.11.2",
|
||||||
"@fluencelabs/fluence-network-environment": "1.0.14",
|
"@fluencelabs/fluence-network-environment": "1.0.14",
|
||||||
"@testing-library/jest-dom": "^5.14.1",
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
"@testing-library/react": "^11.2.7",
|
"@testing-library/react": "^11.2.7",
|
||||||
@ -20,7 +20,6 @@
|
|||||||
"web-vitals": "^1.1.2"
|
"web-vitals": "^1.1.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "copy-marine public",
|
|
||||||
"prestart": "npm run compile-aqua",
|
"prestart": "npm run compile-aqua",
|
||||||
"prebuild": "npm run compile-aqua",
|
"prebuild": "npm run compile-aqua",
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
@ -28,8 +27,8 @@
|
|||||||
"test": "jest --config=jest.config.js",
|
"test": "jest --config=jest.config.js",
|
||||||
"_test": "react-scripts test",
|
"_test": "react-scripts test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
@ -52,13 +51,12 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fluencelabs/aqua": "0.9.4",
|
"@fluencelabs/cli": "0.2.41",
|
||||||
"@fluencelabs/aqua-lib": "0.6.0",
|
"@fluencelabs/aqua-lib": "0.6.0",
|
||||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||||
"@types/puppeteer": "^5.4.4",
|
"@types/puppeteer": "^5.4.4",
|
||||||
"chokidar-cli": "^2.1.0",
|
|
||||||
"jest-puppeteer": "^6.0.2",
|
"jest-puppeteer": "^6.0.2",
|
||||||
"node-sass": "^6.0.1",
|
"sass": "^1.58.3",
|
||||||
"serve": "^13.0.2",
|
"serve": "^13.0.2",
|
||||||
"ts-jest": "^27.1.3"
|
"ts-jest": "^27.1.3"
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
<head>
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<!--
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
|
<!--
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||||
-->
|
-->
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
Only files inside the `public` folder can be referenced from the HTML.
|
||||||
@ -20,12 +21,15 @@
|
|||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>Fluence getting started</title>
|
<title>Fluence getting started</title>
|
||||||
</head>
|
<script src='https://cdn.jsdelivr.net/npm/@fluencelabs/js-client.web.standalone@0.13.3/dist/js-client.min.js'
|
||||||
<body>
|
async></script>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
</head>
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<!--
|
||||||
This HTML file is a template.
|
This HTML file is a template.
|
||||||
If you open it directly in the browser, you will see an empty page.
|
If you open it directly in the browser, you will see an empty page.
|
||||||
|
|
||||||
@ -35,5 +39,6 @@
|
|||||||
To begin the development, run `npm start` or `yarn start`.
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
-->
|
-->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
@ -2,23 +2,40 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import logo from './logo.svg';
|
import logo from './logo.svg';
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
|
|
||||||
import { Fluence } from '@fluencelabs/fluence';
|
import { Fluence } from '@fluencelabs/js-client.api';
|
||||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
import type { ConnectionState } from '@fluencelabs/js-client.api';
|
||||||
|
import { kras } from '@fluencelabs/fluence-network-environment';
|
||||||
import { sayHello, registerHelloPeer } from './_aqua/getting-started';
|
import { sayHello, registerHelloPeer } from './_aqua/getting-started';
|
||||||
|
|
||||||
const relayNodes = [krasnodar[4], krasnodar[5], krasnodar[6]];
|
const relayNodes = [kras[4], kras[5], kras[6]];
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [isConnected, setIsConnected] = useState<boolean>(false);
|
const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
|
||||||
|
const [peerInfo, setPeerInfo] = useState<{ peerId: string; relayPeerId: string } | null>(null);
|
||||||
const [helloMessage, setHelloMessage] = useState<string | null>(null);
|
const [helloMessage, setHelloMessage] = useState<string | null>(null);
|
||||||
|
|
||||||
const [peerIdInput, setPeerIdInput] = useState<string>('');
|
const [peerIdInput, setPeerIdInput] = useState<string>('');
|
||||||
const [relayPeerIdInput, setRelayPeerIdInput] = useState<string>('');
|
const [relayPeerIdInput, setRelayPeerIdInput] = useState<string>('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
Fluence.onConnectionStateChange((state) => {
|
||||||
|
console.log('Connection state changed to: ', state);
|
||||||
|
setConnectionState(state);
|
||||||
|
|
||||||
|
if (state === 'connected') {
|
||||||
|
Fluence.getClient().then((client) => {
|
||||||
|
const peerId = client.getPeerId();
|
||||||
|
const relayPeerId = client.getRelayPeerId();
|
||||||
|
setPeerInfo({ peerId, relayPeerId });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const connect = async (relayPeerId: string) => {
|
const connect = async (relayPeerId: string) => {
|
||||||
try {
|
try {
|
||||||
await Fluence.start({ connectTo: relayPeerId });
|
await Fluence.connect(relayPeerId);
|
||||||
setIsConnected(true);
|
|
||||||
// Register handler for this call in aqua:
|
// Register handler for this call in aqua:
|
||||||
// HelloPeer.hello(%init_peer_id%)
|
// HelloPeer.hello(%init_peer_id%)
|
||||||
registerHelloPeer({
|
registerHelloPeer({
|
||||||
@ -28,20 +45,22 @@ function App() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Peer initialization failed', err);
|
console.log('Client could not connect', err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const helloBtnOnClick = async () => {
|
const helloBtnOnClick = async () => {
|
||||||
if (!Fluence.getStatus().isConnected) {
|
if (connectionState !== 'connected') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using aqua is as easy as calling a javascript funсtion
|
// Using aqua is as easy as calling a javascript function
|
||||||
const res = await sayHello(peerIdInput, relayPeerIdInput);
|
const res = await sayHello(peerIdInput, relayPeerIdInput);
|
||||||
setHelloMessage(res);
|
setHelloMessage(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isConnected = connectionState === 'connected';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<header>
|
<header>
|
||||||
@ -49,20 +68,20 @@ function App() {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className="content">
|
<div className="content">
|
||||||
|
<h1>{connectionState}</h1>
|
||||||
{isConnected ? (
|
{isConnected ? (
|
||||||
<>
|
<>
|
||||||
<h1>Connected</h1>
|
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="bold">Peer id:</td>
|
<td className="bold">Peer id:</td>
|
||||||
<td className="mono">
|
<td className="mono">
|
||||||
<span id="peerId">{Fluence.getStatus().peerId!}</span>
|
<span id="peerId">{peerInfo?.peerId}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
className="btn-clipboard"
|
className="btn-clipboard"
|
||||||
onClick={() => copyToClipboard(Fluence.getStatus().peerId!)}
|
onClick={() => copyToClipboard(peerInfo?.peerId)}
|
||||||
>
|
>
|
||||||
<i className="gg-clipboard"></i>
|
<i className="gg-clipboard"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -71,12 +90,12 @@ function App() {
|
|||||||
<tr>
|
<tr>
|
||||||
<td className="bold">Relay peer id:</td>
|
<td className="bold">Relay peer id:</td>
|
||||||
<td className="mono">
|
<td className="mono">
|
||||||
<span id="relayId">{Fluence.getStatus().relayPeerId}</span>
|
<span id="relayId">{peerInfo?.relayPeerId}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
className="btn-clipboard"
|
className="btn-clipboard"
|
||||||
onClick={() => copyToClipboard(Fluence.getStatus().relayPeerId!)}
|
onClick={() => copyToClipboard(peerInfo?.relayPeerId)}
|
||||||
>
|
>
|
||||||
<i className="gg-clipboard"></i>
|
<i className="gg-clipboard"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -146,8 +165,10 @@ function App() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyToClipboard = (text: string) => {
|
const copyToClipboard = (text?: string) => {
|
||||||
navigator.clipboard.writeText(text);
|
if (text) {
|
||||||
|
navigator.clipboard.writeText(text);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
24548
quickstart/3-browser-to-service/package-lock.json
generated
@ -3,7 +3,7 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluencelabs/fluence": "0.28.0",
|
"@fluencelabs/js-client.api": "0.11.2",
|
||||||
"@fluencelabs/fluence-network-environment": "1.0.14",
|
"@fluencelabs/fluence-network-environment": "1.0.14",
|
||||||
"@testing-library/jest-dom": "^5.14.1",
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
"@testing-library/react": "^11.2.7",
|
"@testing-library/react": "^11.2.7",
|
||||||
@ -19,7 +19,6 @@
|
|||||||
"web-vitals": "^1.1.2"
|
"web-vitals": "^1.1.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "copy-marine public",
|
|
||||||
"prestart": "npm run compile-aqua",
|
"prestart": "npm run compile-aqua",
|
||||||
"prebuild": "npm run compile-aqua",
|
"prebuild": "npm run compile-aqua",
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
@ -27,8 +26,8 @@
|
|||||||
"test": "jest --config=jest.config.js",
|
"test": "jest --config=jest.config.js",
|
||||||
"_test": "react-scripts test",
|
"_test": "react-scripts test",
|
||||||
"eject": "react-scripts eject",
|
"eject": "react-scripts eject",
|
||||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
"compile-aqua": "fluence aqua -i ./aqua/ -o ./src/_aqua",
|
||||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
"watch-aqua": "fluence aqua -w -i ./aqua/ -o ./src/_aqua"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
@ -51,14 +50,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fluencelabs/aqua": "0.9.4",
|
"@fluencelabs/cli": "0.2.41",
|
||||||
"@fluencelabs/aqua-lib": "0.6.0",
|
"@fluencelabs/aqua-lib": "0.6.0",
|
||||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||||
"@types/puppeteer": "^5.4.4",
|
"@types/puppeteer": "^5.4.4",
|
||||||
"@types/serve-handler": "^6.1.1",
|
"@types/serve-handler": "^6.1.1",
|
||||||
"chokidar-cli": "^2.1.0",
|
|
||||||
"jest-puppeteer": "^6.0.2",
|
"jest-puppeteer": "^6.0.2",
|
||||||
"node-sass": "^6.0.1",
|
"sass": "^1.58.3",
|
||||||
"serve": "^13.0.2",
|
"serve": "^13.0.2",
|
||||||
"ts-jest": "^27.1.3"
|
"ts-jest": "^27.1.3"
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
<head>
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
<meta name="theme-color" content="#000000" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<!--
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
|
<!--
|
||||||
manifest.json provides metadata used when your web app is installed on a
|
manifest.json provides metadata used when your web app is installed on a
|
||||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||||
-->
|
-->
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
Only files inside the `public` folder can be referenced from the HTML.
|
||||||
@ -20,12 +21,15 @@
|
|||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>Fluence getting started</title>
|
<title>Fluence getting started</title>
|
||||||
</head>
|
<script src='https://cdn.jsdelivr.net/npm/@fluencelabs/js-client.web.standalone@0.13.3/dist/js-client.min.js'
|
||||||
<body>
|
async></script>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
</head>
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
<body>
|
||||||
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<!--
|
||||||
This HTML file is a template.
|
This HTML file is a template.
|
||||||
If you open it directly in the browser, you will see an empty page.
|
If you open it directly in the browser, you will see an empty page.
|
||||||
|
|
||||||
@ -35,5 +39,6 @@
|
|||||||
To begin the development, run `npm start` or `yarn start`.
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
-->
|
-->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
@ -1,24 +1,41 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import logo from './logo.svg';
|
import logo from './logo.svg';
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
|
|
||||||
import { Fluence } from '@fluencelabs/fluence';
|
import { Fluence } from '@fluencelabs/js-client.api';
|
||||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
import type { ConnectionState } from '@fluencelabs/js-client.api';
|
||||||
import { registerHelloPeer, sayHello } from './_aqua/getting-started';
|
import { kras } from '@fluencelabs/fluence-network-environment';
|
||||||
|
import { sayHello, registerHelloPeer } from './_aqua/getting-started';
|
||||||
|
|
||||||
const relayNodes = [krasnodar[3], krasnodar[4], krasnodar[5]];
|
const relayNodes = [kras[4], kras[5], kras[6]];
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [isConnected, setIsConnected] = useState<boolean>(false);
|
const [connectionState, setConnectionState] = useState<ConnectionState>('disconnected');
|
||||||
|
const [peerInfo, setPeerInfo] = useState<{ peerId: string; relayPeerId: string } | null>(null);
|
||||||
const [helloMessage, setHelloMessage] = useState<string | null>(null);
|
const [helloMessage, setHelloMessage] = useState<string | null>(null);
|
||||||
|
|
||||||
const [peerIdInput, setPeerIdInput] = useState<string>('');
|
const [peerIdInput, setPeerIdInput] = useState<string>('');
|
||||||
const [relayPeerIdInput, setRelayPeerIdInput] = useState<string>('');
|
const [relayPeerIdInput, setRelayPeerIdInput] = useState<string>('');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
Fluence.onConnectionStateChange((state) => {
|
||||||
|
console.log('Connection state changed to: ', state);
|
||||||
|
setConnectionState(state);
|
||||||
|
|
||||||
|
if (state === 'connected') {
|
||||||
|
Fluence.getClient().then((client) => {
|
||||||
|
const peerId = client.getPeerId();
|
||||||
|
const relayPeerId = client.getRelayPeerId();
|
||||||
|
setPeerInfo({ peerId, relayPeerId });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
const connect = async (relayPeerId: string) => {
|
const connect = async (relayPeerId: string) => {
|
||||||
try {
|
try {
|
||||||
await Fluence.start({ connectTo: relayPeerId });
|
await Fluence.connect(relayPeerId);
|
||||||
setIsConnected(true);
|
|
||||||
// Register handler for this call in aqua:
|
// Register handler for this call in aqua:
|
||||||
// HelloPeer.hello(%init_peer_id%)
|
// HelloPeer.hello(%init_peer_id%)
|
||||||
registerHelloPeer({
|
registerHelloPeer({
|
||||||
@ -28,20 +45,22 @@ function App() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log('Peer initialization failed', err);
|
console.log('Client could not connect', err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const helloBtnOnClick = async () => {
|
const helloBtnOnClick = async () => {
|
||||||
if (!isConnected) {
|
if (connectionState !== 'connected') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Using aqua is as easy as calling a javascript funсtion
|
// Using aqua is as easy as calling a javascript function
|
||||||
const res = await sayHello(peerIdInput, relayPeerIdInput);
|
const res = await sayHello(peerIdInput, relayPeerIdInput);
|
||||||
setHelloMessage(res);
|
setHelloMessage(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isConnected = connectionState === 'connected';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<header>
|
<header>
|
||||||
@ -49,20 +68,20 @@ function App() {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className="content">
|
<div className="content">
|
||||||
|
<h1>{connectionState}</h1>
|
||||||
{isConnected ? (
|
{isConnected ? (
|
||||||
<>
|
<>
|
||||||
<h1>Connected</h1>
|
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td className="bold">Peer id:</td>
|
<td className="bold">Peer id:</td>
|
||||||
<td className="mono">
|
<td className="mono">
|
||||||
<span id="peerId">{Fluence.getStatus().peerId!}</span>
|
<span id="peerId">{peerInfo?.peerId}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
className="btn-clipboard"
|
className="btn-clipboard"
|
||||||
onClick={() => copyToClipboard(Fluence.getStatus().peerId!)}
|
onClick={() => copyToClipboard(peerInfo?.peerId)}
|
||||||
>
|
>
|
||||||
<i className="gg-clipboard"></i>
|
<i className="gg-clipboard"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -71,12 +90,12 @@ function App() {
|
|||||||
<tr>
|
<tr>
|
||||||
<td className="bold">Relay peer id:</td>
|
<td className="bold">Relay peer id:</td>
|
||||||
<td className="mono">
|
<td className="mono">
|
||||||
<span id="relayId">{Fluence.getStatus().relayPeerId!}</span>
|
<span id="relayId">{peerInfo?.relayPeerId}</span>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button
|
<button
|
||||||
className="btn-clipboard"
|
className="btn-clipboard"
|
||||||
onClick={() => copyToClipboard(Fluence.getStatus().relayPeerId!)}
|
onClick={() => copyToClipboard(peerInfo?.relayPeerId)}
|
||||||
>
|
>
|
||||||
<i className="gg-clipboard"></i>
|
<i className="gg-clipboard"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -146,8 +165,10 @@ function App() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyToClipboard = (text: string) => {
|
const copyToClipboard = (text?: string) => {
|
||||||
navigator.clipboard.writeText(text);
|
if (text) {
|
||||||
|
navigator.clipboard.writeText(text);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|