1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00

Merge pull request #48 from oceanprotocol/feature/remote-config

add remote config for Nile
This commit is contained in:
Matthias Kretschmann 2019-04-02 17:16:12 +02:00 committed by GitHub
commit 876ee28203
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 236 additions and 139 deletions

View File

@ -9,8 +9,8 @@
[![js oceanprotocol](https://img.shields.io/badge/js-oceanprotocol-7b1173.svg)](https://github.com/oceanprotocol/eslint-config-oceanprotocol) [![js oceanprotocol](https://img.shields.io/badge/js-oceanprotocol-7b1173.svg)](https://github.com/oceanprotocol/eslint-config-oceanprotocol)
[![css bigchaindb](https://img.shields.io/badge/css-bigchaindb-39BA91.svg)](https://github.com/bigchaindb/stylelint-config-bigchaindb) [![css bigchaindb](https://img.shields.io/badge/css-bigchaindb-39BA91.svg)](https://github.com/bigchaindb/stylelint-config-bigchaindb)
- [Prerequisites](#prerequisites)
- [Get Started](#get-started) - [Get Started](#get-started)
- [Use with Barge](#use-with-barge)
- [Production](#production) - [Production](#production)
- [Testing](#testing) - [Testing](#testing)
- [Code Style](#code-style) - [Code Style](#code-style)
@ -18,23 +18,10 @@
<img alt="screen shot 2019-02-08 at 16 53 57" src="https://user-images.githubusercontent.com/90316/52489283-27080e80-2bc2-11e9-8ec0-508c21eb86f7.png"> <img alt="screen shot 2019-02-08 at 16 53 57" src="https://user-images.githubusercontent.com/90316/52489283-27080e80-2bc2-11e9-8ec0-508c21eb86f7.png">
## Prerequisites
To make use of all the functionality, you need to connect to the Ocean network.
For local development, you can spin up [`barge`](https://github.com/oceanprotocol/barge) to use a local network:
```bash
git clone git@github.com:oceanprotocol/barge.git
cd barge
./start_ocean.sh --latest --no-pleuston --local-spree-node
```
The default configuration of the client & server is to connect to this local network. Modify `./client/src/config.ts`, and `./server/src/config/config.ts` to change that.
## Get Started ## Get Started
To make use of all the functionality, you need to connect to the Ocean network. By default, the client will connect to Ocean's Nile test network remotely.
To spin up both, the client and the server in a watch mode for local development, execute: To spin up both, the client and the server in a watch mode for local development, execute:
```bash ```bash
@ -47,6 +34,19 @@ Open [http://localhost:3000](http://localhost:3000) to view the client in the br
The page will reload if you make edits to files in either `./client` or `./server`. The page will reload if you make edits to files in either `./client` or `./server`.
### Use with Barge
If you prefer to connect to locally running components instead of remote connections to Ocean's Nile network, you can spin up [`barge`](https://github.com/oceanprotocol/barge) and use a local network:
```bash
git clone git@github.com:oceanprotocol/barge.git
cd barge
./start_ocean.sh --latest --no-pleuston --local-spree-node
```
Modify `./client/src/config.ts` to use those local connections.
## Production ## Production
To create a production build of both, the client and the server: To create a production build of both, the client and the server:

View File

@ -1026,25 +1026,16 @@
"integrity": "sha512-p2n505t2K0zD1ZvGPhI6EsSviEVLCB7BYowhf/ONmVaWED138PaG4Z9nY6YuHU383uOoIWT+Lq3dLkFzDzstXw==" "integrity": "sha512-p2n505t2K0zD1ZvGPhI6EsSviEVLCB7BYowhf/ONmVaWED138PaG4Z9nY6YuHU383uOoIWT+Lq3dLkFzDzstXw=="
}, },
"@oceanprotocol/keeper-contracts": { "@oceanprotocol/keeper-contracts": {
"version": "0.8.9", "version": "0.9.0",
"resolved": "https://registry.npmjs.org/@oceanprotocol/keeper-contracts/-/keeper-contracts-0.8.9.tgz", "resolved": "https://registry.npmjs.org/@oceanprotocol/keeper-contracts/-/keeper-contracts-0.9.0.tgz",
"integrity": "sha512-qzeBOyaWs6GbTQgbUBVoRm4/eUy4Cp8XoJW7DfsV63ee6n/bF1KS9+0ZsuhfG3dNf+TqF5/G1FqVOGeU9yV59A==" "integrity": "sha512-QrTCQNiQa9KszH6/dTAS0a8AoW/SIEkZazXTwA2aoePBS0X8fNpsKvT3N2OuR1YPAjCU3rGWzYdV4TNnMNbsSw=="
},
"@oceanprotocol/secret-store-client": {
"version": "0.0.14",
"resolved": "https://registry.npmjs.org/@oceanprotocol/secret-store-client/-/secret-store-client-0.0.14.tgz",
"integrity": "sha512-Yo2/9MJC1vlWXGIaU+35naYHWWYGbtzTu2t5dW4Ro1JuIRkzxfM3TSNzPUAgsCrUBUxsCsu9pd/RjvPuE45SGw==",
"requires": {
"node-fetch": "^2.3.0"
}
}, },
"@oceanprotocol/squid": { "@oceanprotocol/squid": {
"version": "0.4.1", "version": "0.5.0",
"resolved": "https://registry.npmjs.org/@oceanprotocol/squid/-/squid-0.4.1.tgz", "resolved": "https://registry.npmjs.org/@oceanprotocol/squid/-/squid-0.5.0.tgz",
"integrity": "sha512-9pbBgiQv3yJkZvRNEitcGOX/nB412webuF4GCN82Uh8rb4fN3bQhkBWBsO6qgpa8DzSNwWhsmt5ScH/HuxK8FA==", "integrity": "sha512-yGu121WJ9XEX1U4ql/p7ISV36fqNydxGBYgXHbOjeXS/kvNFx3hP2emBf4QA12PjPZcmuLz0wE+7GBL4H/v+eA==",
"requires": { "requires": {
"@oceanprotocol/keeper-contracts": "^0.8.5", "@oceanprotocol/keeper-contracts": "^0.9.0",
"@oceanprotocol/secret-store-client": "~0.0.14",
"bignumber.js": "^8.0.1", "bignumber.js": "^8.0.1",
"deprecated-decorator": "^0.1.6", "deprecated-decorator": "^0.1.6",
"ethereumjs-util": "^6.0.0", "ethereumjs-util": "^6.0.0",

View File

@ -11,7 +11,7 @@
}, },
"dependencies": { "dependencies": {
"@oceanprotocol/art": "^2.2.0", "@oceanprotocol/art": "^2.2.0",
"@oceanprotocol/squid": "^0.4.1", "@oceanprotocol/squid": "^0.5.0",
"@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/typographies": "^0.1.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"filesize": "^4.1.2", "filesize": "^4.1.2",

View File

@ -3,10 +3,14 @@
.form { .form {
width: 100%; width: 100%;
background: $brand-white; background: $brand-white;
padding: $spacer; padding: $spacer / 1.5;
border: 1px solid $brand-grey-lighter; border: 1px solid $brand-grey-lighter;
border-radius: $border-radius; border-radius: $border-radius;
@media (min-width: $break-point--small) {
padding: $spacer;
}
fieldset { fieldset {
border: 0; border: 0;
padding: 0; padding: 0;

View File

@ -20,12 +20,14 @@ const AssetLink = ({ asset, list }: { asset: any; list?: boolean }) => {
) : ( ) : (
<article className={styles.asset}> <article className={styles.asset}>
<Link to={`/asset/${asset.id}`}> <Link to={`/asset/${asset.id}`}>
<CategoryImage category={base.categories[0][0]} /> {base.categories && (
<CategoryImage category={base.categories[0]} />
)}
<h1>{base.name}</h1> <h1>{base.name}</h1>
<p>{base.description.substring(0, 90)}...</p> <p>{base.description.substring(0, 90)}...</p>
<footer className={styles.assetFooter}> <footer className={styles.assetFooter}>
{base.categories && <div>{base.categories[0][0]}</div>} {base.categories && <div>{base.categories[0]}</div>}
</footer> </footer>
</Link> </Link>
</article> </article>

View File

@ -41,9 +41,9 @@ export default class AssetsUser extends PureComponent<
} }
} }
) )
} else {
this.setState({ isLoading: false })
} }
this.setState({ isLoading: false })
} }
public render() { public render() {

View File

@ -3,13 +3,27 @@
.header { .header {
margin-top: $spacer; margin-top: $spacer;
margin-bottom: $spacer; margin-bottom: $spacer;
}
h1 { .title {
margin: 0; margin: 0;
} font-size: $font-size-h2;
p { @media (min-width: $break-point--small) {
margin-top: $spacer / 2; font-size: $font-size-h1;
font-size: $font-size-large; }
}
.description {
margin-top: $spacer / 2;
font-size: $font-size-large;
}
.titleReverse {
composes: title;
color: $brand-grey-light;
span {
color: $brand-grey-dark;
} }
} }

View File

@ -7,12 +7,14 @@ import meta from '../../data/meta.json'
const Route = ({ const Route = ({
title, title,
description, description,
titleReverse,
wide, wide,
children, children,
className className
}: { }: {
title: string title: string
description?: string description?: string
titleReverse?: boolean
children: any children: any
wide?: boolean wide?: boolean
className?: string className?: string
@ -26,8 +28,22 @@ const Route = ({
<Content wide={wide}> <Content wide={wide}>
<article> <article>
<header className={styles.header}> <header className={styles.header}>
<h1>{title}</h1> <h1
{description && <p>{description}</p>} className={
titleReverse ? styles.titleReverse : styles.title
}
dangerouslySetInnerHTML={{
__html: title
}}
/>
{description && (
<p
className={styles.description}
dangerouslySetInnerHTML={{
__html: description
}}
/>
)}
</header> </header>
{children} {children}

View File

@ -1,33 +1,67 @@
//
// commons-server connection
//
export const serviceScheme = 'http' export const serviceScheme = 'http'
export const serviceHost = 'localhost' export const serviceHost = 'localhost'
export const servicePort = 4000 export const servicePort = 4000
export const nodeScheme = 'http' //
export const nodeHost = 'localhost' // OCEAN REMOTE CONNECTIONS
export const nodePort = 8545 //
export const nodeScheme = 'https'
export const nodeHost = 'nile.dev-ocean.com'
export const nodePort = 443
export const aquariusScheme = 'http' export const aquariusScheme = 'https'
export const aquariusHost = 'aquarius' export const aquariusHost = 'nginx-aquarius.dev-ocean.com'
export const aquariusPort = 5000 export const aquariusPort = 443
export const brizoScheme = 'http' export const brizoScheme = 'https'
export const brizoHost = 'localhost' export const brizoHost = 'nginx-brizo.dev-ocean.com'
export const brizoPort = 8030 export const brizoPort = 443
export const brizoAddress = '0x413c9ba0a05b8a600899b41b0c62dd661e689354'
export const parityScheme = 'http' export const parityScheme = 'https'
export const parityHost = 'localhost' export const parityHost = 'nile.dev-ocean.com'
export const parityPort = 8545 export const parityPort = 443
export const secretStoreScheme = 'http' export const secretStoreScheme = 'https'
export const secretStoreHost = 'localhost' export const secretStoreHost = 'secret-store.dev-ocean.com'
export const secretStorePort = 12001 export const secretStorePort = 443
export const threshold = 0 export const faucetScheme = 'https'
export const password = 'node0' export const faucetHost = 'faucet.nile.dev-ocean.com'
export const address = '0x00bd138abd70e2f00903268f3db08f2d25677c9e' export const faucetPort = 443
export const faucetScheme = 'http' //
export const faucetHost = 'localhost' // OCEAN LOCAL CONNECTIONS
export const faucetPort = 3001 // e.g. when running with barge
//
// export const nodeScheme = 'http'
// export const nodeHost = 'localhost'
// export const nodePort = 8545
// export const aquariusScheme = 'http'
// export const aquariusHost = 'aquarius'
// export const aquariusPort = 5000
// export const brizoScheme = 'http'
// export const brizoHost = 'localhost'
// export const brizoPort = 8030
// export const parityScheme = 'http'
// export const parityHost = 'localhost'
// export const parityPort = 8545
// export const threshold = 0
// export const password = 'node0'
// export const address = '0x00bd138abd70e2f00903268f3db08f2d25677c9e'
// export const secretStoreScheme = 'http'
// export const secretStoreHost = 'localhost'
// export const secretStorePort = 12001
// export const faucetScheme = 'http'
// export const faucetHost = 'localhost'
// export const faucetPort = 3001
export const verbose = true export const verbose = true

View File

@ -1,24 +1,22 @@
import { Ocean } from '@oceanprotocol/squid' import { Ocean } from '@oceanprotocol/squid'
import { import {
address,
aquariusHost, aquariusHost,
aquariusPort, aquariusPort,
aquariusScheme, aquariusScheme,
brizoHost, brizoHost,
brizoPort, brizoPort,
brizoScheme, brizoScheme,
brizoAddress,
nodeHost, nodeHost,
nodePort, nodePort,
nodeScheme, nodeScheme,
parityHost, parityHost,
parityPort, parityPort,
parityScheme, parityScheme,
password,
secretStoreHost, secretStoreHost,
secretStorePort, secretStorePort,
secretStoreScheme, secretStoreScheme,
threshold,
verbose verbose
} from './config' } from './config'
@ -33,11 +31,9 @@ export async function provideOcean() {
nodeUri, nodeUri,
aquariusUri, aquariusUri,
brizoUri, brizoUri,
brizoAddress,
parityUri, parityUri,
secretStoreUri, secretStoreUri,
threshold,
password,
address,
verbose verbose
} }

View File

@ -5,14 +5,13 @@ import styles from './AssetDetails.module.scss'
import AssetFilesDetails from './AssetFilesDetails' import AssetFilesDetails from './AssetFilesDetails'
interface AssetDetailsProps { interface AssetDetailsProps {
ocean: any
metadata: any metadata: any
ddo: any ddo: any
} }
export default class AssetDetails extends PureComponent<AssetDetailsProps> { export default class AssetDetails extends PureComponent<AssetDetailsProps> {
public render() { public render() {
const { ocean, metadata, ddo } = this.props const { metadata, ddo } = this.props
const { base } = metadata const { base } = metadata
return ( return (
@ -25,7 +24,6 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
{base.copyrightHolder} {base.copyrightHolder}
</h2> </h2>
<div className={styles.metaPrimaryData}> <div className={styles.metaPrimaryData}>
<span title="Date created"> <span title="Date created">
<Moment <Moment
date={base.dateCreated} date={base.dateCreated}
@ -33,7 +31,7 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
interval={0} interval={0}
/> />
</span> </span>
{base.categories ? ( {base.categories ? (
// TODO: Make this link to search for respective category // TODO: Make this link to search for respective category
<Link to={`/search?q=${base.categories[0]}`}> <Link to={`/search?q=${base.categories[0]}`}>
@ -77,7 +75,6 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
<AssetFilesDetails <AssetFilesDetails
files={base.files ? base.files : []} files={base.files ? base.files : []}
ddo={ddo} ddo={ddo}
ocean={ocean}
/> />
<pre> <pre>

View File

@ -11,3 +11,26 @@
color: $red; color: $red;
font-size: $font-size-small; font-size: $font-size-small;
} }
.files {
text-align: center;
}
.file {
display: inline-block;
border: .1rem solid $brand-grey-light;
padding: $spacer $spacer / 2;
text-align: left;
margin-left: $spacer / 4;
margin-right: $spacer / 4;
li {
font-size: $font-size-small;
font-weight: $font-weight-bold;
color: $brand-grey-light;
&:before {
display: none;
}
}
}

View File

@ -1,11 +1,12 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { Logger } from '@oceanprotocol/squid' import { Logger } from '@oceanprotocol/squid'
import filesize from 'filesize'
import { User } from '../../context/User'
import Button from '../../components/atoms/Button' import Button from '../../components/atoms/Button'
import Spinner from '../../components/atoms/Spinner' import Spinner from '../../components/atoms/Spinner'
import styles from './AssetFilesDetails.module.scss' import styles from './AssetFilesDetails.module.scss'
interface AssetFilesDetailsProps { interface AssetFilesDetailsProps {
ocean: any
files: any[] files: any[]
ddo: any ddo: any
} }
@ -13,26 +14,30 @@ interface AssetFilesDetailsProps {
export default class AssetFilesDetails extends PureComponent< export default class AssetFilesDetails extends PureComponent<
AssetFilesDetailsProps AssetFilesDetailsProps
> { > {
public state = { decryptedFiles: [], isLoading: false, error: null } public state = { isLoading: false, error: null }
private purchaseAsset = async (ddo: any) => { private purchaseAsset = async (ddo: any) => {
this.setState({ isLoading: true, error: null }) this.setState({ isLoading: true, error: null })
const { ocean } = this.context
const accounts = await ocean.accounts.list()
try { try {
const account = await this.props.ocean.getAccounts()
const service = ddo.findServiceByType('Access') const service = ddo.findServiceByType('Access')
const serviceAgreementSignatureResult = await this.props.ocean.signServiceAgreement( const agreementId = await ocean.assets.order(
ddo.id, ddo.id,
service.serviceDefinitionId, service.serviceDefinitionId,
account[0] accounts[0]
) )
await this.props.ocean.initializeServiceAgreement(
const path = await ocean.assets.consume(
agreementId,
ddo.id, ddo.id,
service.serviceDefinitionId, service.serviceDefinitionId,
serviceAgreementSignatureResult.agreementId, accounts[0],
serviceAgreementSignatureResult.signature, ''
(files: any) => this.setState({ decryptedFiles: files }),
account[0]
) )
Logger.log('path', path)
this.setState({ isLoading: false }) this.setState({ isLoading: false })
} catch (error) { } catch (error) {
@ -43,51 +48,46 @@ export default class AssetFilesDetails extends PureComponent<
public render() { public render() {
const { files, ddo } = this.props const { files, ddo } = this.props
const filesArray =
this.state.decryptedFiles.length > 0
? this.state.decryptedFiles
: files
return ( return files ? (
<> <>
{this.state.decryptedFiles.length > 0 ? ( <div className={styles.files}>
filesArray.forEach(file => ( {files.map(file => (
<> <ul key={file.index} className={styles.file}>
<ul> <li>
{/* {file.contentType &&
TODO: getting this metadata depends on a change to to OEP-8, file.contentType.split('/')[1]}
see: https://github.com/oceanprotocol/OEPs/pull/154 </li>
*/} <li>
{/* <li>{file.contentType}</li> */} {file.contentLength &&
<li>{file.contentLength}</li> filesize(file.contentLength)}
{/* <li>{file.encoding}</li> */} </li>
{/* <li>{file.compression}</li> */} {/* <li>{file.encoding}</li> */}
</ul> {/* <li>{file.compression}</li> */}
</ul>
))}
</div>
{file.url && ( {this.state.isLoading ? (
<Button href={file.url}>Download asset</Button>
)}
</>
))
) : this.state.isLoading ? (
<Spinner message="Decrypting files, please sign with your wallet..." /> <Spinner message="Decrypting files, please sign with your wallet..." />
) : ( ) : (
<> <Button
<Button primary
primary className={styles.buttonMain}
className={styles.buttonMain} onClick={() => this.purchaseAsset(ddo)}
onClick={() => this.purchaseAsset(ddo)} >
> Get asset files
Get asset files </Button>
</Button> )}
{this.state.error && (
<div className={styles.error}> {this.state.error && (
{this.state.error} <div className={styles.error}>{this.state.error}</div>
</div>
)}
</>
)} )}
</> </>
) : (
<div>No files attached.</div>
) )
} }
} }
AssetFilesDetails.contextType = User

View File

@ -34,11 +34,7 @@ export default class Details extends Component<DetailsProps, DetailsState> {
title={metadata.base ? metadata.base.name : 'Loading Details'} title={metadata.base ? metadata.base.name : 'Loading Details'}
> >
{metadata && metadata.base.name ? ( {metadata && metadata.base.name ? (
<AssetDetails <AssetDetails metadata={metadata} ddo={ddo} />
ocean={this.context.ocean}
metadata={metadata}
ddo={ddo}
/>
) : ( ) : (
<div className={stylesApp.loader}> <div className={stylesApp.loader}>
<Spinner message={'Loading asset...'} /> <Spinner message={'Loading asset...'} />

View File

@ -54,7 +54,7 @@ class Home extends Component<HomeProps, HomeState> {
private searchAssets = (event: FormEvent<HTMLFormElement>) => { private searchAssets = (event: FormEvent<HTMLFormElement>) => {
event.preventDefault() event.preventDefault()
this.props.history.push(`/search?q=${this.state.search}`) this.props.history.push(`/search?text=${this.state.search}`)
} }
} }

View File

@ -1,5 +1,7 @@
import queryString from 'query-string'
import React, { Component } from 'react' import React, { Component } from 'react'
import queryString from 'query-string'
import { Logger } from '@oceanprotocol/squid'
import Spinner from '../components/atoms/Spinner'
import Route from '../components/templates/Route' import Route from '../components/templates/Route'
import { User } from '../context/User' import { User } from '../context/User'
import Asset from '../components/molecules/Asset' import Asset from '../components/molecules/Asset'
@ -7,6 +9,7 @@ import styles from './Search.module.scss'
interface SearchState { interface SearchState {
results: any[] results: any[]
isLoading: boolean
} }
interface SearchProps { interface SearchProps {
@ -15,16 +18,31 @@ interface SearchProps {
} }
export default class Search extends Component<SearchProps, SearchState> { export default class Search extends Component<SearchProps, SearchState> {
public state = { results: [] } public state = { results: [], isLoading: true }
public async componentDidMount() { public async componentDidMount() {
const searchParams = queryString.parse(this.props.location.search) const searchParams = queryString.parse(this.props.location.search)
const assets = await this.context.ocean.assets.search(searchParams.q)
this.setState({ results: assets }) const queryRequest = {
offset: 500,
page: 1,
query: {
text: searchParams.text
},
sort: {
text: 1
}
}
const assets = await this.context.ocean.assets.search(searchParams.text)
this.setState({ results: assets, isLoading: false })
Logger.log(`Loaded ${assets.length} assets`)
} }
public renderResults = () => public renderResults = () =>
this.state.results.length ? ( this.state.isLoading ? (
<Spinner message="Searching..." />
) : this.state.results.length ? (
<div className={styles.results}> <div className={styles.results}>
{this.state.results.map((asset: any) => ( {this.state.results.map((asset: any) => (
<Asset key={asset.id} asset={asset} /> <Asset key={asset.id} asset={asset} />
@ -35,8 +53,14 @@ export default class Search extends Component<SearchProps, SearchState> {
) )
public render() { public render() {
const searchTerm = queryString.parse(this.props.location.search).text
return ( return (
<Route title="Search Results" wide> <Route
title={`Search Results for <span>${searchTerm}</span>`}
titleReverse
wide
>
{this.renderResults()} {this.renderResults()}
</Route> </Route>
) )

View File

@ -22,7 +22,7 @@ export class UrlCheckRouter {
headers: { Range: 'bytes=0-' } headers: { Range: 'bytes=0-' }
}, },
(error, response) => { (error, response) => {
if (response.statusCode.toString().startsWith('2')) { if (response && response.statusCode.toString().startsWith('2')) {
const result: any = {} const result: any = {}
result.found = true result.found = true