├── dist ├── featured.json ├── favicon.ico ├── css │ ├── fonts │ │ ├── icomoon.eot │ │ ├── icomoon.ttf │ │ └── icomoon.woff │ └── icomoon.css ├── webfonts │ └── fa-solid-900.woff2 └── index.html ├── src ├── components │ ├── service │ │ ├── moses-service │ │ │ ├── style.css │ │ │ ├── MosesOptionsSummary.js │ │ │ ├── MosesServiceResult.js │ │ │ ├── DatasetUpload.js │ │ │ ├── CrossValOpts.js │ │ │ └── TargetFeature.js │ │ ├── gene-annotation-service │ │ │ ├── mozi_globe.png │ │ │ ├── AnnotationSelection.js │ │ │ ├── GOFilter.js │ │ │ ├── visualizer.config.js │ │ │ └── GenePathwayFilter.js │ │ ├── emotion-recognition-service │ │ │ ├── emotion_recognition.css.cs.js │ │ │ └── EmotionVisualizer.js │ │ ├── image-viewer-helpers │ │ │ ├── ImageGridViewer.js │ │ │ └── MasonryLayout.js │ │ ├── standardComponents │ │ │ └── HoverIcon.js │ │ ├── NewsSummaryService.js │ │ ├── MosesService.js │ │ ├── analysis-helpers │ │ │ └── DatasetUploaderHelper.js │ │ ├── TranslationService.js │ │ ├── HolisticEdgeDetectionService.js │ │ ├── EmotionRecognitionService.js │ │ ├── SemanticSegmentation.js │ │ ├── TemplateService.js │ │ ├── ExampleService.js │ │ ├── FaceDetectService.js │ │ ├── FaceAlignService.js │ │ ├── NeuralSpeechSynthesis.js │ │ ├── BinarySemanticSimilarity.js │ │ ├── LongQuestionAsnswering.js │ │ └── ShortQuestionAnswering.js │ ├── Landing.js │ ├── feedback │ │ ├── vote.js │ │ └── comment.js │ ├── Footer.js │ ├── DAppModal.js │ ├── ConnectWallet.js │ ├── ReactStyles.js │ ├── Pricing.js │ ├── GetStarted.js │ ├── CardDeckers.js │ ├── Header.js │ └── ChannelHelper.js ├── models │ ├── NullGRPCV3Service.js │ ├── GRPCV3Service.js │ └── GRPCProtoV3Spec.js ├── sandbox │ ├── index.js │ ├── index.html │ ├── JobDetailsStandalone.js │ └── Standalone.js ├── requests.js ├── service_state.js ├── index.js ├── networks.js ├── index.html ├── grpc.js ├── css │ ├── profile.css │ └── background.css ├── protobuf.js ├── js │ └── gdpr.js └── util.js ├── config ├── paths.js ├── webpack.dev.js ├── webpack.prod-analyze.js ├── webpack.prod.js └── webpack.common.js ├── .circleci └── config.yml ├── scripts ├── serveDist.js └── deploy.js ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── LICENSE ├── .gitignore ├── package.json └── README.md /dist/featured.json: -------------------------------------------------------------------------------- 1 | [ 2 | "0x2ed982c220fed6c9374e63804670fc16bd481b8f" 3 | ] 4 | -------------------------------------------------------------------------------- /dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/singnet/snet-betav1-dapp/HEAD/dist/favicon.ico -------------------------------------------------------------------------------- /dist/css/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/singnet/snet-betav1-dapp/HEAD/dist/css/fonts/icomoon.eot -------------------------------------------------------------------------------- /dist/css/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/singnet/snet-betav1-dapp/HEAD/dist/css/fonts/icomoon.ttf -------------------------------------------------------------------------------- /dist/css/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/singnet/snet-betav1-dapp/HEAD/dist/css/fonts/icomoon.woff -------------------------------------------------------------------------------- /dist/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/singnet/snet-betav1-dapp/HEAD/dist/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /src/components/service/moses-service/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Roboto'); 2 | body { 3 | font-family: 'roboto'; 4 | } 5 | -------------------------------------------------------------------------------- /src/components/service/gene-annotation-service/mozi_globe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/singnet/snet-betav1-dapp/HEAD/src/components/service/gene-annotation-service/mozi_globe.png -------------------------------------------------------------------------------- /config/paths.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = { 4 | srcPath: path.join(__dirname, '..', 'src'), 5 | sandBoxPath: path.join(__dirname, '..', 'src','sandbox'), 6 | outPath: path.join(__dirname, '..', 'dist') 7 | } 8 | -------------------------------------------------------------------------------- /src/models/NullGRPCV3Service.js: -------------------------------------------------------------------------------- 1 | import GRPCV3Service from "./GRPCV3Service"; 2 | 3 | export default class NullGRPCV3Service extends GRPCV3Service { 4 | constructor() { 5 | super('NullService', null) 6 | } 7 | 8 | get methodNames() { 9 | return []; 10 | } 11 | 12 | hasSameName(_serviceName) { 13 | return false; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /config/webpack.dev.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge'); 2 | var common = require('./webpack.common.js'); 3 | var MiniCssExtractPlugin = require("mini-css-extract-plugin"); 4 | 5 | module.exports = env => { 6 | return merge(common(env.sandBox), { 7 | mode: 'development', 8 | plugins: [ 9 | new MiniCssExtractPlugin({ 10 | filename: 'css/[name].css' 11 | }) 12 | ] 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/golang:1.9-node 6 | working_directory: ~/singnet/snet-dapp 7 | environment: 8 | TRIGGER_BUILD_BRANCH: master 9 | steps: 10 | - checkout 11 | - run: 12 | name: Run install script 13 | command: npm install 14 | - run: 15 | name: Run build script 16 | command: npm run build 17 | 18 | -------------------------------------------------------------------------------- /src/models/GRPCV3Service.js: -------------------------------------------------------------------------------- 1 | export default class GRPCV3Service { 2 | constructor(serviceName, serviceObject) { 3 | this._serviceName = serviceName; 4 | 5 | this._methodNames = Object.keys(serviceObject["methods"]); 6 | } 7 | 8 | get serviceName() { 9 | return this._serviceName; 10 | } 11 | 12 | get methodNames() { 13 | return [...this._methodNames]; 14 | } 15 | 16 | hasSameName(serviceName) { 17 | return this._serviceName === serviceName; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /scripts/serveDist.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var express = require('express'); 3 | 4 | var paths = require('./../config/paths.js'); 5 | 6 | var app = express(); 7 | 8 | var PORT = 3000; 9 | 10 | app.get('/bundle*', (req, res, next) => { 11 | res.set('Content-Encoding', 'gzip'); 12 | res.set('Content-Type', 'text/javascript'); 13 | next(); 14 | }) 15 | 16 | app.use(express.static(paths.outPath)); 17 | 18 | app.listen(PORT, () => { console.log('Beta DApp running at http://localhost:' + PORT) }); 19 | -------------------------------------------------------------------------------- /src/sandbox/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Standalone from "./Standalone"; 4 | import {BrowserRouter,Route,Switch} from 'react-router-dom'; 5 | 6 | require('../css/style.css'); 7 | require('../css/background.css'); 8 | require('../css/profile.css'); 9 | 10 | ReactDOM.render( 11 | 12 |
13 | 14 | 15 | 16 |
17 |
18 | , 19 | document.getElementById('react-root') 20 | ); 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/components/service/emotion-recognition-service/emotion_recognition.css.cs.js: -------------------------------------------------------------------------------- 1 | export default { 2 | outsideWrapper: { 3 | width: '256px', 4 | height: '256px', 5 | margin: '20px 60px', 6 | border: '0px' 7 | }, 8 | insideWrapper: { 9 | width: '100%', 10 | height: '100%', 11 | position: 'relative' 12 | }, 13 | coveredImage: { 14 | width: '100%', 15 | height: '100%', 16 | position: 'absolute', 17 | top: '0px', 18 | left: '0px' 19 | }, 20 | coveringCanvas: { 21 | width: '100%', 22 | height: '100%', 23 | position: 'absolute', 24 | top: '0px', 25 | left: '0px' 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /config/webpack.prod-analyze.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var merge = require('webpack-merge'); 3 | var UglifyJSPlugin = require('uglifyjs-webpack-plugin'); 4 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; 5 | 6 | var common = require('./webpack.common.js'); 7 | 8 | module.exports = merge(common, { 9 | mode: 'production', 10 | 11 | plugins: [ 12 | new BundleAnalyzerPlugin(), 13 | new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }), 14 | new UglifyJSPlugin({ 15 | sourceMap: true, 16 | uglifyOptions: { 17 | compress: true, 18 | mangle: true, 19 | warnings: false 20 | } 21 | }) 22 | ] 23 | }); 24 | -------------------------------------------------------------------------------- /src/components/Landing.js: -------------------------------------------------------------------------------- 1 | import React, { props } from 'react'; 2 | import SampleServices from './Services'; 3 | import Homepage from './ConnectWallet.js'; 4 | import BlockchainHelper from "./BlockchainHelper.js"; 5 | 6 | export default class Landing extends React.Component { 7 | constructor() { 8 | super(props) 9 | this.network = new BlockchainHelper(); 10 | } 11 | 12 | componentDidMount() { 13 | window.addEventListener('load', () => this.handleWindowLoad()); 14 | this.handleWindowLoad(); 15 | } 16 | 17 | handleWindowLoad() { 18 | this.network.initialize().then().catch(err => { 19 | console.error(err); 20 | }) 21 | } 22 | 23 | render() { 24 | return ( 25 | 26 | {(typeof web3 !== 'undefined') ? : } 27 | 28 | ) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/requests.js: -------------------------------------------------------------------------------- 1 | export class Requests { 2 | 3 | static getPostBody(requestObject) { 4 | const body = { 5 | 'mode': 'cors', 6 | headers: { 7 | "Content-Type": "application/json", 8 | }, 9 | method: 'POST', 10 | body: JSON.stringify(requestObject) 11 | } 12 | return body 13 | } 14 | 15 | static async post(url, requestObject) { 16 | try { 17 | const data = await fetch(url, Requests.getPostBody(requestObject)) 18 | .then(response => response.json()) 19 | .then(json => { 20 | return json; 21 | }) 22 | .catch(err => { 23 | return err 24 | }); 25 | return data 26 | } catch (err) { 27 | console.log(err) 28 | } 29 | } 30 | 31 | static async get(url) { 32 | try { 33 | const resp = await fetch(url) 34 | const data = await resp.json() 35 | return data 36 | } catch (err) { 37 | console.log(err) 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/sandbox/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | SingularityNET Beta Dapp 22 | 23 | 24 | 27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /config/webpack.prod.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var merge = require('webpack-merge'); 3 | var UglifyJSPlugin = require('uglifyjs-webpack-plugin'); 4 | var CompressionPlugin = require('compression-webpack-plugin'); 5 | var MiniCssExtractPlugin = require("mini-css-extract-plugin"); 6 | 7 | var common = require('./webpack.common.js'); 8 | 9 | module.exports = merge(common('false'), { 10 | mode: 'production', 11 | 12 | plugins: [ 13 | new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }), 14 | new UglifyJSPlugin({ 15 | sourceMap: true, 16 | uglifyOptions: { 17 | compress: true, 18 | mangle: true, 19 | warnings: false 20 | } 21 | }), 22 | new CompressionPlugin({ 23 | test: /\.js/, 24 | filename (asset) { 25 | return asset.replace('.gz', '') 26 | } 27 | }), 28 | new MiniCssExtractPlugin({ 29 | filename: 'css/[name].[hash].css' 30 | }) 31 | ] 32 | }); 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 SingularityNET 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/components/feedback/vote.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'react-perfect-scrollbar/dist/css/styles.css'; 3 | 4 | 5 | const Vote = ({upVote,downVote,toggleVote}) =>{ 6 | return( 7 | 8 |
9 |

Vote

10 |
11 |
12 | toggleVote('up')}/> 13 |
14 |
15 |
16 |
17 | toggleVote('down')}/> 18 |
19 |
20 |
21 |
22 | ) 23 | } 24 | 25 | export default Vote; 26 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | SingularityNET Beta Dapp
-------------------------------------------------------------------------------- /src/service_state.js: -------------------------------------------------------------------------------- 1 | export const serviceStateJSON = { 2 | "nested": { 3 | "escrow": { 4 | "nested": { 5 | "PaymentChannelStateService": { 6 | "methods": { 7 | "GetChannelState": { 8 | "requestType": "ChannelStateRequest", 9 | "responseType": "ChannelStateReply" 10 | } 11 | } 12 | }, 13 | "ChannelStateRequest": { 14 | "fields": { 15 | "channelId": { 16 | "type": "bytes", 17 | "id": 1 18 | }, 19 | "signature": { 20 | "type": "bytes", 21 | "id": 2 22 | } 23 | } 24 | }, 25 | "ChannelStateReply": { 26 | "fields": { 27 | "currentNonce": { 28 | "type": "bytes", 29 | "id": 1 30 | }, 31 | "currentSignedAmount": { 32 | "type": "bytes", 33 | "id": 2 34 | }, 35 | "currentSignature": { 36 | "type": "bytes", 37 | "id": 3 38 | } 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/components/Footer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const tosKey="hasACC3p3t3d" 4 | export default class Footer extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { 8 | acceptedTOC: this.hasAcceptedTOC() 9 | } 10 | this.handleAcceptedTOC = this.handleAcceptedTOC.bind(this); 11 | } 12 | 13 | hasAcceptedTOC() { 14 | return window.localStorage.getItem(tosKey) || false; 15 | } 16 | 17 | acceptTOC() { 18 | window.localStorage.setItem(tosKey, true); 19 | } 20 | 21 | handleAcceptedTOC(){ 22 | this.setState({ 23 | acceptedTOC: true 24 | }) 25 | this.acceptTOC() 26 | } 27 | 28 | 29 | render() { 30 | return ( 31 | 32 | {this.state.acceptedTOC ? 33 | null: 34 |
35 |

By continuing to browse the site you agree to our storing of cookies on your browser to enhance site navigation as well agree to our Terms and conditions

36 | 37 |
} 38 |
39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/bundle.* 2 | dist/index.html 3 | dist/css 4 | dist/css/* 5 | dist/src 6 | 7 | # Logs 8 | logs 9 | *.log 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # TypeScript v1 declaration files 46 | typings/ 47 | 48 | # Optional npm cache directory 49 | .npm 50 | 51 | # Optional eslint cache 52 | .eslintcache 53 | 54 | # Optional REPL history 55 | .node_repl_history 56 | 57 | # Output of 'npm pack' 58 | *.tgz 59 | 60 | # Yarn Integrity file 61 | .yarn-integrity 62 | 63 | # dotenv environment variables file 64 | .env 65 | 66 | # next.js build output 67 | .next 68 | /.idea/ 69 | src/networks.js 70 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Header from "./components/Header.js"; 4 | import {BrowserRouter,Route,Switch} from 'react-router-dom'; 5 | import {Account} from "./components/Account.js"; 6 | import SampleServices from './components/Services'; 7 | import Landingpage from "./components/Landing.js"; 8 | import connectwallet from "./components/ConnectWallet.js"; 9 | import GetStarted from "./components/GetStarted.js"; 10 | import Footer from './components/Footer.js'; 11 | import GDPR from './js/gdpr'; 12 | 13 | require('./css/style.css'); 14 | require('./css/background.css'); 15 | require('./css/profile.css'); 16 | 17 | GDPR(); 18 | 19 | ReactDOM.render( 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 |
34 | , 35 | document.getElementById('react-root') 36 | ); 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /scripts/deploy.js: -------------------------------------------------------------------------------- 1 | const { outPath } = require("./../config/paths.js") 2 | 3 | const [ ,, Bucket, region ] = process.argv 4 | console.log("Region " + region + " Bucket " + Bucket); 5 | 6 | const { createReadStream, readdirSync } = require("fs") 7 | const { join, relative } = require("path") 8 | const { cwd } = require("process") 9 | const readdir = require("recursive-readdir") 10 | const mime = require("mime-types") 11 | const AWS = require("aws-sdk") 12 | AWS.config.update({ region }) 13 | const s3 = new AWS.S3({ "apiVersion": "2006-03-01" }) 14 | 15 | const getFilePath = file => 16 | relative(cwd(), file).split("/").slice(1).join("/") 17 | 18 | readdir(outPath) 19 | .then(files => Promise.all(files.map(Key => { 20 | const fileRelativePath = getFilePath(Key) 21 | console.log(fileRelativePath) 22 | return s3.upload({ 23 | Bucket, 24 | "Key": fileRelativePath, 25 | "ContentType": mime.lookup(Key), 26 | "Body": createReadStream(Key), 27 | "CacheControl": fileRelativePath === "index.html" ? "no-cache, no-store, must-revalidate" : "public, max-age=31536000", 28 | ...(Key.includes("bundle") ? { "ContentEncoding": "gzip" } : {}) 29 | }).promise() 30 | }))) 31 | .then(() => { console.log(`Files uploaded successfully`) }) 32 | .catch(error => { console.log(error) }) 33 | -------------------------------------------------------------------------------- /src/networks.js: -------------------------------------------------------------------------------- 1 | export const NETWORKS = { 2 | 1: { 3 | name: "Main Ethereum Network", 4 | etherscan: 'https://etherscan.io', 5 | infura: 'http://mainnet.infura.io', 6 | marketplace:'', 7 | protobufjs:'' 8 | }, 9 | 3: { 10 | name: "Ropsten Test Network", 11 | etherscan: 'https://ropsten.etherscan.io', 12 | infura: 'https://ropsten.infura.io', 13 | marketplace:'https://260r82zgt7.execute-api.us-east-1.amazonaws.com/ropsten/', 14 | protobufjs:'https://protojs.singularitynet.io/ropsten/', 15 | default:true 16 | }, 17 | 4: { 18 | name: "Rinkeby Test Network", 19 | etherscan: 'https://rinkeby.etherscan.io', 20 | infura: 'https://rinkeby.infura.io', 21 | marketplace:'', 22 | protobufjs:'' 23 | }, 24 | 42: { 25 | name: "Kovan Test Network", 26 | etherscan: 'https://kovan.etherscan.io', 27 | infura: 'https:/kovan.infura.io', 28 | marketplace:'https://260r82zgt7.execute-api.us-east-1.amazonaws.com/kovan/', 29 | protobufjs:'https://protojs.singularitynet.io/kovan/' 30 | }, 31 | }; 32 | 33 | export function getMarketplaceURL(chainId) { 34 | return (chainId in NETWORKS ? NETWORKS[chainId]['marketplace'] : undefined); 35 | } 36 | 37 | export function getProtobufjsURL(chainId) { 38 | return (chainId in NETWORKS ? NETWORKS[chainId]['protobufjs'] : undefined); 39 | } 40 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | SingularityNET Beta Dapp 27 | 28 | 29 | 36 | 37 | 38 | 41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /src/sandbox/JobDetailsStandalone.js: -------------------------------------------------------------------------------- 1 | import { hasOwnDefinedProperty } from '../util' 2 | import 'react-perfect-scrollbar/dist/css/styles.css'; 3 | import {Jobdetails} from '../components/JobDetails.js'; 4 | import React, { Fragment } from 'react'; 5 | import PricingStrategy from "../components/Pricing.js" 6 | 7 | export class JobdetailsStandalone extends Jobdetails { 8 | constructor(props) { 9 | super(props) 10 | this.serviceSpecJSON = '' 11 | this.endpoint = '' 12 | } 13 | 14 | onOpenJobDetails(data) { 15 | this.serviceSpecJSON = data["serviceSpecJSON"] 16 | this.endpoint = data['endpoint'] 17 | data['pricing_strategy'] = new PricingStrategy("{\"price_model\": \"fixed_price\", \"price_in_cogs\": 1}"); 18 | 19 | super.setServiceSpec(data["serviceSpecJSON"]) 20 | super.onOpenJobDetails(data); 21 | super.seedDefaultValues(true, 1); 22 | } 23 | 24 | startjob() { 25 | super.seedDefaultValues(true, 1); 26 | } 27 | 28 | handleJobInvocation(serviceName, methodName, requestObject) { 29 | const serviceObj = this.serviceSpecJSON.lookup(serviceName) 30 | const packageName = Object.keys(this.serviceSpecJSON.nested).find(key => 31 | typeof this.serviceSpecJSON.nested[key] === "object" && 32 | hasOwnDefinedProperty(this.serviceSpecJSON.nested[key], "nested") 33 | ) 34 | super.makeGRPCCall(serviceObj, this.endpoint, packageName, serviceName, methodName, {}, requestObject) 35 | } 36 | 37 | render() { 38 | return( 39 | 40 | {super.render()} 41 | 42 | ) 43 | } 44 | } -------------------------------------------------------------------------------- /src/models/GRPCProtoV3Spec.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { hasOwnDefinedProperty } from "../util"; 3 | import GRPCV3Service from "./GRPCV3Service"; 4 | import NullGRPCV3Service from "./NullGRPCV3Service"; 5 | 6 | export default class GRPCProtoV3Spec { 7 | constructor(serviceSpec) { 8 | this._serviceSpec = serviceSpec; 9 | this._services = this.parseServices(); 10 | } 11 | 12 | parseServices() { 13 | const packageName = this._getPackageName(); 14 | const specDefinitions = this._getSpecDefinitions(packageName); 15 | 16 | function hasMethods(specDefinition) { 17 | return specDefinition.hasOwnProperty("methods"); 18 | } 19 | 20 | const services = _.reduce(specDefinitions, (serviceAccumulator, specDefinition, specKey) => { 21 | const isService = typeof specDefinition === 'object' && specDefinition !== null && hasMethods(specDefinition); 22 | 23 | if(!isService) { 24 | return serviceAccumulator; 25 | } 26 | 27 | const service = new GRPCV3Service(specKey, specDefinition); 28 | return [...serviceAccumulator, service]; 29 | }, []); 30 | 31 | return services; 32 | } 33 | 34 | _getPackageName() { 35 | const packageName = _.findKey(this._serviceSpec.nested, (obj) => { 36 | return typeof obj === "object" && hasOwnDefinedProperty(obj, "nested"); 37 | }); 38 | 39 | return packageName || ''; 40 | } 41 | 42 | _getSpecDefinitions(packageName) { 43 | if(packageName) { 44 | return this._serviceSpec.lookup(packageName); 45 | } 46 | 47 | return this._serviceSpec.nested; 48 | } 49 | 50 | get services() { 51 | return [...this._services]; 52 | } 53 | 54 | findServiceByName(serviceName) { 55 | const service = _.find(this._services, (service) => service.hasSameName(serviceName)); 56 | return service || new NullGRPCV3Service(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/service/gene-annotation-service/AnnotationSelection.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { 4 | Checkbox, 5 | FormControlLabel, 6 | Grid, 7 | Typography 8 | } from "@material-ui/core"; 9 | 10 | const filterFormStyle = { 11 | paddingLeft: "25px", 12 | marginLeft: "5px", 13 | borderLeft: "dashed 1px #ddd" 14 | }; 15 | 16 | export default class AnnotationSelection extends React.Component { 17 | isAnnotationSelected(annotation) { 18 | return this.props.selectedAnnotations.some(sa => sa.name === annotation); 19 | } 20 | 21 | render() { 22 | return ( 23 | 24 | 25 | Annotations: 26 | 27 | 28 | 29 | {this.props.availableAnnotations.map(a => ( 30 | 31 | 37 | this.props.handleAnnotationsChanged( 38 | e.target.checked, 39 | e.target.name 40 | ) 41 | } 42 | /> 43 | } 44 | label={a.name} 45 | /> 46 |
47 | {this.isAnnotationSelected(a.key) && ( 48 |
49 | {a.fitlerForm(a.defaults, filter => 50 | this.props.handleFilterChanged(a.key, filter) 51 | )} 52 |
53 | )} 54 |
55 | ))} 56 |
57 |
58 |
59 | ); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/components/DAppModal.js: -------------------------------------------------------------------------------- 1 | import React, { props } from 'react'; 2 | import Dialog from '@material-ui/core/Dialog' 3 | import DialogContent from '@material-ui/core/DialogContent' 4 | import { Link } from 'react-router-dom' 5 | import 'react-perfect-scrollbar/dist/css/styles.css' 6 | import CircularProgress from '@material-ui/core/CircularProgress' 7 | 8 | 9 | export default class DAppModal extends React.Component { 10 | constructor() { 11 | super(props) 12 | 13 | } 14 | 15 | render() 16 | { 17 | // 18 | return( 19 | 20 | 21 | 22 |
23 |
24 | {(this.props.showProgress)? 25 | : 26 | null 27 | } 28 |
29 |
30 | {this.props.message} 31 |
32 |
33 | {(typeof this.props.link !== 'undefined')? 34 | 35 | 36 | :null} 37 |
38 |
39 |
40 |
41 |
42 | ) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/components/feedback/comment.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { TextField } from '@material-ui/core/es'; 4 | 5 | const Comment = ({userComment, handleUserComment}) =>{ 6 | return( 7 |
8 | 39 |
40 | ); 41 | } 42 | 43 | Comment.propTypes={ 44 | userComment: PropTypes.string, 45 | handleUserComment: PropTypes.func 46 | } 47 | export default Comment; -------------------------------------------------------------------------------- /src/components/service/moses-service/MosesOptionsSummary.js: -------------------------------------------------------------------------------- 1 | import React, { Component, Fragment } from "react"; 2 | import Typography from "@material-ui/core/Typography"; 3 | import Modal from "@material-ui/core/Modal"; 4 | import Table from "@material-ui/core/Table"; 5 | import TableBody from "@material-ui/core/TableBody"; 6 | import TableCell from "@material-ui/core/TableCell"; 7 | import TableHead from "@material-ui/core/TableHead"; 8 | import TableRow from "@material-ui/core/TableRow"; 9 | import Paper from "@material-ui/core/Paper"; 10 | import Button from "@material-ui/core/Button"; 11 | 12 | export default class MosesOptionsSummary extends Component { 13 | constructor(props) { 14 | super(props); 15 | } 16 | 17 | render() { 18 | return ( 19 | 20 | 21 | 32 | 33 | Moses Options 34 | 35 | 36 | 37 | 38 | Moses Option 39 | Value 40 | 41 | 42 | 43 | {this.props.options.map(option => ( 44 | 45 | 46 | {option.name} 47 | 48 | {option.value} 49 | 50 | ))} 51 | 52 |
53 |
54 |
55 |
56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/components/service/moses-service/MosesServiceResult.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { CheckCircle, Cancel } from "@material-ui/icons"; 3 | import { Grid, Card, CardContent } from "@material-ui/core"; 4 | 5 | export default class MosesServiceResult extends React.Component { 6 | renderError() { 7 | return ( 8 | 14 | 15 | 16 |
17 |

{this.props.result.description}

18 |
19 |
20 | ); 21 | } 22 | 23 | renderCompleted() { 24 | return ( 25 | 31 | 32 |

33 | 34 |
35 | Anlaysis started! 36 |

37 |

Follow the link below to check the status of the analysis.

38 |

47 | 52 | {this.props.result.resultUrl} 53 | 54 |

55 |
56 |
57 | ); 58 | } 59 | 60 | render() { 61 | return ( 62 | 63 | 64 | 65 | {this.props.result.resultUrl 66 | ? this.renderCompleted() 67 | : this.renderError()} 68 | 69 | 70 | 71 | ); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/components/service/image-viewer-helpers/ImageGridViewer.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Grid, Button, Hidden } from '@material-ui/core'; 3 | import { ArrowDownward } from '@material-ui/icons'; 4 | import MasonryLayout from './MasonryLayout'; 5 | import withWidth from '@material-ui/core/withWidth'; 6 | 7 | export class ImageGridViewer extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | } 11 | 12 | downloadImage(image) { 13 | const link = document.createElement('a'); 14 | link.setAttribute("type", "hidden"); 15 | link.setAttribute('href', image); 16 | link.setAttribute('download', 'result-image'); 17 | document.body.appendChild(link); 18 | link.click(); 19 | link.remove(); 20 | } 21 | 22 | renderContent(response, key) { 23 | return ( 24 |
32 | 40 | 47 |
48 | ); 49 | } 50 | 51 | render() { 52 | return ( 53 | 54 | this.renderContent(r, i))} 56 | /> 57 | 58 | ); 59 | } 60 | } 61 | 62 | export default withWidth()(ImageGridViewer); 63 | -------------------------------------------------------------------------------- /src/components/ConnectWallet.js: -------------------------------------------------------------------------------- 1 | import React, { props } from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | 4 | export default class ConnectWallet extends React.Component { 5 | constructor() { 6 | super(props) 7 | } 8 | 9 | render() { 10 | return ( 11 | 12 |
13 | 14 |
15 |
16 |
17 |

18 |
19 |
20 |
21 |
22 |
23 |
Welcome to SingularityNET
24 |
25 |
SingularityNET is an open and decentralized network of AI services made accessible through blockchain.
AI developers publish their services onto the SingularityNET network where they can be used by anyone with
an internet connection. This Dapp is a front-end for exploring available AI services and interacting with them
through a web-UI

26 | 27 |
28 |
29 |
30 | This Dapp allows you to browse the list of SingularityNET Agents from the SingularityNET Registry. You need a Metamask wallet to invoke a service.

31 | 32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | ) 40 | } 41 | } -------------------------------------------------------------------------------- /src/components/ReactStyles.js: -------------------------------------------------------------------------------- 1 | import { createMuiTheme } from "@material-ui/core/styles" 2 | import Typography from '@material-ui/core/Typography' 3 | import PropTypes from 'prop-types' 4 | import React from 'react' 5 | 6 | /* 7 | const styles = theme => ({ 8 | root: { 9 | flexGrow: 1, 10 | backgroundColor: theme.palette.background.paper, 11 | }, 12 | });*/ 13 | 14 | export const ProfileTabContainer = (props) => { 15 | return ( 16 | 17 | {props.children} 18 | 19 | ); 20 | } 21 | ProfileTabContainer.propTypes = { 22 | children: PropTypes.node.isRequired, 23 | }; 24 | 25 | export const TabContainer = (props) => { 26 | return ( 27 | 28 | {props.children} 29 | 30 | ); 31 | } 32 | 33 | TabContainer.propTypes = { 34 | children: PropTypes.node.isRequired, 35 | }; 36 | 37 | export const ModalStylesAlertWait = { 38 | position: 'center', 39 | borderRadius: '6px', 40 | backgroundColor: 'white', 41 | fontFamily: "Muli", 42 | fontSize: "13px", 43 | color: 'black', 44 | height: '100px', 45 | width: '450px', 46 | padding: '10px', 47 | boxShadow: '#e8e8e8 0px 2px 2px 2px', 48 | margin: 'auto' 49 | } 50 | 51 | //Get modalstyles for alert// 52 | export const ModalStylesAlert = { 53 | fontFamily: "Muli", 54 | position: 'relative', 55 | borderRadius: 3, 56 | border: 5, 57 | color: 'white', 58 | lineHeight: 40, 59 | height: 100, 60 | width: 750, 61 | padding: '0 10px', 62 | boxShadow: '0 3px 5px 2px gray', 63 | top: 450, 64 | left: 350, 65 | } 66 | export const theme = createMuiTheme({ 67 | typography: { 68 | useNextVariants: true, 69 | }, 70 | overrides: { 71 | MuiButton: { 72 | root: { 73 | background: 'white', 74 | borderRadius: 3, 75 | border: 0, 76 | color: 'white', 77 | height: 38, 78 | padding: '0 30px', 79 | boxShadow: '0 3px 5px 2px lightblue', 80 | fontFamily: "Muli", 81 | fontSize: "12px", 82 | }, 83 | }, 84 | }, 85 | }); -------------------------------------------------------------------------------- /src/components/service/gene-annotation-service/GOFilter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { TextField, Grid, Checkbox, FormControlLabel } from "@material-ui/core"; 3 | 4 | const namespaces = [ 5 | { label: "Biological process", value: "biological_process" }, 6 | { label: "Cellular component", value: "cellular_component" }, 7 | { label: "Molecular function", value: "molecular_function" } 8 | ]; 9 | 10 | export default class GOFilter extends React.Component { 11 | constructor(props) { 12 | super(props); 13 | this.namespaces = this.props.defaults.namespace; 14 | } 15 | render() { 16 | return ( 17 | 18 |
19 | {namespaces.map(n => ( 20 | { 30 | if (e.target.checked) { 31 | this.namespaces.push(e.target.name); 32 | } else { 33 | this.namespaces = this.namespaces.filter( 34 | n => n !== e.target.name 35 | ); 36 | } 37 | this.props.handleFilterChanged({ 38 | namespace: this.namespaces 39 | }); 40 | }} 41 | /> 42 | } 43 | label={n.label} 44 | /> 45 | ))} 46 | 47 | 48 | 49 | 58 | this.props.handleFilterChanged({ parents: n.target.value }) 59 | } 60 | /> 61 | 62 | 63 | 64 |
65 | ); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /dist/css/icomoon.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "icomoon"; 3 | src: url("fonts/icomoon.eot?d067fx"); 4 | src: url("fonts/icomoon.eot?d067fx#iefix") format("embedded-opentype"), 5 | url("fonts/icomoon.ttf?d067fx") format("truetype"), 6 | url("fonts/icomoon.woff?d067fx") format("woff"), 7 | url("fonts/icomoon.svg?d067fx#icomoon") format("svg"); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], 13 | [class*=" icon-"] { 14 | /* use !important to prevent issues with browser extensions that change fonts */ 15 | font-family: "icomoon" !important; 16 | speak: none; 17 | font-style: normal; 18 | font-weight: normal; 19 | font-variant: normal; 20 | text-transform: none; 21 | line-height: 1; 22 | 23 | /* Better Font Rendering =========== */ 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | .icon-count-dislike:before { 29 | content: "\e900"; 30 | color: #fff; 31 | text-shadow: -1px 0 #4086ff, 0 1px #4086ff, 1px 0 #4086ff, 0 -1px #4086ff; 32 | font-size: 26px; 33 | } 34 | 35 | .icon-count-like:before { 36 | content: "\e901"; 37 | color: #fff; 38 | text-shadow: -1px 0 #4086ff, 0 1px #4086ff, 1px 0 #4086ff, 0 -1px #4086ff; 39 | font-size: 26px; 40 | } 41 | 42 | .icon-count-dislike-enabled:before { 43 | content: "\e900"; 44 | color: #4086ff; 45 | font-size: 26px; 46 | } 47 | 48 | .icon-count-like-enabled:before { 49 | content: "\e901"; 50 | color: #4086ff; 51 | font-size: 26px; 52 | } 53 | 54 | .icon-dislike:before { 55 | content: "\e900"; 56 | color: #757577; 57 | font-size: 26px; 58 | cursor: pointer; 59 | } 60 | .icon-like:before { 61 | content: "\e901"; 62 | color: #4086ff; 63 | font-size: 26px; 64 | cursor: pointer; 65 | } 66 | 67 | .icon-like-disabled:before { 68 | content: "\e901"; 69 | color: #757577; 70 | font-size: 26px; 71 | cursor: pointer; 72 | } 73 | 74 | .icon-dislike-enabled:before { 75 | content: "\e900"; 76 | color: #4086ff; 77 | font-size: 26px; 78 | cursor: pointer; 79 | } 80 | 81 | .icon-home-icon-silhouette:before { 82 | content: "\e902"; 83 | font-size: 20px; 84 | } 85 | 86 | .icon-logo:before { 87 | content: "\e903"; 88 | color: #fff; 89 | font-size: 50px 90 | } 91 | 92 | .icon-user-3:before { 93 | content: "\e904"; 94 | font-size: 20px; 95 | } -------------------------------------------------------------------------------- /src/components/service/standardComponents/HoverIcon.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Typography from "@material-ui/core/Typography"; 3 | import { Tooltip, IconButton } from "@material-ui/core"; 4 | import PropTypes from "prop-types"; 5 | import { blue, grey } from "@material-ui/core/colors"; 6 | 7 | export default class HoverIcon extends React.Component{ 8 | constructor(props){ 9 | super(props); 10 | this.state={ 11 | hover: false, 12 | }; 13 | this.renderIconButton = this.renderIconButton.bind(this); 14 | } 15 | 16 | renderIconButton(){ 17 | let {children} = this.props; 18 | return( 19 | 31 | {children} 32 | 33 | ) 34 | } 35 | 36 | render(){ 37 | return( 38 | this.props.text ? 39 | 47 | {this.props.text} 48 | 49 | }> 50 | {this.renderIconButton()} 51 | 52 | : 53 | this.renderIconButton() 54 | ) 55 | } 56 | 57 | } 58 | 59 | HoverIcon.propTypes = { 60 | text: PropTypes.string, 61 | textColor: PropTypes.string, 62 | fontFamily: PropTypes.string, 63 | fontSize: PropTypes.number, 64 | href: PropTypes.string, 65 | onColor: PropTypes.string, 66 | offColor: PropTypes.string, 67 | }; 68 | 69 | HoverIcon.defaultProps = { 70 | text: null, 71 | fontFamily: "Muli", 72 | fontSize: 14, 73 | textColor: "white", 74 | onColor: blue[500], 75 | offColor: grey[600], 76 | }; 77 | -------------------------------------------------------------------------------- /config/webpack.common.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | 4 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | var MiniCssExtractPlugin = require("mini-css-extract-plugin"); 6 | 7 | var paths = require('./paths.js') 8 | 9 | module.exports = function(isSandBox) { 10 | var codePath = isSandBox === 'true' ? paths.sandBoxPath : paths.srcPath; 11 | 12 | return { 13 | entry: path.join(codePath, 'index.js'), 14 | 15 | output: { 16 | path: paths.outPath, 17 | filename: 'bundle.[chunkhash:8].js' 18 | }, 19 | 20 | devtool: 'source-map', 21 | devServer: { 22 | historyApiFallback: true, 23 | contentBase: paths.outPath, 24 | disableHostCheck: true 25 | }, 26 | 27 | module: { 28 | rules: [ 29 | { 30 | test: /\.js$/, 31 | loader: 'babel-loader', 32 | include: paths.srcPath, 33 | exclude: /node_modules/, 34 | options: { 35 | presets: [ 36 | ['es2015', { modules: false }], 'react' 37 | ], 38 | plugins: [ 39 | ['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }] 40 | ] 41 | } 42 | }, 43 | { 44 | test: /\.css$/, 45 | use: [ 46 | 'style-loader', 47 | MiniCssExtractPlugin.loader, 48 | 'css-loader' 49 | ] 50 | }, 51 | { 52 | test: /\.less$/, 53 | use: [{ 54 | loader: "style-loader" 55 | }, { 56 | loader: "css-loader" 57 | }, { 58 | loader: "less-loader", 59 | options: { 60 | javascriptEnabled: true 61 | } 62 | }] 63 | }, 64 | { 65 | test: /\.(jpg|png|svg)$/, 66 | use: { 67 | loader: "file-loader", 68 | options: { 69 | name: "[path][name].[hash].[ext]", 70 | }, 71 | }, 72 | }, 73 | ] 74 | }, 75 | 76 | plugins: [ 77 | new HtmlWebpackPlugin({ 78 | inject: true, 79 | template: path.join(paths.srcPath, 'index.html'), 80 | minify: { 81 | removeComments: true, 82 | collapseWhitespace: true, 83 | removeRedundantAttributes: true, 84 | useShortDoctype: true, 85 | removeEmptyAttributes: true, 86 | removeStyleLinkTypeAttributes: true, 87 | keepClosingSlash: true, 88 | minifyJS: true, 89 | minifyCSS: true, 90 | minifyURLs: true, 91 | }, 92 | }) 93 | ] 94 | } 95 | }; 96 | -------------------------------------------------------------------------------- /src/components/Pricing.js: -------------------------------------------------------------------------------- 1 | import {AGI} from '../util' 2 | 3 | export default class PricingStrategy { 4 | constructor(pricingJSON) { 5 | let pricingData = JSON.parse(pricingJSON); 6 | this.priceModel = pricingData.price_model; 7 | if(this.priceModel === 'fixed_price') { 8 | this.pricingModel = new FixedPricing(pricingData); 9 | } else if(this.priceModel === 'fixed_price_per_method') { 10 | this.pricingModel = new MethodPricing(pricingData); 11 | } else { 12 | console.log("Unsupported pricing model - " + pricingJSON); 13 | } 14 | } 15 | 16 | getPriceModel() { 17 | return this.priceModel; 18 | } 19 | 20 | getPriceInCogs(serviceName, methodName) { 21 | return this.pricingModel.getPriceInCogs(serviceName, methodName); 22 | } 23 | 24 | getPriceInAGI(serviceName, methodName) { 25 | return this.pricingModel.getPriceInAGI(serviceName, methodName); 26 | } 27 | 28 | getMaxPriceInCogs() { 29 | return this.pricingModel.getMaxPriceInCogs(); 30 | } 31 | } 32 | 33 | class FixedPricing { 34 | constructor(pricingData) { 35 | this.priceInCogs = pricingData.price_in_cogs; 36 | this.priceInAGI = AGI.inAGI(pricingData.price_in_cogs); 37 | } 38 | 39 | getPriceInCogs(serviceName, methodName) { 40 | return this.priceInCogs; 41 | } 42 | 43 | getPriceInAGI(serviceName, methodName) { 44 | return this.priceInAGI; 45 | } 46 | 47 | getMaxPriceInCogs() { 48 | return this.priceInCogs; 49 | } 50 | } 51 | 52 | class MethodPricing { 53 | constructor(pricingData) { 54 | this.maxPriceInCogs = 0; 55 | this.pricing = {}; 56 | 57 | pricingData.details.map((servicePrice, index) => { 58 | console.log("Method pricing " + servicePrice.service_name) 59 | this.pricing[servicePrice.service_name] = {}; 60 | servicePrice.method_pricing.map((methodPrice) => { 61 | if(methodPrice.price_in_cogs > this.maxPriceInCogs) { 62 | this.maxPriceInCogs = methodPrice.price_in_cogs; 63 | } 64 | this.pricing[servicePrice.service_name][methodPrice.method_name] = methodPrice.price_in_cogs; 65 | }); 66 | }); 67 | } 68 | 69 | getPriceInCogs(serviceName, methodName) { 70 | let methodPricing = this.pricing[serviceName]; 71 | return methodPricing[methodName]; 72 | } 73 | 74 | getPriceInAGI(serviceName, methodName) { 75 | let priceInCogs = this.getPriceInCogs(serviceName, methodName); 76 | return AGI.inAGI(priceInCogs); 77 | } 78 | 79 | getMaxPriceInCogs() { 80 | return this.maxPriceInCogs; 81 | } 82 | } -------------------------------------------------------------------------------- /src/components/service/gene-annotation-service/visualizer.config.js: -------------------------------------------------------------------------------- 1 | export const MAXIMUM_GRAPH_SIZE = 1500; 2 | 3 | export const CYTOSCAPE_COLA_CONFIG = { 4 | name: "cola", 5 | animate: true, 6 | maxSimulationTime: 3000, 7 | ungrabifyWhileSimulating: true, 8 | fit: true, 9 | padding: 10, 10 | randomize: true, 11 | avoidOverlap: true, 12 | handleDisconnected: true, 13 | nodeSpacing: 20, 14 | infinite: false 15 | }; 16 | 17 | export const CYTOSCAPE_STYLE = [ 18 | // Node styles 19 | { 20 | selector: "node", 21 | css: { 22 | shape: "round-rectangle", 23 | width: "mapData(id.length, 0, 20, 50, 300)", 24 | height: "40", 25 | content: "data(id)", 26 | color: "#fff", 27 | "text-wrap": "wrap", 28 | "text-max-width": "350px", 29 | "text-valign": "center", 30 | "text-halign": "center", 31 | "background-color": "#565656", 32 | "text-outline-color": "#565656", 33 | "text-outline-width": 1 34 | } 35 | }, 36 | { 37 | selector: 'node[group="biogrid_interaction_annotation"]', 38 | css: { 39 | shape: "ellipse", 40 | width: 75, 41 | height: 75 42 | } 43 | }, 44 | { 45 | selector: 'node[id^="Uni"]', 46 | css: { 47 | shape: "hexagon" 48 | } 49 | }, 50 | { 51 | selector: 'node[id^="ChEBI"]', 52 | css: { 53 | shape: "diamond", 54 | height: 75 55 | } 56 | }, 57 | { 58 | selector: "node:selected", 59 | css: { 60 | "border-width": 5, 61 | "border-color": "#AAD8FF", 62 | "border-opacity": 1 63 | } 64 | }, 65 | { 66 | selector: 'node[group="Gene"]', 67 | style: { 68 | shape: "ellipse", 69 | content: "data(id)", 70 | height: 75, 71 | color: "#fff", 72 | "text-outline-color": "#005bcd", 73 | "background-color": "#005bcd" 74 | } 75 | }, 76 | { 77 | selector: 'node[group="main"]', 78 | style: { 79 | shape: "ellipse", 80 | content: "data(id)", 81 | width: 75, 82 | height: 75, 83 | color: "#fff", 84 | "background-color": "#005bcd", 85 | "text-outline-color": "#005bcd" 86 | } 87 | }, 88 | // Edge styles 89 | { 90 | selector: "edge", 91 | css: { 92 | "curve-style": "haystack", 93 | "line-color": "#ccc", 94 | width: 4 95 | } 96 | }, 97 | { 98 | selector: "edge[group='gene_go_annotation']", 99 | css: { 100 | "curve-style": "straight", 101 | "target-arrow-shape": "triangle", 102 | "target-arrow-fill": "filled" 103 | } 104 | } 105 | ]; 106 | -------------------------------------------------------------------------------- /src/grpc.js: -------------------------------------------------------------------------------- 1 | const { ChunkParser, ChunkType } = require("grpc-web-client/dist/ChunkParser") 2 | 3 | async function processResponse(response, callback) { 4 | console.log(response); 5 | let error = null, chunk = null; 6 | 7 | if (response.ok) { 8 | var buffer = await response.arrayBuffer(); 9 | chunk = parseChunk(buffer); 10 | var grpcMessage = response.headers.get('Grpc-Message'); 11 | if (grpcMessage != null && chunk == null) { 12 | error = grpcMessage; 13 | } 14 | } 15 | else { 16 | let errorStatus = "Connection failed" 17 | if(typeof response.statusText !== 'undefined') { 18 | errorStatus = response.statusText; 19 | } 20 | error = "Request failed with error ["+errorStatus+"]. Please retry in some time." 21 | } 22 | 23 | try 24 | { 25 | callback(error, chunk && chunk.data ? new Uint8Array(chunk.data) : null); 26 | } 27 | catch(err) { 28 | console.log(err); 29 | callback(err); 30 | } 31 | } 32 | 33 | export function rpcImpl(host, packageName, serviceName, methodName, requestHeaders) { 34 | return (method, requestObject, callback) => { 35 | const service = [ packageName, serviceName ].filter(Boolean).join(".") 36 | window.fetch(`${host}/${service}/${methodName}`, { 37 | "method": "POST", 38 | "headers": Object.assign( 39 | {}, 40 | { 41 | "content-type": "application/grpc-web+proto", 42 | "x-grpc-web": "1" 43 | }, 44 | requestHeaders 45 | ), 46 | "body": frameRequest(requestObject) 47 | }) 48 | .then(response => {processResponse(response, callback)}).catch(err => callback(err)) 49 | } 50 | } 51 | 52 | function grpcJSONResponseToString(arrayBuffer) { 53 | const responseLength = new DataView(arrayBuffer).getUint8(4) 54 | const unframedResponse = new Uint8Array(arrayBuffer.slice(5, responseLength+5)) 55 | return String.fromCharCode(...unframedResponse) 56 | } 57 | 58 | function frameRequest(bytes) { 59 | const frame = new ArrayBuffer(bytes.byteLength + 5) 60 | new DataView(frame, 1, 4).setUint32(0, bytes.length, false) 61 | new Uint8Array(frame, 5).set(bytes) 62 | return new Uint8Array(frame) 63 | } 64 | 65 | function parseChunk(buffer) { 66 | return new ChunkParser() 67 | .parse(new Uint8Array(buffer)) 68 | .find(chunk => chunk.chunkType === ChunkType.MESSAGE) 69 | } 70 | 71 | export function grpcRequest(serviceObject, methodName, requestObject) { 72 | methodName = methodName.charAt(0).toLowerCase() + methodName.substr(1) 73 | if (!serviceObject[methodName]) throw new Error(`Service does not have method ${methodName}. ${serviceObject}`) 74 | 75 | return serviceObject[methodName](requestObject) 76 | } 77 | -------------------------------------------------------------------------------- /src/css/profile.css: -------------------------------------------------------------------------------- 1 | .ProfilegridWrapper { 2 | display: grid; 3 | height: 250px; 4 | width: 100%; 5 | grid-template-rows: 250px 1fr; 6 | grid-template-columns: 5% 40% 5% 40%; 7 | } 8 | 9 | .profilegridspacer { width:100%; } 10 | 11 | .wrapper { 12 | width: 75%; 13 | margin: 30px auto; 14 | } 15 | 16 | .amount-type { width: 100% !important; } 17 | .authorize-deposit-withdraw { padding-bottom: 32px; } 18 | 19 | .authorize-deposit-withdraw a { 20 | border-bottom: 2px solid #959595; 21 | padding: 0 10px 7px; 22 | margin-right: 35px; 23 | font-size: 15px; 24 | text-transform: uppercase; 25 | color: #959595; 26 | } 27 | 28 | .authorize-deposit-withdraw a:hover { 29 | border-bottom: 2px solid #0066ff; 30 | text-decoration: none; 31 | color: #0066ff; 32 | } 33 | 34 | .authorize-deposit-withdraw .active { 35 | border-bottom: 2px solid #0066ff; 36 | color: #0066ff; 37 | } 38 | 39 | 40 | .confirm-btn { 41 | float: right; 42 | color: #fff; 43 | background-color: #0066ff; 44 | border: 1px solid #0066ff; 45 | border-radius: 50px; 46 | padding: 7px 28px; 47 | margin-top: 10px; 48 | font-size: 14px; 49 | } 50 | 51 | .channel-header { 52 | padding: 15px 0; 53 | border-radius: 5px; 54 | font-size: 15px; 55 | font-weight: bold; 56 | border-top: 3px solid #0066ff; 57 | box-shadow: 1px 1px 10px #e0dbdb; 58 | } 59 | 60 | .channel-detail-block { 61 | margin: 25px 0; 62 | box-shadow: 1px 1px 11px 0px #bcd7ff; 63 | } 64 | 65 | .toggle-btn { 66 | float: right; 67 | border: none; 68 | background: none; 69 | } 70 | 71 | .channel-confirmation { 72 | display: none; 73 | background: #f1f1f1; 74 | text-align: right; 75 | } 76 | 77 | .show-confirmation { display: block; } 78 | 79 | .channel-confirmation div { 80 | padding-top: 10px; 81 | padding-bottom: 10px; 82 | } 83 | 84 | .channel-confirmation div input { 85 | border: none; 86 | padding: 7px 0; 87 | margin-right: 10px; 88 | } 89 | 90 | .channel-confirmation button { 91 | margin-top: 0; 92 | float: none; 93 | } 94 | 95 | /* width */ 96 | .channel-info::-webkit-scrollbar { 97 | width: 8px; 98 | background-color: #c3c3c3; 99 | } 100 | 101 | /* Track */ 102 | .channel-info::-webkit-scrollbar-track { 103 | box-shadow: inset 0 0 5px grey; 104 | border-radius: 10px; 105 | } 106 | 107 | /* Handle */ 108 | .channel-info::-webkit-scrollbar-thumb { 109 | background: #676767; 110 | border-radius: 10px; 111 | } 112 | 113 | .MuiCardContent-root-29 { padding-top:0px !important; } 114 | 115 | .MuiTab-root-81 { 116 | min-height:30px !important; 117 | font-size:13px !important; 118 | } 119 | 120 | .MuiTabs-root-72 { min-height:34px !important; } 121 | .MuiInputLabel-shrink-110 { transform: translate(0, 1.5px) scale(1) !important; } -------------------------------------------------------------------------------- /src/components/service/NewsSummaryService.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default class NewSummaryService extends React.Component { 4 | 5 | constructor(props) { 6 | super(props); 7 | this.submitAction = this.submitAction.bind(this); 8 | this.handleFormUpdate = this.handleFormUpdate.bind(this); 9 | 10 | this.state = { 11 | serviceName: "TextSummary", 12 | methodName: "summary", 13 | article_content: 'Analysts are predicting record highs as a global shortage of teddy bears sweeps the nation. "The market these products is way up". The advice is to stay indoors as society collapses under the demand.' 14 | }; 15 | } 16 | 17 | canBeInvoked() { 18 | return (this.state.text !== ""); 19 | } 20 | 21 | handleFormUpdate(event) { 22 | this.setState({ 23 | [event.target.name]: event.target.value 24 | }); 25 | } 26 | 27 | submitAction() { 28 | this.props.callApiCallback(this.state.serviceName, 29 | this.state.methodName, { 30 | article_content: this.state.article_content 31 | }); 32 | } 33 | 34 | renderForm() { 35 | return ( 36 | 37 |
38 |
News text to summarise:
39 |
40 | 105 |
106 | 107 |
108 | 109 |
110 |
111 | 112 |
113 |
114 | 115 |
116 |
About
117 |
118 | 119 |
120 |
121 | 122 |
123 | ) 124 | } 125 | 126 | renderComplete() { 127 | return ( 128 |
129 |
130 |
131 | ); 132 | } 133 | 134 | componentDidUpdate() { 135 | if (this.isComplete) { 136 | var data = new Uint8Array(this.state.response); 137 | var blob = new Blob([data], {type : 'audio/wav'}); 138 | var ac = document.getElementById("audio-container"); 139 | ac.innerHTML = ""; 140 | var audio = document.createElement('audio'); 141 | audio.setAttribute('controls', ''); 142 | 143 | var audioURL = window.URL.createObjectURL(blob); 144 | audio.src = audioURL; 145 | audio.style.width = "100%"; 146 | ac.appendChild(audio); 147 | } 148 | } 149 | 150 | render() { 151 | if (this.isComplete) 152 | return ( 153 |
154 | {this.renderComplete()} 155 |
156 | ); 157 | else { 158 | return ( 159 |
160 | {this.renderForm()} 161 |
162 | ) 163 | } 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/sandbox/Standalone.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ServiceMappings from "../components/service/ServiceMappings.js" 3 | import PropTypes from 'prop-types' 4 | import GRPCProtoV3Spec from "../models/GRPCProtoV3Spec"; 5 | import TextField from '@material-ui/core/TextField'; 6 | import { JobdetailsStandalone } from './JobDetailsStandalone.js'; 7 | import BlockchainHelper from "../components/BlockchainHelper.js" 8 | 9 | class Standalone extends React.Component { 10 | constructor(props) { 11 | super(props); 12 | this.state = { 13 | orgID:'snet', 14 | serviceID:'example-service', 15 | proto:'syntax = "proto3"; package example_service; message Numbers { float a = 1; float b = 2; } message Result { float value = 1; } service Calculator { rpc add(Numbers) returns (Result) {} rpc sub(Numbers) returns (Result) {} rpc mul(Numbers) returns (Result) {} rpc div(Numbers) returns (Result) {} }', 16 | endpoint:'http://localhost:7052', 17 | errorMessage:'', 18 | userAddress:undefined 19 | }; 20 | 21 | this.network = new BlockchainHelper(); 22 | this.serviceSpecJSON = ''; 23 | this.serviceMappings = new ServiceMappings(); 24 | 25 | this.handleField = this.handleField.bind(this); 26 | this.onOpenJobDetailsSlider = this.onOpenJobDetailsSlider.bind(this); 27 | this.fetchWeb3Account = this.fetchWeb3Account.bind(this); 28 | } 29 | 30 | componentDidMount() { 31 | window.addEventListener('load', () => this.handleWindowLoad()); 32 | this.handleWindowLoad(); 33 | this.fetchWeb3Account(); 34 | } 35 | 36 | handleWindowLoad() { 37 | this.network.initialize(); 38 | } 39 | 40 | handleField(e) { 41 | this.setState({errorMessage: ''}) 42 | const { name, value } = e.target; 43 | this.setState({[name]: value,}) 44 | } 45 | 46 | runJob() { 47 | this.errorMessage = '' 48 | this.generate_service_spec_json(this.proto); 49 | } 50 | 51 | generate_service_spec_json() { 52 | try { 53 | const protobuf = require("protobufjs"); 54 | protobuf.parse.defaults.keepCase = true; 55 | let obj = protobuf.parse(this.state.proto) 56 | this.serviceSpecJSON = obj.root; 57 | this.protoSpec = new GRPCProtoV3Spec(this.serviceSpecJSON); 58 | this.onOpenJobDetailsSlider(); 59 | } 60 | catch(ex) { 61 | this.setState({errorMessage: "Exception while parsing proto [" + ex + "]"}); 62 | console.log("Unable to generate service spec json. Please ensure that " + this.proto + " is a valid proto file") 63 | console.log(ex) 64 | } 65 | } 66 | 67 | onOpenJobDetailsSlider() { 68 | let serviceState = {} 69 | serviceState["org_id"] = this.state.orgID; 70 | serviceState["service_id"] = this.state.serviceID; 71 | serviceState["is_available"] = 1; 72 | serviceState["serviceSpecJSON"] = this.serviceSpecJSON 73 | serviceState["endpoint"] =this.state.endpoint 74 | serviceState["protoSpec"] = this.protoSpec 75 | 76 | this.refs.jobdetailsComp.onOpenJobDetails(serviceState); 77 | } 78 | 79 | async fetchWeb3Account(){ 80 | const getAccountDetails = await web3.eth.getAccounts; 81 | getAccountDetails((e,accounts)=>{ 82 | this.setState({userAddress:accounts[0]}); 83 | }) 84 | } 85 | 86 | renderBase() { 87 | return( 88 | 89 |
90 |
91 |
92 | Org ID (Used to look up servicemappings) 93 |
94 |
95 | 96 |
97 |
98 | 99 |
100 |
101 | Service ID (Used to look up servicemappings) 102 |
103 |
104 | 105 |
106 |
107 | 108 |
109 |
110 | Proto Contents 111 |
112 |
113 | 114 |
115 |
116 | 117 |
118 |
119 | Endpoint of daemon with blockchain disabled 120 |
121 |
122 | 123 |
124 |
125 | 126 |
127 | 128 |
129 | {(this.state.errorMessage === '') ? 130 | null : 131 |
132 | {this.state.errorMessage} 133 |
134 | } 135 |
136 | 137 | {}}/> 142 |
143 | ) 144 | } 145 | 146 | render() { 147 | return ( 148 |
149 | {this.renderBase()} 150 |
151 | ) 152 | } 153 | } 154 | 155 | Standalone.propTypes = { 156 | account: PropTypes.string 157 | }; 158 | export default Standalone; -------------------------------------------------------------------------------- /src/components/service/BinarySemanticSimilarity.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {hasOwnDefinedProperty} from '../../util' 3 | import Button from '@material-ui/core/Button'; 4 | 5 | export default class BinarySemanticSimilarity extends React.Component { 6 | 7 | constructor(props) { 8 | super(props); 9 | this.submitAction = this.submitAction.bind(this); 10 | this.handleFormUpdate = this.handleFormUpdate.bind(this); 11 | 12 | this.users_guide = "https://github.com/iktina/semantic-similarity-binary-service"; 13 | this.serviceName = "SSBERT"; 14 | this.methodName = "ss_bert"; 15 | 16 | this.state = { 17 | response: undefined, 18 | a: "", 19 | b: "" 20 | }; 21 | 22 | this.isComplete = false; 23 | this.serviceMethods = []; 24 | this.allServices = []; 25 | this.methodsForAllServices = []; 26 | this.parseProps(props); 27 | } 28 | 29 | componentWillReceiveProps(nextProps) { 30 | if(this.isComplete !== nextProps.isComplete) { 31 | this.parseProps(nextProps); 32 | } 33 | } 34 | 35 | parseProps(nextProps) { 36 | this.isComplete = nextProps.isComplete; 37 | if (!this.isComplete) { 38 | this.parseServiceSpec(nextProps.serviceSpec); 39 | } else { 40 | if (typeof nextProps.response !== 'undefined') { 41 | if (typeof nextProps.response === 'string') { 42 | this.state.response = nextProps.response; 43 | } else { 44 | this.state.response = nextProps.response.answer; 45 | } 46 | } 47 | } 48 | } 49 | 50 | parseServiceSpec(serviceSpec) { 51 | const packageName = Object.keys(serviceSpec.nested).find(key => 52 | typeof serviceSpec.nested[key] === "object" && 53 | hasOwnDefinedProperty(serviceSpec.nested[key], "nested")); 54 | 55 | var objects = undefined; 56 | var items = undefined; 57 | if (typeof packageName !== 'undefined') { 58 | items = serviceSpec.lookup(packageName); 59 | objects = Object.keys(items); 60 | } else { 61 | items = serviceSpec.nested; 62 | objects = Object.keys(serviceSpec.nested); 63 | } 64 | 65 | this.allServices.push("Select a service"); 66 | this.methodsForAllServices = []; 67 | objects.map(rr => { 68 | if (typeof items[rr] === 'object' && items[rr] !== null && items[rr].hasOwnProperty("methods")) { 69 | this.allServices.push(rr); 70 | this.methodsForAllServices.push(rr); 71 | 72 | var methods = Object.keys(items[rr]["methods"]); 73 | methods.unshift("Select a method"); 74 | this.methodsForAllServices[rr] = methods; 75 | } 76 | }) 77 | } 78 | 79 | handleFormUpdate(event) { 80 | this.setState({ 81 | [event.target.name]: event.target.value 82 | }); 83 | } 84 | 85 | onKeyPressvalidator(event) { 86 | // console.log(event.target.value); 87 | } 88 | 89 | submitAction() { 90 | var btn = document.getElementById("invoke-button"); 91 | btn.disabled = true; 92 | btn.innerHTML = "Wait..."; 93 | 94 | this.props.callApiCallback(this.serviceName, 95 | this.methodName, { 96 | a: this.state.a, 97 | b: this.state.b 98 | }); 99 | } 100 | 101 | renderForm() { 102 | return ( 103 | 104 |
105 |
Sentence 1
106 |
107 | 109 |
110 | 111 |
112 |
113 |
Sentence 2
114 |
115 | 117 |
118 |
119 |
120 |
121 | 122 |
123 |
124 | 125 |
126 |
About
127 |
128 | 129 |
130 |
131 | 132 |
133 | ) 134 | } 135 | 136 | renderComplete() { 137 | return ( 138 |
139 |

Response from service is This sentences is {this.state.response === "1" ? "similar" : "distinct"}

140 |
141 | ); 142 | } 143 | 144 | render() { 145 | if (this.isComplete) 146 | return ( 147 |
148 | {this.renderComplete()} 149 |
150 | ); 151 | else { 152 | return ( 153 |
154 | {this.renderForm()} 155 |
156 | ) 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/components/ChannelHelper.js: -------------------------------------------------------------------------------- 1 | import { base64ToHex } from '../util' 2 | import { Requests } from '../requests' 3 | 4 | export default class ChannelHelper { 5 | constructor() { 6 | this.channels = undefined; 7 | this.groupId = undefined; 8 | this.endpoint = undefined; 9 | this.channelId = undefined; 10 | this.recipient = undefined; 11 | this.currentSignedAmount = 0; 12 | } 13 | 14 | reInitialize(channelInfoUrl) { 15 | this.channels = undefined; 16 | this.groupId = undefined; 17 | this.endpoint = undefined; 18 | this.channelId = undefined; 19 | this.recipient = undefined; 20 | this.currentSignedAmount = 0; 21 | return this.fetchChannels(channelInfoUrl); 22 | } 23 | 24 | setCurrentSignedAmount(amount) { 25 | this.currentSignedAmount = amount; 26 | } 27 | 28 | getCurrentSignedAmount() { 29 | return this.currentSignedAmount; 30 | } 31 | 32 | getChannelId() { 33 | return this.channelId; 34 | } 35 | 36 | setChannelId(channelId) { 37 | return this.channelId = channelId; 38 | } 39 | 40 | getGroupId() { 41 | return this.groupId; 42 | } 43 | 44 | getEndpoint() { 45 | if(typeof this.endpoint === 'undefined') { 46 | return undefined 47 | } 48 | return this.endpoint[0]; 49 | } 50 | 51 | getChannel(channelId) { 52 | let channels = this.getChannels(); 53 | for(let ii=0; ii < channels.length; ii++) { 54 | if (channels[ii]["channelId"] === channelId) 55 | { 56 | return channels[ii]; 57 | } 58 | } 59 | return undefined; 60 | } 61 | 62 | getExpiryBlock() { 63 | let channels = this.getChannels(); 64 | let expiryBlock = 0; 65 | for(let ii=0; ii < channels.length; ii++) { 66 | var rrchannels = channels[ii]; 67 | if (rrchannels["channelId"] === this.channelId) 68 | { 69 | expiryBlock = rrchannels["expiration"]; 70 | break; 71 | } 72 | } 73 | return expiryBlock; 74 | } 75 | 76 | getRecipient() { 77 | return this.recipient; 78 | } 79 | 80 | setNonce(newNonce) { 81 | let channels = this.getChannels(); 82 | for(let ii=0; ii < channels.length; ii++) { 83 | var rrchannels = channels[ii]; 84 | if (rrchannels["channelId"] === this.channelId) 85 | { 86 | rrchannels["nonce"] = newNonce; 87 | console.log("Setting nonce for channel " + this.channelId + " to " + rrchannels["nonce"]); 88 | break; 89 | } 90 | } 91 | } 92 | 93 | getNonce(defaultValue) { 94 | let nonce = defaultValue; 95 | let channels = this.getChannels(); 96 | for(let ii=0; ii < channels.length; ii++) { 97 | var rrchannels = channels[ii]; 98 | if (rrchannels["channelId"] === this.channelId) 99 | { 100 | nonce = rrchannels["nonce"]; 101 | break; 102 | } 103 | } 104 | return nonce; 105 | } 106 | 107 | getChannels() { 108 | let channels = this.channels; 109 | if (typeof channels === 'undefined'){ 110 | channels = []; 111 | } 112 | return channels 113 | } 114 | 115 | fetchChannels(channelInfoUrl) { 116 | var caller = this; 117 | Requests.get(channelInfoUrl).then(channeldata => 118 | new Promise(function(resolve) { 119 | caller.populateChannelDetails(channeldata["data"]); 120 | resolve(); 121 | })); 122 | } 123 | 124 | populateChannelDetails(channels) { 125 | if(typeof channels === 'undefined' || channels.length === 0) { 126 | console.log("Unable to get channel information"); 127 | return; 128 | } 129 | 130 | this.channels = channels[0]["channels"]; 131 | this.endpoint = channels[0]["endpoint"] 132 | this.groupId = channels[0]["groupId"]; 133 | this.recipient = channels[0]["recipient"]; 134 | console.log("Populated channels"); 135 | } 136 | 137 | matchEvent(evt, result, senderAddress, groupidgetter, recipientaddress) { 138 | console.log("result from event: " + result); 139 | var event = result.event; 140 | console.log("event: " + event); 141 | var agentGroupID = base64ToHex(groupidgetter); 142 | if (event == "ChannelOpen") { 143 | var MPEChannelId = result.args.channelId; 144 | var channelSender = result.args.sender; 145 | var channelRecipient = result.args.recipient; 146 | var channelGoupId = result.args.groupId; 147 | 148 | console.log("Channel details - [" + channelGoupId + "] [" + channelRecipient + "] [" + channelSender + "]"); 149 | console.log("App details - [" + agentGroupID + "] [" + recipientaddress + "] [" + senderAddress + "]"); 150 | if (channelGoupId === agentGroupID && channelSender.toLowerCase() === senderAddress.toLowerCase() && recipientaddress.toLowerCase() === channelRecipient.toLowerCase()) { 151 | console.log("Matched channel id " + MPEChannelId) 152 | this.channelId = MPEChannelId; 153 | evt.stopWatching(); 154 | } 155 | console.log("channel id" + this.channelId); 156 | } 157 | } 158 | 159 | findExistingChannel(data, thresholdBlockNumber) { 160 | if (typeof this.channels !== 'undefined') 161 | { 162 | console.log('channel state information is ' + this.groupId); 163 | if (this.channels.length > 0) 164 | { 165 | let lowestChannelID = this.channels[0]["channelId"]; 166 | for(let ii=0; ii < this.channels.length; ii++) { 167 | var rrchannels = this.channels[ii]; 168 | if(rrchannels["channelId"] < lowestChannelID){ 169 | lowestChannelID = rrchannels["channelId"]; 170 | } 171 | if (parseInt(rrchannels["balance_in_cogs"]) >= parseInt(data.pricing_strategy.getMaxPriceInCogs()) 172 | && parseInt(rrchannels["expiration"]) >= parseInt(thresholdBlockNumber)) 173 | { 174 | console.log("Found a channel with adequate funds " + JSON.stringify(rrchannels)); 175 | console.log("Setting channel ID to " + rrchannels["channelId"]); 176 | this.channelId = rrchannels["channelId"]; 177 | return true; 178 | } 179 | } 180 | 181 | console.log("No channel is found with adequate funds and expiration"); 182 | console.log("Choosing channel with lowest id"); 183 | this.channelId = lowestChannelID; 184 | return true; 185 | } 186 | } 187 | console.log("Did not find a channel with adequate funds"); 188 | return false; 189 | } 190 | } -------------------------------------------------------------------------------- /src/components/service/LongQuestionAsnswering.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {hasOwnDefinedProperty} from '../../util' 3 | import Button from '@material-ui/core/Button'; 4 | 5 | export default class LongQuestionAsnswering extends React.Component { 6 | 7 | constructor(props) { 8 | super(props); 9 | this.submitAction = this.submitAction.bind(this); 10 | this.handleFormUpdate = this.handleFormUpdate.bind(this); 11 | 12 | this.users_guide = "https://github.com/iktina/question-answering-long-seq-service"; 13 | this.serviceName = "QA"; 14 | this.methodName = "qa"; 15 | 16 | this.state = { 17 | response: undefined, 18 | context: "", 19 | question: "" 20 | }; 21 | 22 | this.isComplete = false; 23 | this.serviceMethods = []; 24 | this.allServices = []; 25 | this.methodsForAllServices = []; 26 | this.parseProps(props); 27 | } 28 | componentWillReceiveProps(nextProps) { 29 | if(this.isComplete !== nextProps.isComplete) { 30 | this.parseProps(nextProps); 31 | } 32 | } 33 | parseProps(nextProps) { 34 | this.isComplete = nextProps.isComplete; 35 | if (!this.isComplete) { 36 | this.parseServiceSpec(nextProps.serviceSpec); 37 | } else { 38 | if (typeof nextProps.response !== 'undefined') { 39 | if (typeof nextProps.response === 'string') { 40 | this.state.response = nextProps.response; 41 | } else { 42 | this.state.response = nextProps.response.answer; 43 | } 44 | } 45 | } 46 | } 47 | 48 | parseServiceSpec(serviceSpec) { 49 | const packageName = Object.keys(serviceSpec.nested).find(key => 50 | typeof serviceSpec.nested[key] === "object" && 51 | hasOwnDefinedProperty(serviceSpec.nested[key], "nested")); 52 | 53 | var objects = undefined; 54 | var items = undefined; 55 | if (typeof packageName !== 'undefined') { 56 | items = serviceSpec.lookup(packageName); 57 | objects = Object.keys(items); 58 | } else { 59 | items = serviceSpec.nested; 60 | objects = Object.keys(serviceSpec.nested); 61 | } 62 | 63 | this.allServices.push("Select a service"); 64 | this.methodsForAllServices = []; 65 | objects.map(rr => { 66 | if (typeof items[rr] === 'object' && items[rr] !== null && items[rr].hasOwnProperty("methods")) { 67 | this.allServices.push(rr); 68 | this.methodsForAllServices.push(rr); 69 | 70 | var methods = Object.keys(items[rr]["methods"]); 71 | methods.unshift("Select a method"); 72 | this.methodsForAllServices[rr] = methods; 73 | } 74 | }) 75 | } 76 | 77 | handleFormUpdate(event) { 78 | this.setState({ 79 | [event.target.name]: event.target.value 80 | }); 81 | } 82 | 83 | onKeyPressvalidator(event) { 84 | // console.log(event.target.value); 85 | } 86 | 87 | submitAction() { 88 | var btn = document.getElementById("invoke-button"); 89 | btn.disabled = true; 90 | btn.innerHTML = "Wait..."; 91 | 92 | this.props.callApiCallback(this.serviceName, 93 | this.methodName, { 94 | context: this.state.context, 95 | question: this.state.question 96 | }); 97 | } 98 | 99 | renderForm() { 100 | return ( 101 | 102 |
103 |
Context
104 |
105 | 107 |
108 | 109 |
110 |
111 |
Question
112 |
113 | 115 |
116 |
117 |
118 |
119 | 120 |
121 |
122 | 123 |
124 |
About
125 |
126 | 127 |
128 |
129 | 130 |
131 | ) 132 | } 133 | 134 | renderComplete() { 135 | return ( 136 |
137 |

Response from service is: {this.state.response}

138 |
139 | ); 140 | } 141 | 142 | render() { 143 | if (this.isComplete) 144 | return ( 145 |
146 | {this.renderComplete()} 147 |
148 | ); 149 | else { 150 | return ( 151 |
152 | {this.renderForm()} 153 |
154 | ) 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/components/service/ShortQuestionAnswering.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {hasOwnDefinedProperty} from '../../util' 3 | import Button from '@material-ui/core/Button'; 4 | 5 | export default class ShortQuestionAnswering extends React.Component { 6 | 7 | constructor(props) { 8 | super(props); 9 | this.submitAction = this.submitAction.bind(this); 10 | this.handleFormUpdate = this.handleFormUpdate.bind(this); 11 | 12 | this.users_guide = "https://github.com/iktina/question-answering-short-seq-service"; 13 | this.serviceName = "QABERT"; 14 | this.methodName = "qa_bert"; 15 | 16 | this.state = { 17 | response: undefined, 18 | context: "", 19 | question: "" 20 | }; 21 | 22 | this.isComplete = false; 23 | this.serviceMethods = []; 24 | this.allServices = []; 25 | this.methodsForAllServices = []; 26 | this.parseProps(props); 27 | } 28 | componentWillReceiveProps(nextProps) { 29 | if(this.isComplete !== nextProps.isComplete) { 30 | this.parseProps(nextProps); 31 | } 32 | } 33 | parseProps(nextProps) { 34 | this.isComplete = nextProps.isComplete; 35 | if (!this.isComplete) { 36 | this.parseServiceSpec(nextProps.serviceSpec); 37 | } else { 38 | if (typeof nextProps.response !== 'undefined') { 39 | if (typeof nextProps.response === 'string') { 40 | this.state.response = nextProps.response; 41 | } else { 42 | this.state.response = nextProps.response.answer; 43 | } 44 | } 45 | } 46 | } 47 | 48 | parseServiceSpec(serviceSpec) { 49 | const packageName = Object.keys(serviceSpec.nested).find(key => 50 | typeof serviceSpec.nested[key] === "object" && 51 | hasOwnDefinedProperty(serviceSpec.nested[key], "nested")); 52 | 53 | var objects = undefined; 54 | var items = undefined; 55 | if (typeof packageName !== 'undefined') { 56 | items = serviceSpec.lookup(packageName); 57 | objects = Object.keys(items); 58 | } else { 59 | items = serviceSpec.nested; 60 | objects = Object.keys(serviceSpec.nested); 61 | } 62 | 63 | this.allServices.push("Select a service"); 64 | this.methodsForAllServices = []; 65 | objects.map(rr => { 66 | if (typeof items[rr] === 'object' && items[rr] !== null && items[rr].hasOwnProperty("methods")) { 67 | this.allServices.push(rr); 68 | this.methodsForAllServices.push(rr); 69 | 70 | var methods = Object.keys(items[rr]["methods"]); 71 | methods.unshift("Select a method"); 72 | this.methodsForAllServices[rr] = methods; 73 | } 74 | }) 75 | } 76 | 77 | handleFormUpdate(event) { 78 | this.setState({ 79 | [event.target.name]: event.target.value 80 | }); 81 | } 82 | 83 | onKeyPressvalidator(event) { 84 | // console.log(event.target.value); 85 | } 86 | 87 | submitAction() { 88 | var btn = document.getElementById("invoke-button"); 89 | btn.disabled = true; 90 | btn.innerHTML = "Wait..."; 91 | 92 | this.props.callApiCallback(this.serviceName, 93 | this.methodName, { 94 | context: this.state.context, 95 | question: this.state.question 96 | }); 97 | } 98 | 99 | renderForm() { 100 | return ( 101 | 102 |
103 |
Context
104 |
105 | 107 |
108 | 109 |
110 |
111 |
Question
112 |
113 | 115 |
116 |
117 |
118 |
119 | 120 |
121 |
122 | 123 |
124 |
About
125 |
126 | 127 |
128 |
129 | 130 |
131 | ) 132 | } 133 | 134 | renderComplete() { 135 | return ( 136 |
137 |

Response from service is: {this.state.response}

138 |
139 | ); 140 | } 141 | 142 | render() { 143 | if (this.isComplete) 144 | return ( 145 |
146 | {this.renderComplete()} 147 |
148 | ); 149 | else { 150 | return ( 151 |
152 | {this.renderForm()} 153 |
154 | ) 155 | } 156 | } 157 | } 158 | --------------------------------------------------------------------------------