mirror of
https://github.com/fluencelabs/examples
synced 2024-12-04 19:20:17 +00:00
Integration tests for all JS-related projects (#97)
This commit is contained in:
parent
c991d0d153
commit
178cc42847
44
.github/dependabot.yaml
vendored
44
.github/dependabot.yaml
vendored
@ -59,6 +59,40 @@ updates:
|
||||
- dependency-name: "@fluencelabs/fluence-network-environment"
|
||||
- dependency-name: "@fluencelabs/aqua"
|
||||
- dependency-name: "@fluencelabs/aqua-lib"
|
||||
- dependency-name: "@fluencelabs/aqua-ipfs"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/aqua-examples/aqua-ipfs-integration/nodejs"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
allow:
|
||||
- dependency-name: "@fluencelabs/fluence"
|
||||
- dependency-name: "@fluencelabs/fluence-network-environment"
|
||||
- dependency-name: "@fluencelabs/aqua"
|
||||
- dependency-name: "@fluencelabs/aqua-lib"
|
||||
- dependency-name: "@fluencelabs/aqua-ipfs"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/aqua-examples/aqua-ipfs-integration/web"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
allow:
|
||||
- dependency-name: "@fluencelabs/fluence"
|
||||
- dependency-name: "@fluencelabs/fluence-network-environment"
|
||||
- dependency-name: "@fluencelabs/aqua"
|
||||
- dependency-name: "@fluencelabs/aqua-lib"
|
||||
- dependency-name: "@fluencelabs/aqua-ipfs"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/aqua-examples/aqua-ipfs-integration/aqua"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
allow:
|
||||
- dependency-name: "@fluencelabs/fluence"
|
||||
- dependency-name: "@fluencelabs/fluence-network-environment"
|
||||
- dependency-name: "@fluencelabs/aqua"
|
||||
- dependency-name: "@fluencelabs/aqua-lib"
|
||||
- dependency-name: "@fluencelabs/aqua-ipfs"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/aqua-examples/echo-greeter/client-peer"
|
||||
@ -79,3 +113,13 @@ updates:
|
||||
- dependency-name: "@fluencelabs/fluence-network-environment"
|
||||
- dependency-name: "@fluencelabs/aqua"
|
||||
- dependency-name: "@fluencelabs/aqua-lib"
|
||||
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/aqua-examples/price-oracle/web"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
allow:
|
||||
- dependency-name: "@fluencelabs/fluence"
|
||||
- dependency-name: "@fluencelabs/fluence-network-environment"
|
||||
- dependency-name: "@fluencelabs/aqua"
|
||||
- dependency-name: "@fluencelabs/aqua-lib"
|
||||
|
65
.github/workflows/test-aqua-ipfs-integration.yml
vendored
Normal file
65
.github/workflows/test-aqua-ipfs-integration.yml
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
name: Run tests for "aqua ipfs integration" project
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
### Prepare cargo & toolchains
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
~/.cargo/bin
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-v2-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: Install Rust toolchain with wasm32-unknown-unknown
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-2021-07-13
|
||||
target: wasm32-unknown-unknown
|
||||
profile: minimal
|
||||
override: true
|
||||
- name: Install wasm32-wasi
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-2021-07-13
|
||||
target: wasm32-wasi
|
||||
profile: minimal
|
||||
|
||||
- name: Install marine
|
||||
run: cargo install marine || true
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-v1-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-v1-node-${{ matrix.node-version }}
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
### === Rust tests ===
|
||||
- name: run tests
|
||||
working-directory:
|
||||
./aqua-examples/aqua-ipfs-integration
|
||||
env:
|
||||
CI: true
|
||||
run: |
|
||||
npm i
|
||||
CI=false npm run build
|
||||
npm run test -w nodejs
|
||||
npm run test -w web
|
73
.github/workflows/test-js-projects.yml
vendored
Normal file
73
.github/workflows/test-js-projects.yml
vendored
Normal file
@ -0,0 +1,73 @@
|
||||
name: Run tests for js-based projects
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x]
|
||||
working-directory: [
|
||||
"./quickstart/1-browser-to-browser",
|
||||
"./quickstart/3-browser-to-service",
|
||||
"./fluence-js-examples/hello-world",
|
||||
"./fluence-js-examples/browser-example",
|
||||
"./fluence-js-examples/node-example",
|
||||
"./aqua-examples/echo-greeter/client-peer",
|
||||
"./aqua-examples/price-oracle/client-peer",
|
||||
"./aqua-examples/price-oracle/web"
|
||||
]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
### Prepare cargo & toolchains
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
~/.cargo/bin
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-v2-${{ hashFiles('**/Cargo.lock') }}
|
||||
- name: Install Rust toolchain with wasm32-unknown-unknown
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-2021-07-13
|
||||
target: wasm32-unknown-unknown
|
||||
profile: minimal
|
||||
override: true
|
||||
- name: Install wasm32-wasi
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly-2021-07-13
|
||||
target: wasm32-wasi
|
||||
profile: minimal
|
||||
|
||||
- name: Install marine
|
||||
run: cargo install marine || true
|
||||
|
||||
- uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: ${{ runner.os }}-v1-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-v1-node-${{ matrix.node-version }}
|
||||
|
||||
- name: Setup Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
### === Rust tests ===
|
||||
- name: run tests
|
||||
working-directory: ${{ matrix.working-directory }}
|
||||
env:
|
||||
CI: true
|
||||
run: |
|
||||
npm i
|
||||
CI=false npm run build
|
||||
npm run test
|
8
aqua-examples/aqua-ipfs-integration/.prettierrc.js
Normal file
8
aqua-examples/aqua-ipfs-integration/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
@ -22,7 +22,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fluencelabs/aqua-ipfs": "0.5.2",
|
||||
"@fluencelabs/fluence": "0.19.1",
|
||||
"@fluencelabs/fluence": "0.19.2",
|
||||
"@fluencelabs/fluence-network-environment": "1.0.13",
|
||||
"ipfs-http-client": "^50.1.2",
|
||||
"it-all": "^1.0.5",
|
||||
@ -30,7 +30,7 @@
|
||||
"uint8arrays": "^2.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-278",
|
||||
"@fluencelabs/aqua": "^0.6.1-279",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"typescript": "^4.5.5"
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testPathIgnorePatterns: ['dist'],
|
||||
};
|
@ -1,41 +1,46 @@
|
||||
{
|
||||
"name": "@fluencelabs/ipfs-execution",
|
||||
"version": "0.1.0",
|
||||
"description": "An example of executing WASM code from IPFS over IPFS files",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"prestart": "npm run build",
|
||||
"start:local": "node dist/demo.js local",
|
||||
"start:remote": "node dist/demo.js krasnodar",
|
||||
"start": "npm run start:remote"
|
||||
},
|
||||
"keywords": [
|
||||
"fluence",
|
||||
"wasm",
|
||||
"ipfs",
|
||||
"functions",
|
||||
"faas",
|
||||
"decentralization",
|
||||
"p2p",
|
||||
"libp2p"
|
||||
],
|
||||
"author": "Fluence Labs",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fluencelabs/ipfs-execution-aqua": "file:../aqua",
|
||||
"@fluencelabs/fluence": "0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.0.13",
|
||||
"@fluencelabs/aqua-lib": "0.4.0",
|
||||
"@fluencelabs/aqua-ipfs": "0.5.2",
|
||||
"ipfs-http-client": "^50.1.2",
|
||||
"it-all": "^1.0.5",
|
||||
"uint8arrays": "^2.1.5",
|
||||
"multiaddr": "^10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-278",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"typescript": "^4.5.5"
|
||||
}
|
||||
"name": "@fluencelabs/ipfs-execution",
|
||||
"version": "0.1.0",
|
||||
"description": "An example of executing WASM code from IPFS over IPFS files",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"prestart": "npm run build",
|
||||
"start:local": "node dist/demo.js local",
|
||||
"start:remote": "node dist/demo.js krasnodar",
|
||||
"start": "npm run start:remote",
|
||||
"test": "jest"
|
||||
},
|
||||
"keywords": [
|
||||
"fluence",
|
||||
"wasm",
|
||||
"ipfs",
|
||||
"functions",
|
||||
"faas",
|
||||
"decentralization",
|
||||
"p2p",
|
||||
"libp2p"
|
||||
],
|
||||
"author": "Fluence Labs",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@fluencelabs/ipfs-execution-aqua": "file:../aqua",
|
||||
"@fluencelabs/fluence": "0.19.2",
|
||||
"@fluencelabs/fluence-network-environment": "1.0.13",
|
||||
"@fluencelabs/aqua-lib": "0.4.0",
|
||||
"@fluencelabs/aqua-ipfs": "0.5.2",
|
||||
"ipfs-http-client": "^50.1.2",
|
||||
"it-all": "^1.0.5",
|
||||
"uint8arrays": "^2.1.5",
|
||||
"multiaddr": "^10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-279",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"typescript": "^4.5.5",
|
||||
"ts-node": "^10.2.1",
|
||||
"@types/jest": "^27.0.3",
|
||||
"jest": "^27.4.0",
|
||||
"ts-jest": "^27.0.7"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
||||
import { main } from '../main';
|
||||
|
||||
describe('smoke test', () => {
|
||||
it('should work', async () => {
|
||||
console.log = jest.fn();
|
||||
|
||||
await main(krasnodar);
|
||||
|
||||
expect(console.log).toBeCalledTimes(16);
|
||||
expect(console.log).toHaveBeenNthCalledWith(
|
||||
13,
|
||||
'📗 uploaded file:',
|
||||
expect.objectContaining({
|
||||
path: 'NZgK6DB.png',
|
||||
size: expect.any(Number),
|
||||
cid: expect.anything(),
|
||||
}),
|
||||
);
|
||||
expect(console.log).toHaveBeenNthCalledWith(
|
||||
15,
|
||||
'📗 File size is saved to IPFS:',
|
||||
expect.objectContaining({
|
||||
error: '',
|
||||
hash: expect.any(String),
|
||||
success: true,
|
||||
}),
|
||||
);
|
||||
}, 20000);
|
||||
});
|
@ -1,143 +1,27 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { provideFile } from "./provider";
|
||||
|
||||
import { Fluence, FluencePeer, setLogLevel } from "@fluencelabs/fluence";
|
||||
import {
|
||||
stage,
|
||||
krasnodar,
|
||||
Node,
|
||||
testNet,
|
||||
} from "@fluencelabs/fluence-network-environment";
|
||||
import {
|
||||
deploy_service,
|
||||
put_file_size,
|
||||
remove_service,
|
||||
set_timeout,
|
||||
} from "@fluencelabs/ipfs-execution-aqua";
|
||||
|
||||
import { globSource, urlSource } from "ipfs-http-client";
|
||||
|
||||
async function main(environment: Node[]) {
|
||||
// setLogLevel('DEBUG');
|
||||
let providerHost = environment[4];
|
||||
let relay = environment[3];
|
||||
let serviceHost = environment[2];
|
||||
|
||||
let providerClient = new FluencePeer();
|
||||
await providerClient.start({ connectTo: providerHost });
|
||||
console.log("📘 uploading .wasm to node %s", providerHost.multiaddr);
|
||||
let path = globSource("../service/artifacts/process_files.wasm");
|
||||
let { file, swarmAddr, rpcAddr } = await provideFile(path, providerClient);
|
||||
console.log("📗 swarmAddr", swarmAddr);
|
||||
console.log("📗 rpcAddr", rpcAddr);
|
||||
|
||||
await Fluence.start({ connectTo: relay });
|
||||
console.log(
|
||||
"📗 created a fluence client %s with relay %s",
|
||||
Fluence.getStatus().peerId,
|
||||
Fluence.getStatus().relayPeerId
|
||||
);
|
||||
|
||||
// default IPFS timeout is 1 sec, set to 10 secs to retrieve file from remote node
|
||||
await set_timeout(serviceHost.peerId, 10);
|
||||
|
||||
console.log("\n\n📘 Will deploy ProcessFiles service");
|
||||
var service_id = await deploy_service(
|
||||
serviceHost.peerId,
|
||||
file.cid.toString(),
|
||||
rpcAddr,
|
||||
(label, error) => {
|
||||
console.error("📕 deploy_service failed: ", label, error);
|
||||
},
|
||||
{ ttl: 10000 }
|
||||
);
|
||||
service_id = fromOption(service_id);
|
||||
if (service_id === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(
|
||||
"📗 ProcessFiles service is now deployed and available as",
|
||||
service_id
|
||||
);
|
||||
|
||||
console.log("\n\n📘 Will upload file & calculate its size");
|
||||
let { file: newFile } = await provideFile(
|
||||
urlSource("https://i.imgur.com/NZgK6DB.png"),
|
||||
providerClient
|
||||
);
|
||||
var putResult = await put_file_size(
|
||||
serviceHost.peerId,
|
||||
newFile.cid.toString(),
|
||||
rpcAddr,
|
||||
service_id,
|
||||
(fileSize) => console.log("📗 Calculated file size:", fileSize),
|
||||
(label, error) => {
|
||||
console.error("📕 put_file_size failed: ", label, error);
|
||||
},
|
||||
{ ttl: 10000 }
|
||||
);
|
||||
putResult = fromOption(putResult);
|
||||
if (putResult !== null) {
|
||||
console.log("📗 File size is saved to IPFS:", putResult);
|
||||
}
|
||||
|
||||
let result = await remove_service(serviceHost.peerId, service_id);
|
||||
console.log("📗 ProcessFiles service removed", result);
|
||||
return;
|
||||
}
|
||||
|
||||
function fromOption<T>(opt: T | T[] | null): T | null {
|
||||
if (Array.isArray(opt)) {
|
||||
if (opt.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
opt = opt[0];
|
||||
}
|
||||
if (opt === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return opt;
|
||||
}
|
||||
import { krasnodar, stage, testNet, Node } from '@fluencelabs/fluence-network-environment';
|
||||
import { main } from './main';
|
||||
|
||||
let args = process.argv.slice(2);
|
||||
var environment: Node[];
|
||||
if (args.length >= 1 && args[0] == "testnet") {
|
||||
environment = testNet;
|
||||
console.log("📘 Will connect to testNet");
|
||||
} else if (args[0] == "stage") {
|
||||
environment = stage;
|
||||
console.log("📘 Will connect to stage");
|
||||
} else if (args[0] == "krasnodar") {
|
||||
environment = krasnodar;
|
||||
console.log("📘 Will connect to krasnodar");
|
||||
} else if (args[0] == "testnet") {
|
||||
environment = testNet;
|
||||
console.log("📘 Will connect to testNet");
|
||||
if (args.length >= 1 && args[0] == 'testnet') {
|
||||
environment = testNet;
|
||||
console.log('📘 Will connect to testNet');
|
||||
} else if (args[0] == 'stage') {
|
||||
environment = stage;
|
||||
console.log('📘 Will connect to stage');
|
||||
} else if (args[0] == 'krasnodar') {
|
||||
environment = krasnodar;
|
||||
console.log('📘 Will connect to krasnodar');
|
||||
} else if (args[0] == 'testnet') {
|
||||
environment = testNet;
|
||||
console.log('📘 Will connect to testNet');
|
||||
} else {
|
||||
throw "Specify environment";
|
||||
throw 'Specify environment';
|
||||
}
|
||||
|
||||
main(environment)
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
106
aqua-examples/aqua-ipfs-integration/nodejs/src/main.ts
Normal file
106
aqua-examples/aqua-ipfs-integration/nodejs/src/main.ts
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2020 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { provideFile } from './provider';
|
||||
|
||||
import { Fluence, FluencePeer } from '@fluencelabs/fluence';
|
||||
import { Node } from '@fluencelabs/fluence-network-environment';
|
||||
import { deploy_service, put_file_size, remove_service, set_timeout } from '@fluencelabs/ipfs-execution-aqua';
|
||||
|
||||
import { globSource, urlSource } from 'ipfs-http-client';
|
||||
|
||||
export async function main(environment: Node[]) {
|
||||
// setLogLevel('DEBUG');
|
||||
let providerHost = environment[4];
|
||||
let relay = environment[3];
|
||||
let serviceHost = environment[2];
|
||||
|
||||
let providerClient = new FluencePeer();
|
||||
await providerClient.start({ connectTo: providerHost });
|
||||
console.log('📘 uploading .wasm to node %s', providerHost.multiaddr);
|
||||
let path = globSource('../service/artifacts/process_files.wasm');
|
||||
let { file, swarmAddr, rpcAddr } = await provideFile(path, providerClient);
|
||||
console.log('📗 swarmAddr', swarmAddr);
|
||||
console.log('📗 rpcAddr', rpcAddr);
|
||||
|
||||
await Fluence.start({ connectTo: relay });
|
||||
console.log(
|
||||
'📗 created a fluence client %s with relay %s',
|
||||
Fluence.getStatus().peerId,
|
||||
Fluence.getStatus().relayPeerId,
|
||||
);
|
||||
|
||||
// default IPFS timeout is 1 sec, set to 10 secs to retrieve file from remote node
|
||||
await set_timeout(serviceHost.peerId, 10);
|
||||
|
||||
console.log('\n\n📘 Will deploy ProcessFiles service');
|
||||
var service_id = await deploy_service(
|
||||
serviceHost.peerId,
|
||||
file.cid.toString(),
|
||||
rpcAddr,
|
||||
(label, error) => {
|
||||
console.error('📕 deploy_service failed: ', label, error);
|
||||
},
|
||||
{ ttl: 10000 },
|
||||
);
|
||||
service_id = fromOption(service_id);
|
||||
if (service_id === null) {
|
||||
await Fluence.stop();
|
||||
await providerClient.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('📗 ProcessFiles service is now deployed and available as', service_id);
|
||||
|
||||
console.log('\n\n📘 Will upload file & calculate its size');
|
||||
let { file: newFile } = await provideFile(urlSource('https://i.imgur.com/NZgK6DB.png'), providerClient);
|
||||
var putResult = await put_file_size(
|
||||
serviceHost.peerId,
|
||||
newFile.cid.toString(),
|
||||
rpcAddr,
|
||||
service_id,
|
||||
(fileSize) => console.log('📗 Calculated file size:', fileSize),
|
||||
(label, error) => {
|
||||
console.error('📕 put_file_size failed: ', label, error);
|
||||
},
|
||||
{ ttl: 10000 },
|
||||
);
|
||||
putResult = fromOption(putResult);
|
||||
if (putResult !== null) {
|
||||
console.log('📗 File size is saved to IPFS:', putResult);
|
||||
}
|
||||
|
||||
let result = await remove_service(serviceHost.peerId, service_id);
|
||||
console.log('📗 ProcessFiles service removed', result);
|
||||
|
||||
await Fluence.stop();
|
||||
await providerClient.stop();
|
||||
}
|
||||
|
||||
function fromOption<T>(opt: T | T[] | null): T | null {
|
||||
if (Array.isArray(opt)) {
|
||||
if (opt.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
opt = opt[0];
|
||||
}
|
||||
if (opt === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return opt;
|
||||
}
|
@ -1,65 +1,50 @@
|
||||
import { create, CID } from "ipfs-http-client";
|
||||
import { AddResult } from "ipfs-core-types/src/root";
|
||||
import { Multiaddr, protocols } from "multiaddr";
|
||||
import { create, CID } from 'ipfs-http-client';
|
||||
import { AddResult } from 'ipfs-core-types/src/root';
|
||||
import { Multiaddr, protocols } from 'multiaddr';
|
||||
|
||||
import { FluencePeer } from "@fluencelabs/fluence";
|
||||
import {
|
||||
get_external_api_multiaddr,
|
||||
get_external_swarm_multiaddr,
|
||||
} from "@fluencelabs/ipfs-execution-aqua";
|
||||
import { FluencePeer } from '@fluencelabs/fluence';
|
||||
import { get_external_api_multiaddr, get_external_swarm_multiaddr } from '@fluencelabs/ipfs-execution-aqua';
|
||||
|
||||
export async function provideFile(
|
||||
source: any,
|
||||
provider: FluencePeer
|
||||
source: any,
|
||||
provider: FluencePeer,
|
||||
): Promise<{ file: AddResult; swarmAddr: string; rpcAddr: string }> {
|
||||
const relayPeerId = provider.getStatus().relayPeerId!;
|
||||
let swarmAddr;
|
||||
let result = await get_external_swarm_multiaddr(
|
||||
provider,
|
||||
provider.getStatus().relayPeerId!,
|
||||
{ ttl: 20000 }
|
||||
);
|
||||
if (result.success) {
|
||||
swarmAddr = result.multiaddr;
|
||||
} else {
|
||||
console.error(
|
||||
"Failed to retrieve external swarm multiaddr from %s: ",
|
||||
provider.getStatus().relayPeerId!
|
||||
);
|
||||
throw result.error;
|
||||
}
|
||||
const relayPeerId = provider.getStatus().relayPeerId!;
|
||||
let swarmAddr;
|
||||
let result = await get_external_swarm_multiaddr(provider, provider.getStatus().relayPeerId!, { ttl: 20000 });
|
||||
if (result.success) {
|
||||
swarmAddr = result.multiaddr;
|
||||
} else {
|
||||
console.error('Failed to retrieve external swarm multiaddr from %s: ', provider.getStatus().relayPeerId!);
|
||||
throw result.error;
|
||||
}
|
||||
|
||||
let rpcAddr;
|
||||
result = await get_external_api_multiaddr(provider, relayPeerId);
|
||||
if (result.success) {
|
||||
rpcAddr = result.multiaddr;
|
||||
} else {
|
||||
console.error(
|
||||
"Failed to retrieve external api multiaddr from %s: ",
|
||||
relayPeerId
|
||||
);
|
||||
throw result.error;
|
||||
}
|
||||
let rpcAddr;
|
||||
result = await get_external_api_multiaddr(provider, relayPeerId);
|
||||
if (result.success) {
|
||||
rpcAddr = result.multiaddr;
|
||||
} else {
|
||||
console.error('Failed to retrieve external api multiaddr from %s: ', relayPeerId);
|
||||
throw result.error;
|
||||
}
|
||||
|
||||
let rpcMaddr = new Multiaddr(rpcAddr).decapsulateCode(
|
||||
protocols.names.p2p.code
|
||||
);
|
||||
// HACK: `as any` is needed because ipfs-http-client forgot to add `| Multiaddr` to the `create` types
|
||||
const ipfs = create(rpcMaddr as any);
|
||||
console.log("📗 created ipfs client to %s", rpcMaddr);
|
||||
let rpcMaddr = new Multiaddr(rpcAddr).decapsulateCode(protocols.names.p2p.code);
|
||||
// HACK: `as any` is needed because ipfs-http-client forgot to add `| Multiaddr` to the `create` types
|
||||
const ipfs = create(rpcMaddr as any);
|
||||
console.log('📗 created ipfs client to %s', rpcMaddr);
|
||||
|
||||
await ipfs.id();
|
||||
console.log("📗 connected to ipfs");
|
||||
await ipfs.id();
|
||||
console.log('📗 connected to ipfs');
|
||||
|
||||
const file = await ipfs.add(source);
|
||||
console.log("📗 uploaded file:", file);
|
||||
const file = await ipfs.add(source);
|
||||
console.log('📗 uploaded file:', file);
|
||||
|
||||
// To download the file, uncomment the following code:
|
||||
// let files = await ipfs.get(file.cid);
|
||||
// for await (const file of files) {
|
||||
// const content = uint8ArrayConcat(await all(file.content));
|
||||
// console.log("📗 downloaded file of length ", content.length);
|
||||
// }
|
||||
// To download the file, uncomment the following code:
|
||||
// let files = await ipfs.get(file.cid);
|
||||
// for await (const file of files) {
|
||||
// const content = uint8ArrayConcat(await all(file.content));
|
||||
// console.log("📗 downloaded file of length ", content.length);
|
||||
// }
|
||||
|
||||
return { file, swarmAddr, rpcAddr };
|
||||
return { file, swarmAddr, rpcAddr };
|
||||
}
|
||||
|
77136
aqua-examples/aqua-ipfs-integration/package-lock.json
generated
77136
aqua-examples/aqua-ipfs-integration/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,23 +1,24 @@
|
||||
{
|
||||
"name": "aqua-ipfs-integration",
|
||||
"workspaces": [
|
||||
"aqua",
|
||||
"nodejs",
|
||||
"web"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "check-node-version --npm '>= 7' && npm run build -w aqua -w nodejs -w web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.19.1",
|
||||
"typescript": "^4.4.4"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=7",
|
||||
"node": ">=15.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"check-node-version": "^4.2.1",
|
||||
"@fluencelabs/avm": "0.20.3"
|
||||
}
|
||||
"name": "aqua-ipfs-integration",
|
||||
"workspaces": [
|
||||
"aqua",
|
||||
"nodejs",
|
||||
"web"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "check-node-version --npm '>= 7' && npm run build -w aqua -w nodejs -w web"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-279",
|
||||
"@fluencelabs/fluence": "0.19.2",
|
||||
"typescript": "^4.4.4"
|
||||
},
|
||||
"engines": {
|
||||
"npm": ">=7",
|
||||
"node": ">=15.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/avm": "0.20.3",
|
||||
"check-node-version": "^4.2.1"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
module Exports
|
||||
|
||||
import "@fluencelabs/aqua-ipfs/ipfs-api.aqua"
|
||||
|
||||
export set_timeout, get_external_swarm_multiaddr, get_external_api_multiaddr
|
@ -1,78 +0,0 @@
|
||||
import "@fluencelabs/aqua-lib/builtin.aqua"
|
||||
import "@fluencelabs/aqua-ipfs/ipfs.aqua"
|
||||
import "process_files.aqua"
|
||||
|
||||
alias PeerId : string
|
||||
alias CID : string
|
||||
alias Multiaddr : string
|
||||
alias Hash : string
|
||||
alias ServiceID : string
|
||||
|
||||
service StringOp("op"):
|
||||
-- function that wraps string in array
|
||||
array(s: string) -> []string
|
||||
|
||||
-- Add module to node
|
||||
func add_module(name: string, path: string) -> Hash:
|
||||
config <- Dist.default_module_config(name)
|
||||
module_hash <- Dist.add_module_from_vault(path, config)
|
||||
<- module_hash
|
||||
|
||||
-- Add service blueprint to node
|
||||
func add_blueprint(module_hash: Hash) -> string:
|
||||
prefixed_hash <- Op.concat_strings("hash:", module_hash)
|
||||
dependencies <- StringOp.array(prefixed_hash)
|
||||
blueprint <- Dist.make_blueprint("process_files", dependencies)
|
||||
blueprint_id <- Dist.add_blueprint(blueprint)
|
||||
<- blueprint_id
|
||||
|
||||
-- Download single .wasm module from IPFS and create a service from it
|
||||
func deploy_service(relay: PeerId, cid: CID, ipfs: Multiaddr, error: string, string -> ()) -> ?ServiceID:
|
||||
service_id: *ServiceID
|
||||
on relay:
|
||||
-- Download .wasm from IPFS to node
|
||||
get_result <- Ipfs.get_from(cid, ipfs)
|
||||
if get_result.success:
|
||||
module_hash <- add_module("process_files", get_result.path)
|
||||
blueprint_id <- add_blueprint(module_hash)
|
||||
service_id <- Srv.create(blueprint_id)
|
||||
else:
|
||||
co error("Ipfs.get_from failed", get_result.error)
|
||||
|
||||
<- service_id
|
||||
|
||||
-- Download file from IPFS, and write it's size to file in IPFS
|
||||
func put_file_size(
|
||||
relay: PeerId,
|
||||
cid: CID,
|
||||
ipfs: Multiaddr,
|
||||
service_id: ServiceID,
|
||||
logSize: u32 -> (),
|
||||
error: string, string -> ()
|
||||
) -> ?IpfsPutResult:
|
||||
result: *IpfsPutResult
|
||||
ProcessFiles service_id
|
||||
on relay:
|
||||
get <- Ipfs.get_from(cid, ipfs)
|
||||
if get.success:
|
||||
size <- ProcessFiles.file_size(get.path)
|
||||
if size.success:
|
||||
-- report file size in background
|
||||
co logSize(size.size)
|
||||
-- write file size to disk
|
||||
write <- ProcessFiles.write_file_size(size.size)
|
||||
if write.success:
|
||||
-- upload file to ipfs
|
||||
result <- Ipfs.put(write.path)
|
||||
else:
|
||||
co error("ProcessFiles.write_file_size failed", write.error)
|
||||
else:
|
||||
co error("ProcessFiles.file_size failed", size.error)
|
||||
else:
|
||||
co error("Ipfs.get_from failed", get.error)
|
||||
<- result
|
||||
|
||||
func remove_service(relay: PeerId, service_id: ServiceID) -> bool:
|
||||
on relay:
|
||||
Srv.remove(service_id)
|
||||
<- true
|
@ -1,15 +0,0 @@
|
||||
module ProcessFiles declares *
|
||||
|
||||
data SizeResult:
|
||||
size: u32
|
||||
success: bool
|
||||
error: string
|
||||
|
||||
data WriteResult:
|
||||
path: string
|
||||
success: bool
|
||||
error: string
|
||||
|
||||
service ProcessFiles:
|
||||
file_size(file_path: string) -> SizeResult
|
||||
write_file_size(size: u32) -> WriteResult
|
8
aqua-examples/aqua-ipfs-integration/web/jest.config.js
Normal file
8
aqua-examples/aqua-ipfs-integration/web/jest.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
preset: 'jest-puppeteer',
|
||||
testMatch: ['**/?(*.)+(spec|test).[t]s'],
|
||||
testPathIgnorePatterns: ['/node_modules/', 'dist'],
|
||||
transform: {
|
||||
'^.+\\.ts?$': 'ts-jest',
|
||||
},
|
||||
};
|
@ -1,54 +1,63 @@
|
||||
{
|
||||
"name": "ipfs-aqua-browser",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/ipfs-execution-aqua": "file:../aqua",
|
||||
"@fluencelabs/fluence": "0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"ipfs-http-client": "^50.1.2",
|
||||
"multiaddr": "^10.0.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"recoil": "^0.3.1",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"node-sass": "^6.0.1",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0"
|
||||
}
|
||||
"name": "ipfs-aqua-browser",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/ipfs-execution-aqua": "file:../aqua",
|
||||
"@fluencelabs/fluence": "0.19.2",
|
||||
"@fluencelabs/fluence-network-environment": "1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"ipfs-http-client": "^50.1.2",
|
||||
"multiaddr": "^10.0.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^5.0.0",
|
||||
"recoil": "^0.3.1",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all",
|
||||
"not ie 11",
|
||||
"not android 4.4.3-4.4.4"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/serve-handler": "^6.1.1",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"node-sass": "^6.0.1",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"jest-puppeteer": "^6.0.2",
|
||||
"serve": "^13.0.2",
|
||||
"ts-jest": "^27.1.3"
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ table {
|
||||
}
|
||||
}
|
||||
|
||||
.input-ro {
|
||||
.input-readonly {
|
||||
display: inline;
|
||||
width: 500px;
|
||||
height: 26px;
|
||||
|
@ -11,7 +11,7 @@ export const ConnectionForm = () => {
|
||||
{relayNodes.map((x) => (
|
||||
<li key={x.peerId}>
|
||||
<span className="mono">{x.peerId}</span>
|
||||
<button className="btn" onClick={() => connect(x.multiaddr)}>
|
||||
<button className="btn btn-connect" onClick={() => connect(x.multiaddr)}>
|
||||
Connect
|
||||
</button>
|
||||
</li>
|
||||
|
@ -31,7 +31,7 @@ export const IpfsForm = () => {
|
||||
setValue={setWasm}
|
||||
/>
|
||||
<div className="row">
|
||||
<button className="btn btn-right" onClick={deployService}>
|
||||
<button id="deploy-service" className="btn btn-right" onClick={deployService}>
|
||||
deploy service
|
||||
</button>
|
||||
</div>
|
||||
|
@ -28,7 +28,7 @@ export const SizeCalcForm = () => {
|
||||
<TextInput text={"IPFS CID"} value={fileCID} setValue={setFileCID} />
|
||||
|
||||
<div className="row">
|
||||
<button className="btn btn-right" onClick={getFileSize}>
|
||||
<button id="get-size" className="btn btn-right" onClick={getFileSize}>
|
||||
get size
|
||||
</button>
|
||||
</div>
|
||||
|
@ -16,7 +16,7 @@ export const SizeCalcResult = () => {
|
||||
CID
|
||||
</p>
|
||||
</div>
|
||||
<TextWithLabel text="File size:" value={fileSize} />
|
||||
<TextWithLabel id="file-size" text="File size:" value={fileSize} />
|
||||
<TextWithLabel text="File size IPFS CID:" value={fileSizeCID} />
|
||||
</>
|
||||
);
|
||||
|
@ -21,12 +21,15 @@ export const TextInput = (props: {
|
||||
|
||||
export const TextWithLabel = (props: {
|
||||
text: string;
|
||||
id?: string;
|
||||
value: string | null;
|
||||
}) => {
|
||||
const idAttr = props.id ? { id: props.id } : {}
|
||||
const attrs = { className: "input-readonly", ...idAttr };
|
||||
return (
|
||||
<div className="row">
|
||||
<label className="label bold">{props.text}</label>
|
||||
<div className="input-ro">{props.value || ""}</div>
|
||||
<div {...attrs}>{props.value || ""}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,63 @@
|
||||
import handler from 'serve-handler';
|
||||
import http from 'http';
|
||||
import path from 'path';
|
||||
|
||||
const port = 3001;
|
||||
const uri = `http://localhost:${port}/`;
|
||||
const publicPath = path.join(__dirname, '../../build/');
|
||||
|
||||
console.log(publicPath);
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
return handler(request, response, {
|
||||
public: publicPath,
|
||||
});
|
||||
});
|
||||
|
||||
const startServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.listen(port, resolve);
|
||||
});
|
||||
};
|
||||
|
||||
const stopServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.close(resolve);
|
||||
});
|
||||
};
|
||||
|
||||
describe('smoke test', () => {
|
||||
beforeAll(startServer);
|
||||
|
||||
afterAll(stopServer);
|
||||
|
||||
it('should work', async () => {
|
||||
console.log('going to the page in browser...');
|
||||
await page.goto(uri);
|
||||
|
||||
console.log('clicking connect button...');
|
||||
await page.click('.btn-connect');
|
||||
|
||||
console.log('waiting for fluence to connect...');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
console.log('waiting for "deploy service" button to appear...');
|
||||
await page.waitForSelector('#deploy-service');
|
||||
|
||||
console.log('clicking "deploy service" button...');
|
||||
await page.click('#deploy-service');
|
||||
|
||||
console.log('waiting for "get size" button to appear...');
|
||||
await page.waitForSelector('#get-size');
|
||||
|
||||
console.log('clicking "get size" button...');
|
||||
await page.click('#get-size');
|
||||
|
||||
console.log('waiting for result to appear...');
|
||||
const sizeEl = await page.waitForSelector('#file-size');
|
||||
|
||||
const size = await sizeEl?.evaluate((x) => x.textContent);
|
||||
|
||||
expect(size).toBe('144804');
|
||||
}, 15000);
|
||||
});
|
8
aqua-examples/echo-greeter/client-peer/.prettierrc.js
Normal file
8
aqua-examples/echo-greeter/client-peer/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
5
aqua-examples/echo-greeter/client-peer/jest.config.js
Normal file
5
aqua-examples/echo-greeter/client-peer/jest.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testPathIgnorePatterns: ['dist'],
|
||||
};
|
22854
aqua-examples/echo-greeter/client-peer/package-lock.json
generated
22854
aqua-examples/echo-greeter/client-peer/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,49 +1,53 @@
|
||||
{
|
||||
"name": "echo-greeter-example",
|
||||
"version": "0.1.0",
|
||||
"description": "Fluence Echo Greeter Example",
|
||||
"main": "./dist/src/index.js",
|
||||
"typings": "./dist/src/index.d.ts",
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"bic": [
|
||||
"client-peer/*",
|
||||
"*.aqua",
|
||||
"package-lock.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"it-all": "^1.0.5"
|
||||
},
|
||||
"scripts": {
|
||||
"compile-aqua": "aqua -i ../aqua -o src/_aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"build": "tsc",
|
||||
"prestart:local": "npm run build",
|
||||
"start:local": "node dist/src/index.js local",
|
||||
"prestart:remote": "npm run build",
|
||||
"start:remote": "node dist/src/index.js krasnodar",
|
||||
"start": "npm run start:remote"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fluencelabs/examples/aqua-examples/echo-greeter"
|
||||
},
|
||||
"keywords": [
|
||||
"aqua",
|
||||
"fluence"
|
||||
],
|
||||
"author": "Fluence Labs",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "git+https://github.com/fluencelabs/examples/issues"
|
||||
},
|
||||
"homepage": "git+https://github.com/fluencelabs/examples/aqua-examples/echo-greeter#readme",
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-278",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"typescript": "^4.5.5"
|
||||
}
|
||||
"name": "echo-greeter-example",
|
||||
"version": "0.1.0",
|
||||
"description": "Fluence Echo Greeter Example",
|
||||
"main": "./dist/src/index.js",
|
||||
"typings": "./dist/src/index.d.ts",
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"bic": [
|
||||
"client-peer/*",
|
||||
"*.aqua",
|
||||
"package-lock.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"it-all": "^1.0.5"
|
||||
},
|
||||
"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\""
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fluencelabs/examples/aqua-examples/echo-greeter"
|
||||
},
|
||||
"keywords": [
|
||||
"aqua",
|
||||
"fluence"
|
||||
],
|
||||
"author": "Fluence Labs",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "git+https://github.com/fluencelabs/examples/issues"
|
||||
},
|
||||
"homepage": "git+https://github.com/fluencelabs/examples/aqua-examples/echo-greeter#readme",
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.0-272",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.2",
|
||||
"@types/jest": "^27.0.3",
|
||||
"jest": "^27.4.0",
|
||||
"ts-jest": "^27.0.7"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
import { main } from '../main';
|
||||
|
||||
describe('smoke test', () => {
|
||||
it('should work', async () => {
|
||||
console.log = jest.fn();
|
||||
|
||||
await main();
|
||||
|
||||
expect(console.log).toBeCalledTimes(6);
|
||||
expect(console.log).toHaveBeenNthCalledWith(2, expect.stringMatching('echo result'), 'Jim,John,Jake,');
|
||||
expect(console.log).toHaveBeenNthCalledWith(3, expect.stringMatching('greeting result'), 'Hi, Jim');
|
||||
expect(console.log).toHaveBeenNthCalledWith(4, expect.stringMatching('seq result'), [
|
||||
'Hi, Jim',
|
||||
'Hi, John',
|
||||
'Hi, Jake',
|
||||
]);
|
||||
expect(console.log).toHaveBeenNthCalledWith(5, expect.stringMatching('par result'), [
|
||||
'Hi, Jim',
|
||||
'Hi, Jim',
|
||||
'Hi, John',
|
||||
'Hi, John',
|
||||
'Hi, Jake',
|
||||
'Hi, Jake',
|
||||
]);
|
||||
expect(console.log).toHaveBeenNthCalledWith(6, expect.stringMatching('par improved signature result'), [
|
||||
'Hi, Jim',
|
||||
'Bye, Jim',
|
||||
'Hi, John',
|
||||
'Bye, John',
|
||||
'Hi, Jake',
|
||||
'Bye, Jake',
|
||||
]);
|
||||
}, 15000);
|
||||
});
|
@ -1,153 +1,8 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { setLogLevel, Fluence, FluencePeer } from "@fluencelabs/fluence";
|
||||
import { krasnodar, Node } from "@fluencelabs/fluence-network-environment";
|
||||
import {
|
||||
echo,
|
||||
greeting,
|
||||
echo_greeting_seq,
|
||||
echo_greeting_par,
|
||||
echo_greeting_par_alternative,
|
||||
echo_greeting_par_improved,
|
||||
} from "./_aqua/echo_greeter";
|
||||
|
||||
interface EchoResult {
|
||||
echo: string;
|
||||
}
|
||||
interface NodeServicePair {
|
||||
node: string;
|
||||
service_id: string;
|
||||
}
|
||||
|
||||
interface EchoService {
|
||||
node: string;
|
||||
service_id: string;
|
||||
names: Array<string>;
|
||||
}
|
||||
|
||||
interface GreetingService {
|
||||
node: string;
|
||||
service_id: string;
|
||||
greet: boolean;
|
||||
}
|
||||
|
||||
let greeting_topos: Array<NodeServicePair> = [
|
||||
{
|
||||
node: "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
service_id: "5cf520ff-dd65-47d7-a51a-2bf08dfe2ede",
|
||||
},
|
||||
{
|
||||
node: "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE",
|
||||
service_id: "5a03906b-3217-40a2-93fb-7e83be735408",
|
||||
},
|
||||
];
|
||||
let echo_topos: Array<NodeServicePair> = [
|
||||
{
|
||||
node: "12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt",
|
||||
service_id: "fb5f7126-e1ee-4ecf-81e7-20804cb7203b",
|
||||
},
|
||||
{
|
||||
node: "12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE",
|
||||
service_id: "893a6fb8-43b9-4b11-8786-93300bd68bc8",
|
||||
},
|
||||
];
|
||||
let echo_service: EchoService = {
|
||||
node: echo_topos[0].node,
|
||||
service_id: echo_topos[0].service_id,
|
||||
names: ["Jim", "John", "Jake"],
|
||||
};
|
||||
let greeting_services: Array<GreetingService> = [
|
||||
{
|
||||
node: greeting_topos[0].node,
|
||||
service_id: greeting_topos[0].service_id,
|
||||
greet: true,
|
||||
},
|
||||
{
|
||||
node: greeting_topos[1].node,
|
||||
service_id: greeting_topos[1].service_id,
|
||||
greet: false,
|
||||
},
|
||||
];
|
||||
|
||||
let names: Array<string> = ["Jim", "John", "Jake"];
|
||||
|
||||
// let greeting_service =
|
||||
|
||||
async function main() {
|
||||
// console.log("hello");
|
||||
// setLogLevel('DEBUG');
|
||||
|
||||
await Fluence.start({ connectTo: krasnodar[2] });
|
||||
console.log(
|
||||
"created a fluence client %s with relay %s",
|
||||
Fluence.getStatus().peerId,
|
||||
Fluence.getStatus().relayPeerId
|
||||
);
|
||||
|
||||
let echo_result = await echo(
|
||||
names,
|
||||
echo_topos[0].node,
|
||||
echo_topos[0].service_id
|
||||
);
|
||||
|
||||
let result = "";
|
||||
|
||||
for (let item of echo_result) {
|
||||
result += item.echo + ",";
|
||||
}
|
||||
console.log("echo result : ", result);
|
||||
|
||||
let greeting_result = await greeting(
|
||||
names[0],
|
||||
true,
|
||||
greeting_topos[0].node,
|
||||
greeting_topos[0].service_id
|
||||
);
|
||||
console.log("greeting result : ", greeting_result);
|
||||
|
||||
// echo_greeting_par(greet: bool, echo_service: EchoServiceInput, greeting_services: []NodeServicePair) -> []string:
|
||||
let seq_result = await echo_greeting_seq(
|
||||
names,
|
||||
true,
|
||||
echo_topos[0].node,
|
||||
echo_topos[0].service_id,
|
||||
greeting_topos[0].service_id
|
||||
);
|
||||
console.log("seq result : ", seq_result);
|
||||
|
||||
let par_result = await echo_greeting_par(
|
||||
true,
|
||||
echo_service,
|
||||
greeting_services
|
||||
);
|
||||
console.log("par result : ", par_result);
|
||||
|
||||
par_result = await echo_greeting_par_improved(
|
||||
echo_service,
|
||||
greeting_services
|
||||
);
|
||||
console.log("par improved signature result : ", par_result);
|
||||
|
||||
return;
|
||||
}
|
||||
import { main } from './main';
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
128
aqua-examples/echo-greeter/client-peer/src/main.ts
Normal file
128
aqua-examples/echo-greeter/client-peer/src/main.ts
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { setLogLevel, Fluence, FluencePeer } from '@fluencelabs/fluence';
|
||||
import { krasnodar, Node } from '@fluencelabs/fluence-network-environment';
|
||||
import {
|
||||
echo,
|
||||
greeting,
|
||||
echo_greeting_seq,
|
||||
echo_greeting_par,
|
||||
echo_greeting_par_alternative,
|
||||
echo_greeting_par_improved,
|
||||
} from './_aqua/echo_greeter';
|
||||
|
||||
interface EchoResult {
|
||||
echo: string;
|
||||
}
|
||||
interface NodeServicePair {
|
||||
node: string;
|
||||
service_id: string;
|
||||
}
|
||||
|
||||
interface EchoService {
|
||||
node: string;
|
||||
service_id: string;
|
||||
names: Array<string>;
|
||||
}
|
||||
|
||||
interface GreetingService {
|
||||
node: string;
|
||||
service_id: string;
|
||||
greet: boolean;
|
||||
}
|
||||
|
||||
let greeting_topos: Array<NodeServicePair> = [
|
||||
{
|
||||
node: '12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt',
|
||||
service_id: '5cf520ff-dd65-47d7-a51a-2bf08dfe2ede',
|
||||
},
|
||||
{
|
||||
node: '12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE',
|
||||
service_id: '5a03906b-3217-40a2-93fb-7e83be735408',
|
||||
},
|
||||
];
|
||||
let echo_topos: Array<NodeServicePair> = [
|
||||
{
|
||||
node: '12D3KooWFtf3rfCDAfWwt6oLZYZbDfn9Vn7bv7g6QjjQxUUEFVBt',
|
||||
service_id: 'fb5f7126-e1ee-4ecf-81e7-20804cb7203b',
|
||||
},
|
||||
{
|
||||
node: '12D3KooWJd3HaMJ1rpLY1kQvcjRPEvnDwcXrH8mJvk7ypcZXqXGE',
|
||||
service_id: '893a6fb8-43b9-4b11-8786-93300bd68bc8',
|
||||
},
|
||||
];
|
||||
let echo_service: EchoService = {
|
||||
node: echo_topos[0].node,
|
||||
service_id: echo_topos[0].service_id,
|
||||
names: ['Jim', 'John', 'Jake'],
|
||||
};
|
||||
let greeting_services: Array<GreetingService> = [
|
||||
{
|
||||
node: greeting_topos[0].node,
|
||||
service_id: greeting_topos[0].service_id,
|
||||
greet: true,
|
||||
},
|
||||
{
|
||||
node: greeting_topos[1].node,
|
||||
service_id: greeting_topos[1].service_id,
|
||||
greet: false,
|
||||
},
|
||||
];
|
||||
|
||||
let names: Array<string> = ['Jim', 'John', 'Jake'];
|
||||
|
||||
export async function main() {
|
||||
// console.log("hello");
|
||||
// setLogLevel('DEBUG');
|
||||
|
||||
await Fluence.start({ connectTo: krasnodar[2] });
|
||||
console.log(
|
||||
'created a fluence client %s with relay %s',
|
||||
Fluence.getStatus().peerId,
|
||||
Fluence.getStatus().relayPeerId,
|
||||
);
|
||||
|
||||
let echo_result = await echo(names, echo_topos[0].node, echo_topos[0].service_id);
|
||||
|
||||
let result = '';
|
||||
|
||||
for (let item of echo_result) {
|
||||
result += item.echo + ',';
|
||||
}
|
||||
console.log('echo result : ', result);
|
||||
|
||||
let greeting_result = await greeting(names[0], true, greeting_topos[0].node, greeting_topos[0].service_id);
|
||||
console.log('greeting result : ', greeting_result);
|
||||
|
||||
// echo_greeting_par(greet: bool, echo_service: EchoServiceInput, greeting_services: []NodeServicePair) -> []string:
|
||||
let seq_result = await echo_greeting_seq(
|
||||
names,
|
||||
true,
|
||||
echo_topos[0].node,
|
||||
echo_topos[0].service_id,
|
||||
greeting_topos[0].service_id,
|
||||
);
|
||||
console.log('seq result : ', seq_result);
|
||||
|
||||
let par_result = await echo_greeting_par(true, echo_service, greeting_services);
|
||||
console.log('par result : ', par_result);
|
||||
|
||||
par_result = await echo_greeting_par_improved(echo_service, greeting_services);
|
||||
console.log('par improved signature result : ', par_result);
|
||||
|
||||
await Fluence.stop();
|
||||
}
|
8
aqua-examples/price-oracle/client-peer/.prettierrc.js
Normal file
8
aqua-examples/price-oracle/client-peer/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
5
aqua-examples/price-oracle/client-peer/jest.config.js
Normal file
5
aqua-examples/price-oracle/client-peer/jest.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testPathIgnorePatterns: ['dist'],
|
||||
};
|
22523
aqua-examples/price-oracle/client-peer/package-lock.json
generated
22523
aqua-examples/price-oracle/client-peer/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,49 +1,53 @@
|
||||
{
|
||||
"name": "price-oracle",
|
||||
"version": "0.1.0",
|
||||
"description": "Fluence Price Oracle Demo",
|
||||
"main": "./dist/src/index.js",
|
||||
"typings": "./dist/src/index.d.ts",
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"bic": [
|
||||
"client-peer/*",
|
||||
"*.aqua",
|
||||
"package-lock.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.0.13",
|
||||
"it-all": "^1.0.5"
|
||||
},
|
||||
"scripts": {
|
||||
"compile-aqua": "aqua -i ../aqua -o src/_aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"build": "tsc",
|
||||
"prestart:local": "npm run build",
|
||||
"start:local": "node dist/src/index.js local",
|
||||
"prestart:remote": "npm run build",
|
||||
"start:remote": "node dist/src/index.js krasnodar",
|
||||
"start": "npm run start:remote"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fluencelabs/examples/aqua-examples/price-oracle"
|
||||
},
|
||||
"keywords": [
|
||||
"aqua",
|
||||
"fluence"
|
||||
],
|
||||
"author": "Fluence Labs",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "git+https://github.com/fluencelabs/examples/issues"
|
||||
},
|
||||
"homepage": "git+https://github.com/fluencelabs/examples/aqua-examples/price-oracle#readme",
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-278",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"typescript": "^4.5.5"
|
||||
}
|
||||
"name": "price-oracle",
|
||||
"version": "0.1.0",
|
||||
"description": "Fluence Price Oracle Demo",
|
||||
"main": "./dist/src/index.js",
|
||||
"typings": "./dist/src/index.d.ts",
|
||||
"files": [
|
||||
"dist/*"
|
||||
],
|
||||
"bic": [
|
||||
"client-peer/*",
|
||||
"*.aqua",
|
||||
"package-lock.json"
|
||||
],
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "1.0.13",
|
||||
"it-all": "^1.0.5"
|
||||
},
|
||||
"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\""
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/fluencelabs/examples/aqua-examples/price-oracle"
|
||||
},
|
||||
"keywords": [
|
||||
"aqua",
|
||||
"fluence"
|
||||
],
|
||||
"author": "Fluence Labs",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "git+https://github.com/fluencelabs/examples/issues"
|
||||
},
|
||||
"homepage": "git+https://github.com/fluencelabs/examples/aqua-examples/price-oracle#readme",
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.0-272",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.2",
|
||||
"@types/jest": "^27.0.3",
|
||||
"jest": "^27.4.0",
|
||||
"ts-jest": "^27.0.7"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
import { main } from '../main';
|
||||
|
||||
describe('smoke test', () => {
|
||||
it('should work', async () => {
|
||||
console.log = jest.fn();
|
||||
|
||||
await main();
|
||||
|
||||
expect(console.log).toBeCalledTimes(4);
|
||||
expect(console.log).toHaveBeenNthCalledWith(3, 'seq result: ', {
|
||||
error_msg: '',
|
||||
result: expect.any(Number),
|
||||
success: true,
|
||||
});
|
||||
expect(console.log).toHaveBeenNthCalledWith(4, 'par result: ', {
|
||||
error_msg: '',
|
||||
result: expect.any(Number),
|
||||
success: true,
|
||||
});
|
||||
}, 15000);
|
||||
});
|
@ -1,90 +1,8 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { setLogLevel, Fluence } from "@fluencelabs/fluence";
|
||||
import { krasnodar, Node } from "@fluencelabs/fluence-network-environment";
|
||||
import { get_price, get_price_par } from "./_aqua/get_crypto_prices";
|
||||
|
||||
interface NodeServicePair {
|
||||
node: string;
|
||||
service_id: string;
|
||||
}
|
||||
|
||||
let getter_topo: Array<NodeServicePair>;
|
||||
let mean_topo: Array<NodeServicePair>;
|
||||
|
||||
// description of the services' locations, copypaste from data/deployed_services.json
|
||||
getter_topo = [
|
||||
{
|
||||
node: "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||
service_id: "b67586f7-e96f-49ee-914e-9eabe1a0b83d",
|
||||
},
|
||||
{
|
||||
node: "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi",
|
||||
service_id: "f5b456fa-ee18-4df1-b18b-84fe7ebc7ad0",
|
||||
}
|
||||
];
|
||||
|
||||
mean_topo = [
|
||||
{
|
||||
node: "12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS",
|
||||
service_id: "79b8ddb9-e2e6-4924-9293-c5d55c94af6b",
|
||||
},
|
||||
{
|
||||
node: "12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi",
|
||||
service_id: "debecd02-ba7d-40a2-92ab-08a9321da2cf"
|
||||
}
|
||||
];
|
||||
|
||||
async function main() {
|
||||
console.log("hello crypto investors");
|
||||
|
||||
// Uncomment to enable debug logs:
|
||||
// setLogLevel('DEBUG');
|
||||
|
||||
// create the Fluence client for the Krasnodar testnet
|
||||
await Fluence.start({ connectTo: krasnodar[5] });
|
||||
console.log(
|
||||
"Created a fluence client with peer id %s and relay id %s",
|
||||
Fluence.getStatus().peerId,
|
||||
Fluence.getStatus().relayPeerId
|
||||
);
|
||||
|
||||
// call the get_price function -- sequential processing
|
||||
const network_result = await get_price(
|
||||
"ethereum",
|
||||
"usd",
|
||||
getter_topo[1].node,
|
||||
getter_topo[1].service_id,
|
||||
mean_topo[1].service_id
|
||||
);
|
||||
console.log("seq result: ", network_result);
|
||||
|
||||
// call the get_price_par function -- parallel processing
|
||||
// func get_price_par(coin: string, currency: string, getter_topo: []NodeServicePair, mean_topo: NodeServicePair) -> Result:
|
||||
const network_result_par = await get_price_par("ethereum", "usd", getter_topo, mean_topo[0]
|
||||
);
|
||||
console.log("par result: ", network_result_par);
|
||||
|
||||
await Fluence.stop();
|
||||
}
|
||||
import { main } from './main';
|
||||
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
.then(() => process.exit(0))
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
82
aqua-examples/price-oracle/client-peer/src/main.ts
Normal file
82
aqua-examples/price-oracle/client-peer/src/main.ts
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2021 Fluence Labs Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { setLogLevel, Fluence } from '@fluencelabs/fluence';
|
||||
import { krasnodar, Node } from '@fluencelabs/fluence-network-environment';
|
||||
import { get_price, get_price_par } from './_aqua/get_crypto_prices';
|
||||
|
||||
interface NodeServicePair {
|
||||
node: string;
|
||||
service_id: string;
|
||||
}
|
||||
|
||||
let getter_topo: Array<NodeServicePair>;
|
||||
let mean_topo: Array<NodeServicePair>;
|
||||
|
||||
// description of the services' locations, copypaste from data/deployed_services.json
|
||||
getter_topo = [
|
||||
{
|
||||
node: '12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS',
|
||||
service_id: 'b67586f7-e96f-49ee-914e-9eabe1a0b83d',
|
||||
},
|
||||
{
|
||||
node: '12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi',
|
||||
service_id: 'f5b456fa-ee18-4df1-b18b-84fe7ebc7ad0',
|
||||
},
|
||||
];
|
||||
|
||||
mean_topo = [
|
||||
{
|
||||
node: '12D3KooWCMr9mU894i8JXAFqpgoFtx6qnV1LFPSfVc3Y34N4h4LS',
|
||||
service_id: '79b8ddb9-e2e6-4924-9293-c5d55c94af6b',
|
||||
},
|
||||
{
|
||||
node: '12D3KooWFEwNWcHqi9rtsmDhsYcDbRUCDXH84RC4FW6UfsFWaoHi',
|
||||
service_id: 'debecd02-ba7d-40a2-92ab-08a9321da2cf',
|
||||
},
|
||||
];
|
||||
|
||||
export async function main() {
|
||||
console.log('hello crypto investors');
|
||||
|
||||
// Uncomment to enable debug logs:
|
||||
// setLogLevel('DEBUG');
|
||||
|
||||
// create the Fluence client for the Krasnodar testnet
|
||||
await Fluence.start({ connectTo: krasnodar[5] });
|
||||
console.log(
|
||||
'Created a fluence client with peer id %s and relay id %s',
|
||||
Fluence.getStatus().peerId,
|
||||
Fluence.getStatus().relayPeerId,
|
||||
);
|
||||
|
||||
// call the get_price function -- sequential processing
|
||||
const network_result = await get_price(
|
||||
'ethereum',
|
||||
'usd',
|
||||
getter_topo[1].node,
|
||||
getter_topo[1].service_id,
|
||||
mean_topo[1].service_id,
|
||||
);
|
||||
console.log('seq result: ', network_result);
|
||||
|
||||
// call the get_price_par function -- parallel processing
|
||||
// func get_price_par(coin: string, currency: string, getter_topo: []NodeServicePair, mean_topo: NodeServicePair) -> Result:
|
||||
const network_result_par = await get_price_par('ethereum', 'usd', getter_topo, mean_topo[0]);
|
||||
console.log('par result: ', network_result_par);
|
||||
|
||||
await Fluence.stop();
|
||||
}
|
8
aqua-examples/price-oracle/web/.gitignore
vendored
8
aqua-examples/price-oracle/web/.gitignore
vendored
@ -21,3 +21,11 @@
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
|
||||
public/*.wasm
|
||||
public/runnerScript.*
|
8
aqua-examples/price-oracle/web/.prettierrc.js
Normal file
8
aqua-examples/price-oracle/web/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
8
aqua-examples/price-oracle/web/jest.config.js
Normal file
8
aqua-examples/price-oracle/web/jest.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
preset: 'jest-puppeteer',
|
||||
testMatch: ['**/?(*.)+(spec|test).[t]s'],
|
||||
testPathIgnorePatterns: ['/node_modules/', 'dist'],
|
||||
transform: {
|
||||
'^.+\\.ts?$': 'ts-jest',
|
||||
},
|
||||
};
|
82968
aqua-examples/price-oracle/web/package-lock.json
generated
82968
aqua-examples/price-oracle/web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,53 +1,64 @@
|
||||
{
|
||||
"name": "price-oracle",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "aqua -i ../aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"../aqua/**/*.aqua\" -c \"npm run compile-aqua\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-278",
|
||||
"chokidar-cli": "^2.1.0",
|
||||
"node-sass": "^6.0.1"
|
||||
}
|
||||
"name": "price-oracle",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.2",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^5.0.0",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "aqua -i ../aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"../aqua/**/*.aqua\" -c \"npm run compile-aqua\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all",
|
||||
"not ie 11",
|
||||
"not android 4.4.3-4.4.4"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/serve-handler": "^6.1.1",
|
||||
"@fluencelabs/aqua": "^0.6.0-275",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"chokidar-cli": "^2.1.0",
|
||||
"jest-puppeteer": "^6.0.2",
|
||||
"node-sass": "^6.0.1",
|
||||
"serve": "^13.0.2",
|
||||
"ts-jest": "^27.1.3"
|
||||
}
|
||||
}
|
||||
|
8
aqua-examples/price-oracle/web/src/.prettierrc.js
Normal file
8
aqua-examples/price-oracle/web/src/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
@ -94,14 +94,14 @@ function App() {
|
||||
<TextInput text={"meanSid"} value={meanSid} setValue={setMeanSid} />
|
||||
|
||||
<div className="row">
|
||||
<button className="btn btn-hello" onClick={() => doGetPrice()}>
|
||||
<button id="btn" className="btn btn-hello" onClick={() => doGetPrice()}>
|
||||
Get price
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Coin price</h2>
|
||||
{result && result.success && (
|
||||
<p className="success">The price is: {result.result}</p>
|
||||
<p id="price" className="success">The price is: {result.result}</p>
|
||||
)}
|
||||
{result && !result.success && (
|
||||
<p className="error">Error: {result.error_msg}</p>
|
||||
|
52
aqua-examples/price-oracle/web/src/__test__/test.spec.ts
Normal file
52
aqua-examples/price-oracle/web/src/__test__/test.spec.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import handler from 'serve-handler';
|
||||
import http from 'http';
|
||||
import path from 'path';
|
||||
|
||||
const port = 3000;
|
||||
const uri = `http://localhost:${port}/`;
|
||||
const publicPath = path.join(__dirname, '../../build/');
|
||||
|
||||
console.log(publicPath);
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
return handler(request, response, {
|
||||
public: publicPath,
|
||||
});
|
||||
});
|
||||
|
||||
const startServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.listen(port, resolve);
|
||||
});
|
||||
};
|
||||
|
||||
const stopServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.close(resolve);
|
||||
});
|
||||
};
|
||||
|
||||
describe('smoke test', () => {
|
||||
beforeAll(startServer);
|
||||
|
||||
afterAll(stopServer);
|
||||
|
||||
it('should work', async () => {
|
||||
console.log('going to the page in browser...');
|
||||
await page.goto(uri);
|
||||
|
||||
console.log('waiting for fluence to connect...');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('clicking button...');
|
||||
await page.click('#btn');
|
||||
|
||||
console.log('waiting for price to appear...');
|
||||
const elem = await page.waitForSelector('#price');
|
||||
|
||||
console.log('getting the content of price div...');
|
||||
const content = await elem?.evaluate((x) => x.textContent);
|
||||
|
||||
expect(content).toMatch('The price is:');
|
||||
}, 15000);
|
||||
});
|
@ -1,412 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* This file is auto-generated. Do not edit manually: changes may be erased.
|
||||
* Generated by Aqua compiler: https://github.com/fluencelabs/aqua/.
|
||||
* If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||
* Aqua version: 0.6.1-278
|
||||
*
|
||||
*/
|
||||
import { Fluence, FluencePeer } from '@fluencelabs/fluence';
|
||||
import {
|
||||
CallParams,
|
||||
callFunction,
|
||||
registerService,
|
||||
} from '@fluencelabs/fluence/dist/internal/compilerSupport/v2';
|
||||
|
||||
|
||||
// Services
|
||||
|
||||
export interface MeanServiceDef {
|
||||
mean: (data: number[], callParams: CallParams<'data'>) => { error_msg: string; result: number; success: boolean; } | Promise<{ error_msg: string; result: number; success: boolean; }>;
|
||||
}
|
||||
export function registerMeanService(serviceId: string, service: MeanServiceDef): void;
|
||||
export function registerMeanService(peer: FluencePeer, serviceId: string, service: MeanServiceDef): void;
|
||||
|
||||
|
||||
export function registerMeanService(...args: any) {
|
||||
registerService(
|
||||
args,
|
||||
{
|
||||
"functions" : [
|
||||
{
|
||||
"functionName" : "mean",
|
||||
"argDefs" : [
|
||||
{
|
||||
"name" : "data",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
],
|
||||
"returnType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface F64OpDef {
|
||||
identity: (x: number, callParams: CallParams<'x'>) => number | Promise<number>;
|
||||
}
|
||||
export function registerF64Op(service: F64OpDef): void;
|
||||
export function registerF64Op(serviceId: string, service: F64OpDef): void;
|
||||
export function registerF64Op(peer: FluencePeer, service: F64OpDef): void;
|
||||
export function registerF64Op(peer: FluencePeer, serviceId: string, service: F64OpDef): void;
|
||||
|
||||
|
||||
export function registerF64Op(...args: any) {
|
||||
registerService(
|
||||
args,
|
||||
{
|
||||
"defaultServiceId" : "op",
|
||||
"functions" : [
|
||||
{
|
||||
"functionName" : "identity",
|
||||
"argDefs" : [
|
||||
{
|
||||
"name" : "x",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
],
|
||||
"returnType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
export interface PriceGetterServiceDef {
|
||||
price_getter: (coin: string, currency: string, timestamp_ms: number, callParams: CallParams<'coin' | 'currency' | 'timestamp_ms'>) => { error_msg: string; result: number; success: boolean; } | Promise<{ error_msg: string; result: number; success: boolean; }>;
|
||||
}
|
||||
export function registerPriceGetterService(serviceId: string, service: PriceGetterServiceDef): void;
|
||||
export function registerPriceGetterService(peer: FluencePeer, serviceId: string, service: PriceGetterServiceDef): void;
|
||||
|
||||
|
||||
export function registerPriceGetterService(...args: any) {
|
||||
registerService(
|
||||
args,
|
||||
{
|
||||
"functions" : [
|
||||
{
|
||||
"functionName" : "price_getter",
|
||||
"argDefs" : [
|
||||
{
|
||||
"name" : "coin",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "currency",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "timestamp_ms",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
],
|
||||
"returnType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Functions
|
||||
export type Get_price_parArgMean_topo = { node: string; service_id: string; }
|
||||
export type Get_price_parResult = { error_msg: string; result: number; success: boolean; }
|
||||
export function get_price_par(
|
||||
coin: string,
|
||||
currency: string,
|
||||
getter_topo: { node: string; service_id: string; }[],
|
||||
mean_topo: Get_price_parArgMean_topo,
|
||||
config?: {ttl?: number}
|
||||
): Promise<Get_price_parResult>;
|
||||
|
||||
export function get_price_par(
|
||||
peer: FluencePeer,
|
||||
coin: string,
|
||||
currency: string,
|
||||
getter_topo: { node: string; service_id: string; }[],
|
||||
mean_topo: Get_price_parArgMean_topo,
|
||||
config?: {ttl?: number}
|
||||
): Promise<Get_price_parResult>;
|
||||
|
||||
export function get_price_par(...args: any) {
|
||||
|
||||
let script = `
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||
(call %init_peer_id% ("getDataSrv" "coin") [] coin)
|
||||
)
|
||||
(call %init_peer_id% ("getDataSrv" "currency") [] currency)
|
||||
)
|
||||
(call %init_peer_id% ("getDataSrv" "getter_topo") [] getter_topo)
|
||||
)
|
||||
(call %init_peer_id% ("getDataSrv" "mean_topo") [] mean_topo)
|
||||
)
|
||||
(new $prices
|
||||
(seq
|
||||
(par
|
||||
(fold getter_topo topo
|
||||
(par
|
||||
(seq
|
||||
(seq
|
||||
(call -relay- ("op" "noop") [])
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(call topo.$.node! ("peer" "timestamp_ms") [] ts_ms)
|
||||
(call topo.$.node! (topo.$.service_id! "price_getter") [coin currency ts_ms] res)
|
||||
)
|
||||
(call topo.$.node! ("op" "identity") [res.$.result!] $prices)
|
||||
)
|
||||
(call topo.$.node! ("op" "noop") [])
|
||||
)
|
||||
(seq
|
||||
(call -relay- ("op" "noop") [])
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
|
||||
)
|
||||
)
|
||||
)
|
||||
(call mean_topo.$.node! ("op" "noop") [])
|
||||
)
|
||||
(next topo)
|
||||
)
|
||||
)
|
||||
(null)
|
||||
)
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(call mean_topo.$.node! ("op" "identity") [$prices.$.[1]!])
|
||||
(call mean_topo.$.node! (mean_topo.$.service_id! "mean") [$prices] result)
|
||||
)
|
||||
(call -relay- ("op" "noop") [])
|
||||
)
|
||||
(seq
|
||||
(call -relay- ("op" "noop") [])
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(xor
|
||||
(call %init_peer_id% ("callbackSrv" "response") [result])
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3])
|
||||
)
|
||||
)
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 4])
|
||||
)
|
||||
`
|
||||
return callFunction(
|
||||
args,
|
||||
{
|
||||
"functionName" : "get_price_par",
|
||||
"returnType" : {
|
||||
"tag" : "primitive"
|
||||
},
|
||||
"argDefs" : [
|
||||
{
|
||||
"name" : "coin",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "currency",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "getter_topo",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "mean_topo",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
],
|
||||
"names" : {
|
||||
"relay" : "-relay-",
|
||||
"getDataSrv" : "getDataSrv",
|
||||
"callbackSrv" : "callbackSrv",
|
||||
"responseSrv" : "callbackSrv",
|
||||
"responseFnName" : "response",
|
||||
"errorHandlingSrv" : "errorHandlingSrv",
|
||||
"errorFnName" : "error"
|
||||
}
|
||||
},
|
||||
script
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export type Get_priceResult = { error_msg: string; result: number; success: boolean; }
|
||||
export function get_price(
|
||||
coin: string,
|
||||
currency: string,
|
||||
node: string,
|
||||
pg_sid: string,
|
||||
mean_sid: string,
|
||||
config?: {ttl?: number}
|
||||
): Promise<Get_priceResult>;
|
||||
|
||||
export function get_price(
|
||||
peer: FluencePeer,
|
||||
coin: string,
|
||||
currency: string,
|
||||
node: string,
|
||||
pg_sid: string,
|
||||
mean_sid: string,
|
||||
config?: {ttl?: number}
|
||||
): Promise<Get_priceResult>;
|
||||
|
||||
export function get_price(...args: any) {
|
||||
|
||||
let script = `
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||
(call %init_peer_id% ("getDataSrv" "coin") [] coin)
|
||||
)
|
||||
(call %init_peer_id% ("getDataSrv" "currency") [] currency)
|
||||
)
|
||||
(call %init_peer_id% ("getDataSrv" "node") [] node)
|
||||
)
|
||||
(call %init_peer_id% ("getDataSrv" "pg_sid") [] pg_sid)
|
||||
)
|
||||
(call %init_peer_id% ("getDataSrv" "mean_sid") [] mean_sid)
|
||||
)
|
||||
(new $prices
|
||||
(seq
|
||||
(call -relay- ("op" "noop") [])
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(call node ("op" "string_to_b58") [node] k)
|
||||
(call node ("peer" "timestamp_ms") [] ts_ms0)
|
||||
)
|
||||
(call node (pg_sid "price_getter") [coin currency ts_ms0] res0)
|
||||
)
|
||||
(call node ("op" "identity") [res0.$.result!] $prices)
|
||||
)
|
||||
(call node ("peer" "timestamp_ms") [] ts_ms1)
|
||||
)
|
||||
(call node (pg_sid "price_getter") [coin currency ts_ms1] res1)
|
||||
)
|
||||
(call node ("op" "identity") [res1.$.result!] $prices)
|
||||
)
|
||||
(call node (mean_sid "mean") [$prices] result)
|
||||
)
|
||||
(call -relay- ("op" "noop") [])
|
||||
)
|
||||
(seq
|
||||
(call -relay- ("op" "noop") [])
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(xor
|
||||
(call %init_peer_id% ("callbackSrv" "response") [result])
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
|
||||
)
|
||||
)
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3])
|
||||
)
|
||||
`
|
||||
return callFunction(
|
||||
args,
|
||||
{
|
||||
"functionName" : "get_price",
|
||||
"returnType" : {
|
||||
"tag" : "primitive"
|
||||
},
|
||||
"argDefs" : [
|
||||
{
|
||||
"name" : "coin",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "currency",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "node",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "pg_sid",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name" : "mean_sid",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
],
|
||||
"names" : {
|
||||
"relay" : "-relay-",
|
||||
"getDataSrv" : "getDataSrv",
|
||||
"callbackSrv" : "callbackSrv",
|
||||
"responseSrv" : "callbackSrv",
|
||||
"responseFnName" : "response",
|
||||
"errorHandlingSrv" : "errorHandlingSrv",
|
||||
"errorFnName" : "error"
|
||||
}
|
||||
},
|
||||
script
|
||||
)
|
||||
}
|
8
fluence-js-examples/browser-example/.prettierrc.js
Normal file
8
fluence-js-examples/browser-example/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
8
fluence-js-examples/browser-example/jest.config.js
Normal file
8
fluence-js-examples/browser-example/jest.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
preset: 'jest-puppeteer',
|
||||
testMatch: ['**/?(*.)+(spec|test).[t]s'],
|
||||
testPathIgnorePatterns: ['/node_modules/', 'dist'],
|
||||
transform: {
|
||||
'^.+\\.ts?$': 'ts-jest',
|
||||
},
|
||||
};
|
85254
fluence-js-examples/browser-example/package-lock.json
generated
85254
fluence-js-examples/browser-example/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,54 +1,65 @@
|
||||
{
|
||||
"name": "getting-started-browser",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-278",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"chokidar-cli": "^2.1.0",
|
||||
"node-sass": "^6.0.1"
|
||||
}
|
||||
"name": "getting-started-browser",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.19.2",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/serve-handler": "^6.1.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^5.0.0",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all",
|
||||
"not ie 11",
|
||||
"not android 4.4.3-4.4.4"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.0-275",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"chokidar-cli": "^2.1.0",
|
||||
"jest-puppeteer": "^6.0.2",
|
||||
"node-sass": "^6.0.1",
|
||||
"serve": "^13.0.2",
|
||||
"ts-jest": "^27.1.3"
|
||||
}
|
||||
}
|
||||
|
@ -34,14 +34,14 @@ function App() {
|
||||
</header>
|
||||
|
||||
<div className="content">
|
||||
<h1>Status: {Fluence.getStatus().isConnected ? "Connected" : "Disconnected"}</h1>
|
||||
<button className="btn" onClick={onGetRelayTimeBtnClick}>
|
||||
<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>{relayTime?.toLocaleString() || ""}</div>
|
||||
<div id="relayTime">{relayTime?.toLocaleString() || ""}</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
@ -0,0 +1,52 @@
|
||||
import handler from 'serve-handler';
|
||||
import http from 'http';
|
||||
import path from 'path';
|
||||
|
||||
const port = 3000;
|
||||
const uri = `http://localhost:${port}/`;
|
||||
const publicPath = path.join(__dirname, '../../build/');
|
||||
|
||||
console.log(publicPath);
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
return handler(request, response, {
|
||||
public: publicPath,
|
||||
});
|
||||
});
|
||||
|
||||
const startServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.listen(port, resolve);
|
||||
});
|
||||
};
|
||||
|
||||
const stopServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.close(resolve);
|
||||
});
|
||||
};
|
||||
|
||||
describe('smoke test', () => {
|
||||
beforeAll(startServer);
|
||||
|
||||
afterAll(stopServer);
|
||||
|
||||
it('should work', async () => {
|
||||
console.log('going to the page in browser...');
|
||||
await page.goto(uri);
|
||||
|
||||
console.log('waiting for fluence to connect...');
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
console.log('clicking button...');
|
||||
await page.click('#btn');
|
||||
|
||||
console.log('waiting for relay time to appear...');
|
||||
const elem = await page.waitForSelector('#relayTime');
|
||||
|
||||
console.log('getting the content of relay time div...');
|
||||
const content = await elem?.evaluate((x) => x.textContent);
|
||||
|
||||
expect(content?.length).toBeGreaterThan(10);
|
||||
}, 15000);
|
||||
});
|
@ -1,92 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* This file is auto-generated. Do not edit manually: changes may be erased.
|
||||
* Generated by Aqua compiler: https://github.com/fluencelabs/aqua/.
|
||||
* If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
|
||||
* Aqua version: 0.5.2-256
|
||||
*
|
||||
*/
|
||||
import { Fluence, FluencePeer } from '@fluencelabs/fluence';
|
||||
import {
|
||||
CallParams,
|
||||
callFunction,
|
||||
registerService,
|
||||
} from '@fluencelabs/fluence/dist/internal/compilerSupport/v2';
|
||||
|
||||
|
||||
// Services
|
||||
|
||||
// Functions
|
||||
|
||||
|
||||
export function getRelayTime(
|
||||
relayPeerId: string,
|
||||
config?: {ttl?: number}
|
||||
): Promise<number>;
|
||||
|
||||
export function getRelayTime(
|
||||
peer: FluencePeer,
|
||||
relayPeerId: string,
|
||||
config?: {ttl?: number}
|
||||
): Promise<number>;
|
||||
|
||||
export function getRelayTime(...args: any) {
|
||||
|
||||
let script = `
|
||||
(xor
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(seq
|
||||
(call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
|
||||
(call %init_peer_id% ("getDataSrv" "relayPeerId") [] relayPeerId)
|
||||
)
|
||||
(call -relay- ("op" "noop") [])
|
||||
)
|
||||
(xor
|
||||
(seq
|
||||
(call relayPeerId ("peer" "timestamp_ms") [] ts)
|
||||
(call -relay- ("op" "noop") [])
|
||||
)
|
||||
(seq
|
||||
(call -relay- ("op" "noop") [])
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
|
||||
)
|
||||
)
|
||||
)
|
||||
(xor
|
||||
(call %init_peer_id% ("callbackSrv" "response") [ts])
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
|
||||
)
|
||||
)
|
||||
(call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3])
|
||||
)
|
||||
`
|
||||
return callFunction(
|
||||
args,
|
||||
{
|
||||
"functionName" : "getRelayTime",
|
||||
"returnType" : {
|
||||
"tag" : "primitive"
|
||||
},
|
||||
"argDefs" : [
|
||||
{
|
||||
"name" : "relayPeerId",
|
||||
"argType" : {
|
||||
"tag" : "primitive"
|
||||
}
|
||||
}
|
||||
],
|
||||
"names" : {
|
||||
"relay" : "-relay-",
|
||||
"getDataSrv" : "getDataSrv",
|
||||
"callbackSrv" : "callbackSrv",
|
||||
"responseSrv" : "callbackSrv",
|
||||
"responseFnName" : "response",
|
||||
"errorHandlingSrv" : "errorHandlingSrv",
|
||||
"errorFnName" : "error"
|
||||
}
|
||||
},
|
||||
script
|
||||
)
|
||||
}
|
@ -17,9 +17,10 @@
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"isolatedModules": false,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
"jsx": "react-jsx",
|
||||
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
|
27
fluence-js-examples/hello-world/.gitignore
vendored
27
fluence-js-examples/hello-world/.gitignore
vendored
@ -1,3 +1,30 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
/dist
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
|
8
fluence-js-examples/hello-world/.prettierrc.js
Normal file
8
fluence-js-examples/hello-world/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
5
fluence-js-examples/hello-world/jest.config.js
Normal file
5
fluence-js-examples/hello-world/jest.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testPathIgnorePatterns: ['dist'],
|
||||
};
|
23394
fluence-js-examples/hello-world/package-lock.json
generated
23394
fluence-js-examples/hello-world/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,25 +1,31 @@
|
||||
{
|
||||
"name": "hello-world",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prestart": "npm run compile-aqua",
|
||||
"start": "node -r ts-node/register src/index.ts",
|
||||
"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.6.1-278",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13"
|
||||
}
|
||||
"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.6.0-272",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.2",
|
||||
"@types/jest": "^27.0.3",
|
||||
"jest": "^27.4.0",
|
||||
"ts-jest": "^27.0.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13"
|
||||
}
|
||||
}
|
||||
|
14
fluence-js-examples/hello-world/src/__test__/test.spec.ts
Normal file
14
fluence-js-examples/hello-world/src/__test__/test.spec.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { main } from '../main';
|
||||
|
||||
describe('smoke test', () => {
|
||||
it('should work', async () => {
|
||||
console.log = jest.fn();
|
||||
|
||||
await main();
|
||||
|
||||
expect(console.log).toBeCalledTimes(3);
|
||||
expect(console.log).toHaveBeenNthCalledWith(1, 'Hello, world!');
|
||||
expect(console.log).toHaveBeenNthCalledWith(2, 'Wealth awaits you very soon.');
|
||||
expect(console.log).toHaveBeenNthCalledWith(3, 'The relay time is: ', expect.anything());
|
||||
}, 15000);
|
||||
});
|
@ -1,36 +1,3 @@
|
||||
import { Fluence } from "@fluencelabs/fluence";
|
||||
import { krasnodar } from "@fluencelabs/fluence-network-environment";
|
||||
import {
|
||||
registerHelloWorld,
|
||||
sayHello,
|
||||
getRelayTime,
|
||||
tellFortune,
|
||||
} from "./_aqua/hello-world";
|
||||
|
||||
async function main() {
|
||||
await Fluence.start({ connectTo: krasnodar[0] });
|
||||
|
||||
registerHelloWorld({
|
||||
hello: (str) => {
|
||||
console.log(str);
|
||||
},
|
||||
getFortune: async () => {
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
return "Wealth awaits you very soon.";
|
||||
},
|
||||
});
|
||||
|
||||
await sayHello();
|
||||
|
||||
console.log(await tellFortune());
|
||||
|
||||
const relayTime = await getRelayTime();
|
||||
|
||||
console.log("The relay time is: ", new Date(relayTime).toLocaleString());
|
||||
|
||||
await Fluence.stop();
|
||||
}
|
||||
import { main } from './main';
|
||||
|
||||
main();
|
||||
|
29
fluence-js-examples/hello-world/src/main.ts
Normal file
29
fluence-js-examples/hello-world/src/main.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { Fluence } from '@fluencelabs/fluence';
|
||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
||||
import { registerHelloWorld, sayHello, getRelayTime, tellFortune } from './_aqua/hello-world';
|
||||
|
||||
export async function main() {
|
||||
await Fluence.start({ connectTo: krasnodar[0] });
|
||||
|
||||
registerHelloWorld({
|
||||
hello: (str) => {
|
||||
console.log(str);
|
||||
},
|
||||
getFortune: async () => {
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
return 'Wealth awaits you very soon.';
|
||||
},
|
||||
});
|
||||
|
||||
await sayHello();
|
||||
|
||||
console.log(await tellFortune());
|
||||
|
||||
const relayTime = await getRelayTime();
|
||||
|
||||
console.log('The relay time is: ', new Date(relayTime).toLocaleString());
|
||||
|
||||
await Fluence.stop();
|
||||
}
|
@ -1,7 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2015",
|
||||
"module": "CommonJS",
|
||||
"skipLibCheck": true
|
||||
}
|
||||
"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"
|
||||
],
|
||||
}
|
27
fluence-js-examples/node-example/.gitignore
vendored
27
fluence-js-examples/node-example/.gitignore
vendored
@ -1,3 +1,30 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
/dist
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
|
||||
# fluence
|
||||
|
||||
src/_aqua/*
|
||||
|
8
fluence-js-examples/node-example/.prettierrc.js
Normal file
8
fluence-js-examples/node-example/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
5
fluence-js-examples/node-example/jest.config.js
Normal file
5
fluence-js-examples/node-example/jest.config.js
Normal file
@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testPathIgnorePatterns: ['dist'],
|
||||
};
|
23392
fluence-js-examples/node-example/package-lock.json
generated
23392
fluence-js-examples/node-example/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,24 +1,30 @@
|
||||
{
|
||||
"name": "node-example",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prestart": "npm run compile-aqua",
|
||||
"start": "node -r ts-node/register src/index.ts",
|
||||
"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.6.1-278",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13"
|
||||
}
|
||||
"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.6.0-272",
|
||||
"chokidar-cli": "^3.0.0",
|
||||
"ts-node": "^10.2.1",
|
||||
"typescript": "^4.4.2",
|
||||
"@types/jest": "^27.0.3",
|
||||
"jest": "^27.4.0",
|
||||
"ts-jest": "^27.0.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13"
|
||||
}
|
||||
}
|
||||
|
13
fluence-js-examples/node-example/src/__test__/test.spec.ts
Normal file
13
fluence-js-examples/node-example/src/__test__/test.spec.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { justStop, runServer } from '../main';
|
||||
import { demoCalculation } from '../_aqua/demo-calculation';
|
||||
|
||||
describe('smoke test', () => {
|
||||
it('should work', async () => {
|
||||
await runServer();
|
||||
|
||||
const res = await demoCalculation();
|
||||
await justStop();
|
||||
|
||||
expect(res).toBe(7);
|
||||
}, 15000);
|
||||
});
|
@ -1,64 +1,3 @@
|
||||
import { Fluence, KeyPair } from "@fluencelabs/fluence";
|
||||
import { krasnodar } from "@fluencelabs/fluence-network-environment";
|
||||
import { registerCalc, CalcDef } from "./_aqua/calc";
|
||||
import { runServer, waitForKeypressAndStop } from './main';
|
||||
|
||||
class Calc implements CalcDef {
|
||||
private _state: number = 0;
|
||||
|
||||
add(n: number) {
|
||||
this._state += n;
|
||||
}
|
||||
|
||||
subtract(n: number) {
|
||||
this._state -= n;
|
||||
}
|
||||
|
||||
multiply(n: number) {
|
||||
this._state *= n;
|
||||
}
|
||||
|
||||
divide(n: number) {
|
||||
this._state /= n;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._state = 0;
|
||||
}
|
||||
|
||||
getResult() {
|
||||
return this._state;
|
||||
}
|
||||
}
|
||||
|
||||
const keypress = async () => {
|
||||
process.stdin.setRawMode(true);
|
||||
return new Promise<void>((resolve) =>
|
||||
process.stdin.once("data", () => {
|
||||
process.stdin.setRawMode(false);
|
||||
resolve();
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const relay = krasnodar[0];
|
||||
// generated with `npx aqua create_keypair`
|
||||
const skBytes = "tOpsT08fvYMnRypj3VtSoqWMN5W/AptKsP39yanlkg4=";
|
||||
|
||||
async function main() {
|
||||
await Fluence.start({
|
||||
connectTo: relay,
|
||||
KeyPair: await KeyPair.fromEd25519SK(Buffer.from(skBytes, "base64")),
|
||||
});
|
||||
|
||||
registerCalc(new Calc());
|
||||
|
||||
console.log("application started");
|
||||
console.log("peer id is: ", Fluence.getStatus().peerId);
|
||||
console.log("relay is: ", Fluence.getStatus().relayPeerId);
|
||||
console.log("press any key to continue");
|
||||
await keypress();
|
||||
|
||||
await Fluence.stop();
|
||||
}
|
||||
|
||||
main();
|
||||
runServer().then(waitForKeypressAndStop);
|
||||
|
62
fluence-js-examples/node-example/src/main.ts
Normal file
62
fluence-js-examples/node-example/src/main.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { Fluence, KeyPair } from '@fluencelabs/fluence';
|
||||
import { krasnodar } from '@fluencelabs/fluence-network-environment';
|
||||
import { registerCalc, CalcDef } from './_aqua/calc';
|
||||
|
||||
class Calc implements CalcDef {
|
||||
private _state: number = 0;
|
||||
|
||||
add(n: number) {
|
||||
this._state += n;
|
||||
}
|
||||
|
||||
subtract(n: number) {
|
||||
this._state -= n;
|
||||
}
|
||||
|
||||
multiply(n: number) {
|
||||
this._state *= n;
|
||||
}
|
||||
|
||||
divide(n: number) {
|
||||
this._state /= n;
|
||||
}
|
||||
|
||||
reset() {
|
||||
this._state = 0;
|
||||
}
|
||||
|
||||
getResult() {
|
||||
return this._state;
|
||||
}
|
||||
}
|
||||
|
||||
const relay = krasnodar[0];
|
||||
// generated with `npx aqua create_keypair`
|
||||
const skBytes = 'tOpsT08fvYMnRypj3VtSoqWMN5W/AptKsP39yanlkg4=';
|
||||
|
||||
export async function runServer() {
|
||||
await Fluence.start({
|
||||
connectTo: relay,
|
||||
KeyPair: await KeyPair.fromEd25519SK(Buffer.from(skBytes, 'base64')),
|
||||
});
|
||||
|
||||
registerCalc(new Calc());
|
||||
|
||||
console.log('application started');
|
||||
console.log('peer id is: ', Fluence.getStatus().peerId);
|
||||
console.log('relay is: ', Fluence.getStatus().relayPeerId);
|
||||
console.log('press any key to quit...');
|
||||
}
|
||||
|
||||
export async function justStop() {
|
||||
await Fluence.stop();
|
||||
}
|
||||
|
||||
export async function waitForKeypressAndStop() {
|
||||
process.stdin.setRawMode(true);
|
||||
process.stdin.resume();
|
||||
process.stdin.on('data', async () => {
|
||||
await Fluence.stop();
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
@ -1,7 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2015",
|
||||
"module": "CommonJS",
|
||||
"skipLibCheck": true
|
||||
}
|
||||
"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"
|
||||
],
|
||||
}
|
6
package-lock.json
generated
Normal file
6
package-lock.json
generated
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "examples",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
8
quickstart/1-browser-to-browser/.prettierrc.js
Normal file
8
quickstart/1-browser-to-browser/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
8
quickstart/1-browser-to-browser/jest.config.js
Normal file
8
quickstart/1-browser-to-browser/jest.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
preset: 'jest-puppeteer',
|
||||
testMatch: ['**/?(*.)+(spec|test).[t]s'],
|
||||
testPathIgnorePatterns: ['/node_modules/', 'dist'],
|
||||
transform: {
|
||||
'^.+\\.ts?$': 'ts-jest',
|
||||
},
|
||||
};
|
83897
quickstart/1-browser-to-browser/package-lock.json
generated
83897
quickstart/1-browser-to-browser/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,54 +1,65 @@
|
||||
{
|
||||
"name": "getting-started-browser",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-278",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"chokidar-cli": "^2.1.0",
|
||||
"node-sass": "^6.0.1"
|
||||
}
|
||||
"name": "getting-started-browser",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.19.2",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"@types/serve-handler": "^6.1.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^5.0.0",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all",
|
||||
"not ie 11",
|
||||
"not android 4.4.3-4.4.4"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.0-275",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"chokidar-cli": "^2.1.0",
|
||||
"jest-puppeteer": "^6.0.2",
|
||||
"node-sass": "^6.0.1",
|
||||
"serve": "^13.0.2",
|
||||
"ts-jest": "^27.1.3"
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,9 @@ function App() {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="bold">Peer id:</td>
|
||||
<td className="mono">{Fluence.getStatus().peerId!}</td>
|
||||
<td className="mono">
|
||||
<span id="peerId">{Fluence.getStatus().peerId!}</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn-clipboard"
|
||||
@ -68,7 +70,11 @@ function App() {
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bold">Relay peer id:</td>
|
||||
<td className="mono">{Fluence.getStatus().relayPeerId}</td>
|
||||
<td className="mono">
|
||||
<span id="relayId">
|
||||
{Fluence.getStatus().relayPeerId}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn-clipboard"
|
||||
@ -90,6 +96,7 @@ function App() {
|
||||
<div className="row">
|
||||
<label className="label bold">Target peer id</label>
|
||||
<input
|
||||
id="targetPeerId"
|
||||
className="input"
|
||||
type="text"
|
||||
onChange={(e) => setPeerIdInput(e.target.value)}
|
||||
@ -99,6 +106,7 @@ function App() {
|
||||
<div className="row">
|
||||
<label className="label bold">Target relay</label>
|
||||
<input
|
||||
id="targetRelayId"
|
||||
className="input"
|
||||
type="text"
|
||||
onChange={(e) => setRelayPeerIdInput(e.target.value)}
|
||||
@ -132,7 +140,7 @@ function App() {
|
||||
{helloMessage && (
|
||||
<>
|
||||
<h2>Message</h2>
|
||||
<div> {helloMessage} </div>
|
||||
<div id="message"> {helloMessage} </div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
104
quickstart/1-browser-to-browser/src/__test__/test.spec.ts
Normal file
104
quickstart/1-browser-to-browser/src/__test__/test.spec.ts
Normal file
@ -0,0 +1,104 @@
|
||||
import { Page } from 'puppeteer';
|
||||
import handler from 'serve-handler';
|
||||
import http from 'http';
|
||||
import path from 'path';
|
||||
|
||||
const port = 3000;
|
||||
const uri = `http://localhost:${port}/`;
|
||||
const publicPath = path.join(__dirname, '../../build/');
|
||||
|
||||
console.log(publicPath);
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
return handler(request, response, {
|
||||
public: publicPath,
|
||||
});
|
||||
});
|
||||
|
||||
const startServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.listen(port, resolve);
|
||||
});
|
||||
};
|
||||
|
||||
const stopServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.close(resolve);
|
||||
});
|
||||
};
|
||||
|
||||
const peerIdLength = '12D3KooWM2CYSHefG6KPKbYFAgsbPh8p6b8HYHc6VNkge2rPtYv5'.length;
|
||||
|
||||
const loadApp = async (page: Page) => {
|
||||
console.log('opening page...');
|
||||
await page.goto(uri);
|
||||
|
||||
console.log('clicking connect button...');
|
||||
await page.click('.btn');
|
||||
|
||||
console.log('waiting for fluence to connect...');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
console.log('waiting for "say hello" button to appear...');
|
||||
await page.waitForSelector('.btn-hello');
|
||||
|
||||
console.log('getting self peer id and relay...');
|
||||
const peerId = await page.$eval('#peerId', (x) => x.textContent);
|
||||
const relayId = await page.$eval('#relayId', (x) => x.textContent);
|
||||
|
||||
expect(peerId?.length).toBe(peerIdLength);
|
||||
expect(relayId?.length).toBe(peerIdLength);
|
||||
|
||||
return {
|
||||
peerId,
|
||||
relayId,
|
||||
};
|
||||
};
|
||||
|
||||
const waitForSelectorAndGetText = async (page: Page, selector: string) => {
|
||||
const page1Message = await page.waitForSelector('#message');
|
||||
return await page1Message?.evaluate((x) => x.textContent?.trim().replace('\n', ''));
|
||||
};
|
||||
|
||||
describe('smoke test', () => {
|
||||
beforeAll(startServer);
|
||||
|
||||
afterAll(stopServer);
|
||||
|
||||
it('should work', async () => {
|
||||
const page1 = await browser.newPage();
|
||||
const page2 = await browser.newPage();
|
||||
|
||||
console.log('=== browser 1 ===');
|
||||
const peerRelay1 = await loadApp(page1);
|
||||
|
||||
console.log('=== browser 2 ===');
|
||||
const peerRelay2 = await loadApp(page2);
|
||||
|
||||
console.log('=== browser 1 ===');
|
||||
|
||||
console.log('filling form...');
|
||||
await page1.focus('#targetPeerId');
|
||||
await page1.keyboard.type(peerRelay2.peerId!);
|
||||
|
||||
await page1.focus('#targetRelayId');
|
||||
await page1.keyboard.type(peerRelay2.relayId!);
|
||||
|
||||
console.log('clicking "say hello"...');
|
||||
await page1.click('.btn-hello');
|
||||
|
||||
console.log('waiting for particle to execute...');
|
||||
await page1.waitForTimeout(1000);
|
||||
|
||||
console.log('=== finale ===');
|
||||
|
||||
console.log('getting message from page1...');
|
||||
const page1Message = await waitForSelectorAndGetText(page1, '#message');
|
||||
|
||||
console.log('getting message from page2...');
|
||||
const page2Message = await waitForSelectorAndGetText(page2, '#message');
|
||||
|
||||
expect(page1Message).toBe('Hello back to you, ' + peerRelay1.peerId);
|
||||
expect(page2Message).toBe('Hello from: ' + peerRelay1.peerId);
|
||||
}, 15000);
|
||||
});
|
@ -16,7 +16,7 @@
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"isolatedModules": false,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
|
8
quickstart/3-browser-to-service/.prettierrc.js
Normal file
8
quickstart/3-browser-to-service/.prettierrc.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
semi: true,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 120,
|
||||
tabWidth: 4,
|
||||
useTabs: false,
|
||||
};
|
8
quickstart/3-browser-to-service/jest.config.js
Normal file
8
quickstart/3-browser-to-service/jest.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
preset: 'jest-puppeteer',
|
||||
testMatch: ['**/?(*.)+(spec|test).[t]s'],
|
||||
testPathIgnorePatterns: ['/node_modules/', 'dist'],
|
||||
transform: {
|
||||
'^.+\\.ts?$': 'ts-jest',
|
||||
},
|
||||
};
|
83949
quickstart/3-browser-to-service/package-lock.json
generated
83949
quickstart/3-browser-to-service/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,54 +1,65 @@
|
||||
{
|
||||
"name": "getting-started-browser",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "^0.19.1",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "4.0.3",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.1-278",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"chokidar-cli": "^2.1.0",
|
||||
"node-sass": "^6.0.1"
|
||||
}
|
||||
"name": "getting-started-browser",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fluencelabs/fluence": "0.19.2",
|
||||
"@fluencelabs/fluence-network-environment": "^1.0.13",
|
||||
"@testing-library/jest-dom": "^5.14.1",
|
||||
"@testing-library/react": "^11.2.7",
|
||||
"@testing-library/user-event": "^12.8.3",
|
||||
"@types/jest": "^27.4.0",
|
||||
"@types/node": "^12.20.16",
|
||||
"@types/react": "^17.0.14",
|
||||
"@types/react-dom": "^17.0.9",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-scripts": "^5.0.0",
|
||||
"typescript": "^4.3.5",
|
||||
"web-vitals": "^1.1.2"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "copy-avm-public public",
|
||||
"prestart": "npm run compile-aqua",
|
||||
"prebuild": "npm run compile-aqua",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "jest --config=jest.config.js",
|
||||
"_test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"compile-aqua": "aqua -i ./aqua/ -o ./src/_aqua",
|
||||
"watch-aqua": "chokidar \"**/*.aqua\" -c \"npm run compile-aqua\""
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all",
|
||||
"not ie 11",
|
||||
"not android 4.4.3-4.4.4"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fluencelabs/aqua": "^0.6.0-275",
|
||||
"@fluencelabs/aqua-lib": "^0.4.0",
|
||||
"@types/jest-environment-puppeteer": "^4.4.1",
|
||||
"@types/puppeteer": "^5.4.4",
|
||||
"@types/serve-handler": "^6.1.1",
|
||||
"chokidar-cli": "^2.1.0",
|
||||
"jest-puppeteer": "^6.0.2",
|
||||
"node-sass": "^6.0.1",
|
||||
"serve": "^13.0.2",
|
||||
"ts-jest": "^27.1.3"
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,11 @@ function App() {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="bold">Peer id:</td>
|
||||
<td className="mono">{Fluence.getStatus().peerId!}</td>
|
||||
<td className="mono">
|
||||
<span id="peerId">
|
||||
{Fluence.getStatus().peerId!}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn-clipboard"
|
||||
@ -68,7 +72,11 @@ function App() {
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="bold">Relay peer id:</td>
|
||||
<td className="mono">{Fluence.getStatus().relayPeerId!}</td>
|
||||
<td className="mono">
|
||||
<span id="relayId">
|
||||
{Fluence.getStatus().relayPeerId!}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
className="btn-clipboard"
|
||||
@ -90,6 +98,7 @@ function App() {
|
||||
<div className="row">
|
||||
<label className="label bold">Target peer id</label>
|
||||
<input
|
||||
id="targetPeerId"
|
||||
className="input"
|
||||
type="text"
|
||||
onChange={(e) => setPeerIdInput(e.target.value)}
|
||||
@ -99,6 +108,7 @@ function App() {
|
||||
<div className="row">
|
||||
<label className="label bold">Target relay</label>
|
||||
<input
|
||||
id="targetRelayId"
|
||||
className="input"
|
||||
type="text"
|
||||
onChange={(e) => setRelayPeerIdInput(e.target.value)}
|
||||
@ -132,7 +142,7 @@ function App() {
|
||||
{helloMessage && (
|
||||
<>
|
||||
<h2>Message</h2>
|
||||
<div> {helloMessage} </div>
|
||||
<div id="message"> {helloMessage} </div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
103
quickstart/3-browser-to-service/src/__test__/test.spec.ts
Normal file
103
quickstart/3-browser-to-service/src/__test__/test.spec.ts
Normal file
@ -0,0 +1,103 @@
|
||||
import { Page } from 'puppeteer';
|
||||
import handler from 'serve-handler';
|
||||
import http from 'http';
|
||||
import path from 'path';
|
||||
|
||||
const port = 3000;
|
||||
const uri = `http://localhost:${port}/`;
|
||||
const publicPath = path.join(__dirname, '../../build/');
|
||||
|
||||
console.log(publicPath);
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
return handler(request, response, {
|
||||
public: publicPath,
|
||||
});
|
||||
});
|
||||
|
||||
const startServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.listen(port, resolve);
|
||||
});
|
||||
};
|
||||
|
||||
const stopServer = async () => {
|
||||
return new Promise((resolve: any) => {
|
||||
server.close(resolve);
|
||||
});
|
||||
};
|
||||
const peerIdLength = '12D3KooWM2CYSHefG6KPKbYFAgsbPh8p6b8HYHc6VNkge2rPtYv5'.length;
|
||||
|
||||
const loadApp = async (page: Page) => {
|
||||
console.log('opening page...');
|
||||
await page.goto('http://localhost:3000/');
|
||||
|
||||
console.log('clicking connect button...');
|
||||
await page.click('.btn');
|
||||
|
||||
console.log('waiting for fluence to connect...');
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
console.log('waiting for "say hello" button to appear...');
|
||||
await page.waitForSelector('.btn-hello');
|
||||
|
||||
console.log('getting self peer id and relay...');
|
||||
const peerId = await page.$eval('#peerId', (x) => x.textContent);
|
||||
const relayId = await page.$eval('#relayId', (x) => x.textContent);
|
||||
|
||||
expect(peerId?.length).toBe(peerIdLength);
|
||||
expect(relayId?.length).toBe(peerIdLength);
|
||||
|
||||
return {
|
||||
peerId,
|
||||
relayId,
|
||||
};
|
||||
};
|
||||
|
||||
const waitForSelectorAndGetText = async (page: Page, selector: string) => {
|
||||
const page1Message = await page.waitForSelector('#message');
|
||||
return await page1Message?.evaluate((x) => x.textContent?.trim().replace('\n', ''));
|
||||
};
|
||||
|
||||
describe('smoke test', () => {
|
||||
beforeAll(startServer);
|
||||
|
||||
afterAll(stopServer);
|
||||
|
||||
it('should work', async () => {
|
||||
const page1 = await browser.newPage();
|
||||
const page2 = await browser.newPage();
|
||||
|
||||
console.log('=== browser 1 ===');
|
||||
const peerRelay1 = await loadApp(page1);
|
||||
|
||||
console.log('=== browser 2 ===');
|
||||
const peerRelay2 = await loadApp(page2);
|
||||
|
||||
console.log('=== browser 1 ===');
|
||||
|
||||
console.log('filling form...');
|
||||
await page1.focus('#targetPeerId');
|
||||
await page1.keyboard.type(peerRelay2.peerId!);
|
||||
|
||||
await page1.focus('#targetRelayId');
|
||||
await page1.keyboard.type(peerRelay2.relayId!);
|
||||
|
||||
console.log('clicking "say hello"...');
|
||||
await page1.click('.btn-hello');
|
||||
|
||||
console.log('waiting for particle to execute...');
|
||||
await page1.waitForTimeout(1000);
|
||||
|
||||
console.log('=== finale ===');
|
||||
|
||||
console.log('getting message from page1...');
|
||||
const page1Message = await waitForSelectorAndGetText(page1, '#message');
|
||||
|
||||
console.log('getting message from page2...');
|
||||
const page2Message = await waitForSelectorAndGetText(page2, '#message');
|
||||
|
||||
expect(page1Message).toBe('Hello back to you, ' + peerRelay1.peerId);
|
||||
expect(page2Message).toBe('Hello from: ' + peerRelay1.peerId);
|
||||
}, 15000);
|
||||
});
|
@ -16,7 +16,7 @@
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"isolatedModules": false,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user