Merge pull request #936 from oceanprotocol/v4

V4
This commit is contained in:
Akshay 2022-03-31 12:06:48 +02:00 committed by GitHub
commit 38943dd5da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 1637 additions and 991 deletions

View File

@ -3,7 +3,8 @@ name: 'CI'
on:
push:
branches:
- '**'
- main
- v4
pull_request:
branches:
- '**'

3
.gitignore vendored
View File

@ -8,4 +8,5 @@ yarn-error.log
.env.*
markdowns/
.vscode/
size-plugin.json
size-plugin.json
read-the-docs/

View File

@ -11,5 +11,6 @@
"no-trailing-punctuation": false,
"ol-prefix": false,
"ul-style": { "style": "dash" },
"no-emphasis-as-header": false
"no-emphasis-as-header": false,
"blanks-around-fences": false
}

View File

@ -42,7 +42,7 @@ module.exports = {
},
{
from: '/setup/compute-to-data/',
to: '/tutorials/compute-to-data/'
to: '/tutorials/compute-to-data-minikube/'
},
{
from: '/concepts/networks-overview/',
@ -92,7 +92,7 @@ module.exports = {
swaggerComponents: [
{
name: 'aquarius',
url: 'https://aquarius.oceanprotocol.com/spec'
url: 'https://v4.aquarius.oceanprotocol.com/spec'
},
{
name: 'provider',

View File

@ -1,6 +1,6 @@
---
title: Architecture Overview
description: Simplicity and Interoperability via a Datatokens Core
description: Data NFTs and datatokens architecture
---
## Overview
@ -11,27 +11,31 @@ Here is the Ocean architecture.
Heres an overview of the figure.
- The top layer is **applications** like Ocean Market. With these apps, users can onboard data services into crypto (publish and mint datatokens), hold datatokens as assets (data wallets), discover data assets and buy / sell datatokens for fixed or auto-determined price (data marketplaces), and consume data services (consume datatokens).
- Below that are **libraries** used by the applications: Ocean React hooks, JavaScript library, and Python library. This also includes middleware to assist discovery: Aquarius and (3rd party tool) TheGraph.
- The lowest level has the **smart contracts** used by the libraries. Theyre deployed on Ethereum mainnet to start, and other networks later.
- The top layer is **applications** like Ocean Market. With these apps, users can onboard services like data, algorithms, compute-to-data into crypto (publish and mint data NFTs and datatokens), hold datatokens as assets (data wallets), discover assets, and buy/sell datatokens for a fixed or auto-determined price (data marketplaces), and consume data services (consume datatokens).
- Below are **libraries** used by the applications: Ocean.js (JavaScript library) and Ocean.py (Python library). This also includes middleware to assist discovery:
- **Aquarius**: Provides metadata cache for faster search by caching on-chain data into elasticsearch
- **Provider**: Facilitates downloading assets, DDO encryption, and communicating with `operator-service` for Compute-to-Data jobs.
- **The Graph**: It is a 3rd party tool that developers can utilize the libraries to build their custom applications and marketplaces.
- The lowest level has the **smart contracts**. The smart contracts are deployed on the Ethereum mainnet and other compatible networks. Libraries encapsulate the calls to these smart contracts and provide features like publishing new assets, facilitating consumption, managing pricing, and much more. To see the supported networks click [here](/concepts/networks/).
Left to right are groupings of functionality: tools for datatokens, tools for markets (including pools), tools to consume data services and for metadata, and external ERC20 tools.
## Data NFTs, Datatokens and Access Control Tools
The rest of this page elaborates.
Data NFTs are based on [ERC721](https://eips.ethereum.org/EIPS/eip-721) standard. The publisher can use Marketplace or client libraries to deploy a new data NFT contract. To save gas fees, it uses [ERC1167](https://eips.ethereum.org/EIPS/eip-1167) proxy approach on the **ERC721 template**. Publisher can then assign manager role to other Ethereum addresses who can deploy new datatoken contracts and even mint them. Each datatoken contract is associated with one data NFT contract.
Click [here](/concepts/datanft-and-datatoken/) to further read about data NFTs and datatokens.
## Datatokens & Access Control Tools
ERC721 data NFTs represent holding copyright/base IP of a data asset, and ERC20 datatokens represent licenses to consume the data asset.
The publisher actor holds the dataset in Google Drive, Dropbox, AWS S3, on their phone, on their home server, etc. The dataset has a URL. The publisher can optionally use IPFS for a content-addressable URL. Or instead of a file, the publisher may run a compute-to-data service.
Datatoken represents the asset that the publisher wants to monetize. The asset can be a dataset or an algorithm. The publisher actor holds the asset in Google Drive, Dropbox, AWS S3, on their phone, on their home server, etc. The publisher can optionally use IPFS for a content-addressable URL. Or instead of a file, the publisher may run a compute-to-data service.
In the **publish** step, the publisher invokes **Ocean Datatoken Factory** to deploy a new datatoken to the chain. To save gas fees, it uses [ERC1167](https://eips.ethereum.org/EIPS/eip-1167) proxy approach on the **ERC20 datatoken template**. The publisher then mints datatokens.
The publisher runs **Ocean Provider**. In the **consume** step, Provider software needs to retrieve the data service URL given a datatoken address. One approach would be for the publisher to run a database; however this adds another dependency. To avoid this, it stores the URL on-chain. So that others dont see that URL, it encrypts it.
The publisher runs their own **Ocean Provider** or can use one deployed by Ocean Protocol. In the **consume** step, Provider software needs to retrieve the data service URL given a datatoken address. One approach would be for the publisher to run a database. However, this adds another dependency. To avoid this, the Provider encrypts the URL and it URL on-chain.
To initiate the **consume** step, the data consumer sends 1.0 datatokens to the Provider wallet. Then they make a service request to the Provider. The Provider loads the encrypted URL, decrypts it, and provisions the requested service (send static data, or enable a compute-to-data job).
Instead of running a Provider themselves, the publisher can have a 3rd party like Ocean Market run it. While more convenient, it means that the 3rd party has custody of the private encryption/decryption key (more centralized). Ocean will support more service types and url custody options in the future.
Instead of running a Provider themselves, the publisher can have a 3rd party like Ocean Market to run it. While more convenient, it means that the 3rd party has custody of the private encryption/decryption key (more centralized). Ocean will support more service types and URL custody options in the future.
**Ocean JavaScript and Python libraries** act as drivers for the lower-level contracts. Each library integrates with Ocean Provider to provision & consume data services, and Ocean Aquarius for metadata. **Ocean React hooks** use the JavaScript library, to help build web apps & React Native apps with Ocean.
**Ocean JavaScript and Python libraries** act as drivers for the lower-level contracts. Each library integrates with Ocean Provider to provision & consume data services, and Ocean Aquarius for metadata.
<repo name="provider"></repo>
<repo name="ocean.js"></repo>
@ -45,8 +49,8 @@ The marketplaces are decentralized (no single owner or controller), and non-cust
Ocean Market supports fixed pricing and automatic price discovery.
- For **fixed pricing**, theres a simple contract for users to buy/sell datatokens for OCEAN, while avoiding custodianship during value transfer.
- For **automatic price discovery**, Ocean Market uses automated market makers (AMMs) powered by [Balancer](https://www.balancer.finance). Each pool is a datatoken-OCEAN pair. In the Ocean Market GUI, the user adds liquidity then invokes pool creation; the GUIs React code calls the Ocean JavaScript library, which calls the **Pool Factory** to deploy a **Pool** contract. (The Python library also does this.) Deploying a datatoken pool can be viewed as an “Initial Data Offering” (IDO).
- For **fixed pricing**, theres a simple contract for users to buy/sell datatokens for OCEAN while avoiding custodianship during value transfer.
- For **automatic price discovery**, Ocean Market uses automated market makers (AMMs) powered by [Balancer](https://www.balancer.fi). Each pool is a datatoken-OCEAN pair. In the Ocean Market GUI, the user adds liquidity then invokes pool creation; the GUIs React code calls the Ocean JavaScript library, which calls the **Pool Factory** to deploy a **Pool** contract. (The Python library also does this.) Deploying a datatoken pool can be viewed as an “Initial Data Offering” (IDO).
Complementary to Ocean Market, Ocean has reference code to ease building **third-party data marketplaces**, such as for logistics ([dexFreight data marketplace](https://blog.oceanprotocol.com/dexfreight-ocean-protocol-partner-to-enable-transportation-logistics-companies-to-monetize-data-7aa839195ac)) or mobility ([Daimler](https://blog.oceanprotocol.com/ocean-protocol-delivers-proof-of-concept-for-daimler-ag-in-collaboration-with-daimler-south-east-564aa7d959ca)).
@ -56,14 +60,14 @@ Complementary to Ocean Market, Ocean has reference code to ease building **third
## Metadata Tools
Metadata (name of dataset, date created etc.) is used by marketplaces for data asset discovery. Each data asset can have a [decentralized identifier](https://w3c-ccg.github.io/did-spec/) (DID) that resolves to a DID document (DDO) for associated metadata. The DDO is essentially [JSON](https://www.json.org/) filling in metadata fields. For more details on working with OCEAN DIDs check out the [DID concept documentation](https://docs.oceanprotocol.com/concepts/did-ddo/).
Marketplaces use the Metadata of the asset for discovery. Metadata consists of information like the type of asset, name of the asset, creation date, license, etc. Each data asset can have a [decentralized identifier](https://w3c-ccg.github.io/did-spec/) (DID) that resolves to a DID document (DDO) for associated metadata. The DDO is essentially [JSON](https://www.json.org/) filling in metadata fields. For more details on working with OCEAN DIDs check out the [DID concept documentation](https://docs.oceanprotocol.com/concepts/did-ddo/).
The [DDO Metadata documentation](https://docs.oceanprotocol.com/concepts/ddo-metadata/) goes into more depth regarding metadata structure.
[OEP8](https://github.com/oceanprotocol/OEPs/tree/master/8) specifies Ocean metadata schema, including fields that must be filled. Its based on the public [DataSet schema from schema.org](https://schema.org/Dataset).
[OEP8](/concepts/did-ddo/) specifies Ocean metadata schema, including fields that must be filled. Its based on the public [DataSet schema from schema.org](https://schema.org/Dataset).
Ocean uses the Ethereum mainnet as an **on-chain metadata store**, i.e. to store both DID and DDO. This means that once the write fee is paid, there are no further expenses or dev-ops work needed to ensure metadata availability into the future, aiding in the discoverability of data assets. It also simplifies integration with the rest of the Ocean system, which is Ethereum-based. Storage cost on Ethereum mainnet is not negligible, but not prohibitive and the other benefits are currently worth the tradeoff compared to alternatives.
Ocean uses the Ethereum mainnet and other compatible networks as an **on-chain metadata store**, i.e. to store both DID and DDO. This means that once the transaction fee is paid, there are no further expenses or devops work needed to ensure metadata availability into the future, aiding in the discoverability of data assets. It also simplifies integration with the rest of the Ocean system, which is Ethereum-based. Storage cost on Ethereum mainnet is not negligible, but not prohibitive and the other benefits are currently worth the trade-off compared to alternatives.
Due to the permissionless, decentralized nature of data on Ethereum mainnet, any last-mile tool can access metadata. **Ocean Aquarius** supports different metadata fields for each different Ocean-based marketplace. Developers could also use [TheGraph](https://www.thegraph.com) to see metadata fields that are common across all marketplaces.
Due to the permissionless, decentralized nature of data on the Ethereum mainnet, any last mile tool can access metadata. **Ocean Aquarius** supports different metadata fields for each different Ocean-based marketplace. Developers could also use [The Graph](https://www.thegraph.com) to see metadata fields that are common across all marketplaces.
<repo name="aquarius"></repo>

View File

@ -24,7 +24,7 @@ The most basic scenario for a Publisher is to provide access to the datasets the
- [Compute-to-Data architecture](/tutorials/compute-to-data-architecture/)
- [Tutorial: Writing Algorithms](/tutorials/compute-to-data-algorithms/)
- [Tutorial: Set Up a Compute-to-Data Environment](/tutorials/compute-to-data/)
- [Tutorial: Set Up a Compute-to-Data Environment](/tutorials/compute-to-data-minikube/)
- [Use Compute-to-Data in Ocean Market](https://blog.oceanprotocol.com/compute-to-data-is-now-available-in-ocean-market-58868be52ef7)
- [Build ML models via Ocean Market or Python](https://medium.com/ravenprotocol/machine-learning-series-using-logistic-regression-for-classification-in-oceans-compute-to-data-18df49b6b165)
- [Compute-to-Data Python Quickstart](https://github.com/oceanprotocol/ocean.py/blob/main/READMEs/c2d-flow.md)

View File

@ -0,0 +1,48 @@
---
title: Data NFTs and Datatokens
description: In Ocean Protocol, ERC721 data NFTs represent holding copyright/base IP of a data asset, and ERC20 datatokens represent licenses to consume the assets.
---
A non-fungible token stored on the blockchain represents a unique asset. NFTs can represent images, videos, digital art, or any piece of information. NFTs can be traded, and allow transfer of copyright/base IP. [EIP-721](https://eips.ethereum.org/EIPS/eip-721) defines an interface for handling NFTs on EVM-compatible blockchains. The creator of the NFT can deploy a new contract on Ethereum or any Blockchain supporting NFT related interface and also, transfer the ownership of copyright/base IP through transfer transactions.
Fungible tokens represent fungible assets. If you have 5 ETH and Alice has 5 ETH, you and Alice could swap your ETH and your final holdings remain the same. They're apples-to-apples. Licenses (contracts) to consume a copyrighted asset are naturally fungible - they can be swapped with each other.
![Data NFT and datatoken](images/datanft-and-datatoken.png)
## High-Level Architecture
The image above describes how ERC721 data NFTs, ERC20 datatokens, and AMMs relate.
- Bottom: The publisher deploys an ERC721 data NFT contract representing the base IP for the data asset. They are now the manager of the data NFT.
- Middle: The manager then deploys an ERC20 datatoken contract against the data NFT. The ERC20 represents a license with specific terms like "can consume for the next 3 days". They could even publish further ERC20 datatoken contracts, to represent different license terms or for compute-to-data.
- Top: The manager then deploys a pool of the datatoken and OCEAN (or H2O), adds initial liquidity, and receives ERC20 pool tokens in return. Others may also add liquidity to receive pool tokens, i.e. become liquidity providers (LPs).
## Terminology
- **Base IP** means the artifact being copyrighted. Represented by the {ERC721 address, tokenId} from the publish transactions.
- **Base IP holder** means the holder of the Base IP. Represented as the actor that did the initial "publish" action.
- **Sub-licensee** is the holder of the sub-license. Represented as the entity that controls address ERC721.\_owners[tokenId=x].
- **To Publish**: Claim copyright or exclusive base license.
- **To Sub-license**: Transfer one (of many) sub-licenses to new licensee: ERC20.transfer(to=licensee, value=1.0).
## Implementation in Ocean Protocol
Ocean Protocol defines the [ERC721Factory](https://github.com/oceanprotocol/contracts/blob/v4main/contracts/ERC721Factory.sol) contract, allowing **Base IP holders** to create their ERC721 contract instances on any supported networks. The deployed contract stores Metadata, ownership, sub-license information, permissions. The contract creator can also create and mint ERC20 token instances for sub-licensing the **Base IP**.
ERC721 tokens are non-fungible, thus cannot be used for automatic price discovery like ERC20 tokens. ERC721 and ERC20 combined together can be used for sub-licensing. Ocean Protocol's [ERC721Template](https://github.com/oceanprotocol/contracts/blob/v4main/contracts/templates/ERC721Template.sol) solves this problem by using ERC721 for tokenizing the **Base IP** and tokenizing sub-licenses by using ERC20. Thus, sub-licenses can be traded on any AMM as the underlying contract is ERC20 compliant.
## High-Level Behavior
![Flow](images/use-case.png)
Here's an example.
- In step 1, Alice **publishes** her dataset with Ocean: this means deploying an ERC721 data NFT contract (claiming copyright/base IP), then an ERC20 datatoken contract (license against base IP).
- In step 2, she **mints** some ERC20 datatokens and **transfers** 1.0 of them to Bob's wallet; now he has a license to be able to consume that dataset.
## Other References
- [Data & NFTs 1: Practical Connections of ERC721 with Intellectual Property](https://blog.oceanprotocol.com/nfts-ip-1-practical-connections-of-erc721-with-intellectual-property-dc216aaf005d)
- [Data & NFTs 2: Leveraging ERC20 Fungibility](https://blog.oceanprotocol.com/nfts-ip-2-leveraging-erc20-fungibility-bcee162290e3)
- [Data & NFTs 3: Combining ERC721 & ERC20](https://blog.oceanprotocol.com/nfts-ip-3-combining-erc721-erc20-b69ea659115e)
- [Fungibility sightings in NFTs](https://blog.oceanprotocol.com/on-difficult-to-explain-fungibility-sightings-in-nfts-26bc18620f70)

View File

@ -1,349 +0,0 @@
---
title: DDO Metadata
description: Specification of the DDO subset dedicated to asset metadata
slug: /concepts/ddo-metadata/
section: concepts
---
## Overview
This page defines the schema for asset _metadata_. Metadata is the subset of an Ocean DDO that holds information about the asset.
The schema is based on public schema.org [DataSet schema](https://schema.org/Dataset).
Standardizing labels is key to effective searching, sorting and filtering (discovery).
This page specifies metadata attributes that _must_ be included, and that _may_ be included. These attributes are organized hierarchically, from top-layer attributes like `"main"` to sub-level attributes like `"main.type"`. This page also provides DDO metadata examples.
## Rules for Metadata Storage and Control in Ocean
The publisher publishes an asset DDO (including metadata) onto the chain.
The publisher may be the asset owner, or a marketplace acting on behalf of the owner.
Most metadata fields may be modified after creation. The blockchain records the provenance of changes.
DDOs (including metadata) are found in two places:
- _Remote_ - main storage, on-chain. File URLs are always encrypted. One may actually encrypt all metadata, at a severe cost to discoverability.
- _Local_ - local cache. All fields are in plaintext.
Ocean Aquarius helps manage metadata. It can be used to write DDOs to the chain, read from the chain, and has a local cache of the DDO in plaintext with fast search.
## Fields for Metadata
An asset represents a resource in Ocean, e.g. a dataset or an algorithm.
A `metadata` object has the following attributes, all of which are objects. Some are only required for local or remote, and are specified as such.
| Attribute | Required | Description |
| --------------------------- | -------- | ---------------------------------------------------------- |
| **`main`** | **Yes** | Main attributes |
| **`encryptedFiles`** | Remote | Encrypted string of the `attributes.main.files` object. |
| **`encryptedServices`** | Remote | Encrypted string of the `attributes.main.services` object. |
| **`status`** | No | Status attributes |
| **`additionalInformation`** | No | Optional attributes |
The `main` and `additionalInformation` attributes are independent of the asset type.
## Fields for `attributes.main`
The `main` object has the following attributes.
| Attribute | Type | Required | Description |
| ------------------- | --------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`name`** | Text |**Yes** | Descriptive name or title of the asset. |
| **`type`** | Text |**Yes** | Asset type. Includes `"dataset"` (e.g. csv file), `"algorithm"` (e.g. Python script). Each type needs a different subset of metadata attributes. |
| **`author`** | Text |**Yes** | Name of the entity generating this data (e.g. Tfl, Disney Corp, etc.). |
| **`license`** | Text |**Yes** | Short name referencing the license of the asset (e.g. Public Domain, CC-0, CC-BY, No License Specified, etc. ). If it's not specified, the following value will be added: "No License Specified". |
| **`files`** | Array of files object |**Yes** | Array of `File` objects including the encrypted file urls. |
| **`dateCreated`** | DateTime |**Yes** | The date on which the asset was created by the originator. ISO 8601 format, Coordinated Universal Time, e.g. `2019-01-31T08:38:32Z`. |
| **`datePublished`** | DateTime | Remote | The date on which the asset DDO is registered into the metadata store (Aquarius) |
## Fields for `attributes.main.files`
The `files` object has a list of `file` objects.
Each `file` object has the following attributes, with the details necessary to consume and validate the data.
| Attribute | Required | Description |
| -------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`index`** |**Yes** | Index number starting from 0 of the file. |
| **`contentType`** |**Yes** | File format. |
| **`url`** | Local | Content URL. Omitted from the remote metadata. Supports `http(s)://` and `ipfs://` URLs. |
| **`name`** | No | File name. |
| **`checksum`** | No | Checksum of the file using your preferred format (i.e. MD5). Format specified in `checksumType`. If it's not provided can't be validated if the file was not modified after registering. |
| **`checksumType`** | No | Format of the provided checksum. Can vary according to server (i.e Amazon vs. Azure) |
| **`contentLength`** | No | Size of the file in bytes. |
| **`encoding`** | No | File encoding (e.g. UTF-8). |
| **`compression`** | No | File compression (e.g. no, gzip, bzip2, etc). |
| **`encrypted`** | No | Boolean. Is the file encrypted? If is not set is assumed the file is not encrypted |
| **`encryptionMode`** | No | Encryption mode used. Just valid if `encrypted=true` |
| **`resourceId`** | No | Remote identifier of the file in the external provider. It is typically the remote id in the cloud provider. |
| **`attributes`** | No | Key-Value hash map with additional attributes describing the asset file. It could include details like the Amazon S3 bucket, region, etc. |
## Fields for `attributes.status`
A `status` object has the following attributes.
| Attribute | Type | Required | Description |
| --------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`isListed`** | Boolean | No | Use to flag unsuitable content. True by default. If it's false, the content must not be returned. |
| **`isRetired`** | Boolean | No | Flag retired content. False by default. If it's true, the content may either not be returned, or returned with a note about retirement. |
| **`isOrderDisabled`** | Boolean | No | For temporarily disabling ordering assets, e.g. when file host is in maintenance. False by default. If it's true, no ordering of assets for download or compute should be allowed. |
## Fields for `attributes.additionalInformation`
All the additional information will be stored as part of the `additionalInformation` section.
| Attribute | Type | Required |
| --------------------- | ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`tags`** | Array of Text | No | Array of keywords or tags used to describe this content. Empty by default. |
| **`description`** | Text | No | Details of what the resource is. For a dataset, this attribute explains what the data represents and what it can be used for. |
| **`copyrightHolder`** | Text | No | The party holding the legal copyright. Empty by default. |
| **`workExample`** | Text | No | Example of the concept of this asset. This example is part of the metadata, not an external link. |
| **`links`** | Array of Link | No | Mapping of links for data samples, or links to find out more information. Links may be to either a URL or another Asset. We expect marketplaces to converge on agreements of typical formats for linked data: The Ocean Protocol itself does not mandate any specific formats as these requirements are likely to be domain-specific. The links array can be an empty array, but if there is a link object in it, then an "url" is required in that link object. |
| **`inLanguage`** | Text | No | The language of the content. Please use one of the language codes from the [IETF BCP 47 standard](https://tools.ietf.org/html/bcp47). |
| **`categories`** | Array of Text | No | Optional array of categories associated to the asset. Note: recommended to use `"tags"` instead of this. |
## Fields - Other Suggestions
Here are example attributes to help an asset's discoverability.
| Attribute | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`updateFrequency`** | An indication of update latency - i.e. How often are updates expected (seldom, annually, quarterly, etc.), or is the resource static that is never expected to get updated. |
| **`structuredMarkup`** | A link to machine-readable structured markup (such as ttl/json-ld/rdf) describing the dataset. |
## DDO Metadata Example - Local
This is what the DDO metadata looks like. All fields are in plaintext. This is before it's stored on-chain or when it's retrieved and decrypted into a local cache.
```json
{
"main": {
"name": "Madrid Weather forecast",
"dateCreated": "2019-05-16T12:36:14.535Z",
"author": "Norwegian Meteorological Institute",
"type": "dataset",
"license": "Public Domain",
"price": "123000000000000000000",
"files": [
{
"index": 0,
"url": "https://example-url.net/weather/forecast/madrid/350750305731.xml",
"contentLength": "0",
"contentType": "text/xml",
"compression": "none"
}
]
},
"additionalInformation": {
"description": "Weather forecast of Europe/Madrid in XML format",
"copyrightHolder": "Norwegian Meteorological Institute",
"categories": ["Other"],
"links": [],
"tags": [],
"updateFrequency": null,
"structuredMarkup": []
},
"status": {
"isListed": true,
"isRetired": false,
"isOrderDisabled": false
}
}
```
## DDO Metadata Example - Remote
The previous example was for a local cache, with all fields in plaintext.
Here's the same example, for remote on-chain storage. That is, it's how metadata looks as a response to querying Aquarius (remote metadata).
How remote is changed, compared to local:
- `url` is removed from all objects in the `files` array
- `encryptedFiles` is added.
```json
{
"service": [
{
"index": 0,
"serviceEndpoint": "http://aquarius:5000/api/v1/aquarius/assets/ddo/{did}",
"type": "metadata",
"attributes": {
"main": {
"type": "dataset",
"name": "Madrid Weather forecast",
"dateCreated": "2019-05-16T12:36:14.535Z",
"author": "Norwegian Meteorological Institute",
"license": "Public Domain",
"files": [
{
"contentLength": "0",
"contentType": "text/xml",
"compression": "none",
"index": 0
}
],
"datePublished": "2019-05-16T12:41:01Z"
},
"encryptedFiles": "0x7a0d1c66ae861…df43aa9",
"additionalInformation": {
"description": "Weather forecast of Europe/Madrid in XML format",
"copyrightHolder": "Norwegian Meteorological Institute",
"categories": ["Other"],
"links": [],
"tags": [],
"updateFrequency": null,
"structuredMarkup": []
},
"status": {
"isListed": true,
"isRetired": false,
"isOrderDisabled": false
}
}
}
]
}
```
## Fields when `attributes.main.type = algorithm`
An asset of type `algorithm` has the following additional attributes under `main.algorithm`:
| Attribute | Type | Required | Description |
| --------------- | -------- | -------- | --------------------------------------------- |
| **`container`** | `Object` |**Yes** | Object describing the Docker container image. |
| **`language`** | `string` | No | Language used to implement the software |
| **`format`** | `string` | No | Packaging format of the software. |
| **`version`** | `string` | No | Version of the software. |
The `container` object has the following attributes:
| Attribute | Type | Required | Description |
| ---------------- | -------- | -------- | ----------------------------------------------------------------- |
| **`entrypoint`** | `string` |**Yes** | The command to execute, or script to run inside the Docker image. |
| **`image`** | `string` |**Yes** | Name of the Docker image. |
| **`tag`** | `string` |**Yes** | Tag of the Docker image. |
| **`checksum`** | `string` |**Yes** | Checksum of the Docker image. |
```json
{
"index": 0,
"serviceEndpoint": "http://localhost:5000/api/v1/aquarius/assets/ddo/{did}",
"type": "metadata",
"attributes": {
"main": {
"author": "John Doe",
"dateCreated": "2019-02-08T08:13:49Z",
"license": "CC-BY",
"name": "My super algorithm",
"type": "algorithm",
"algorithm": {
"language": "scala",
"format": "docker-image",
"version": "0.1",
"container": {
"entrypoint": "node $ALGO",
"image": "node",
"tag": "10",
"checksum": "efb2c764274b745f5fc37f97c6b0e761"
}
},
"files": [
{
"name": "build_model",
"url": "https://raw.gith ubusercontent.com/oceanprotocol/test-algorithm/master/javascript/algo.js",
"index": 0,
"checksum": "efb2c764274b745f5fc37f97c6b0e761",
"contentLength": "4535431",
"contentType": "text/plain",
"encoding": "UTF-8",
"compression": "zip"
}
]
},
"additionalInformation": {
"description": "Workflow to aggregate weather information",
"tags": ["weather", "uk", "2011", "workflow", "aggregation"],
"copyrightHolder": "John Doe"
}
}
}
```
## Fields when `attributes.main.type = compute`
An asset with a service of type `compute` has the following additional attributes under `main.privacy`:
| Attribute | Type | Required | Description |
| --------------------------------- | ------------------ | -------- | ---------------------------------------------------------- |
| **`allowRawAlgorithm`** | `boolean` |**Yes** | If True, a drag & drop algo can be runned |
| **`allowNetworkAccess`** | `boolean` |**Yes** | If True, the algo job will have network access (stil WIP) |
| **`publisherTrustedAlgorithms `** | Array of `Objects` |**Yes** | If Empty , then any published algo is allowed. (see below) |
The `publisherTrustedAlgorithms ` is an array of objects with the following structure:
| Attribute | Type | Required | Description |
| ------------------------------ | -------- | -------- | ------------------------------------------------------------------ |
| **`did`** | `string` |**Yes** | The did of the algo which is trusted by the publisher. |
| **`filesChecksum`** | `string` |**Yes** | Hash of ( algorithm's encryptedFiles + files section (as string) ) |
| **`containerSectionChecksum`** | `string` |**Yes** | Hash of the algorithm container section (as string) |
To produce `filesChecksum`:
```javascript
sha256(
algorithm_ddo.service['metadata'].attributes.encryptedFiles +
JSON.Stringify(algorithm_ddo.service['metadata'].attributes.main.files)
)
```
To produce `containerSectionChecksum`:
```javascript
sha256(
JSON.Stringify(
algorithm_ddo.service['metadata'].attributes.main.algorithm.container
)
)
```
### Example of a compute service
```json
{
"type": "compute",
"index": 1,
"serviceEndpoint": "https://provider.oceanprotocol.com",
"attributes": {
"main": {
"name": "dataAssetComputingService",
"creator": "0xA32C84D2B44C041F3a56afC07a33f8AC5BF1A071",
"datePublished": "2021-02-17T06:31:33Z",
"cost": "1",
"timeout": 3600,
"privacy": {
"allowRawAlgorithm": true,
"allowNetworkAccess": false,
"publisherTrustedAlgorithms": [
{
"did": "0xxxxx",
"filesChecksum": "1234",
"containerSectionChecksum": "7676"
},
{
"did": "0xxxxx",
"filesChecksum": "1232334",
"containerSectionChecksum": "98787"
}
]
}
}
}
}
```

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -3,20 +3,23 @@ title: Introduction
description: Ocean Protocol - Tools for the Web3 Data Economy
---
In Ocean Protocol, each data service gets its own ERC20 **datatoken**. This enables data wallets, data exchanges, and data co-ops by directly leveraging crypto wallets, exchanges, and more.
In Ocean Protocol, each asset gets its own ERC721 **data NFT** and one(or more) ERC20 **datatokens**. This enables data wallets, data exchanges, and data co-ops by directly leveraging crypto wallets, exchanges, and more.
OCEAN token is used for staking, and more. [Here](https://oceanprotocol.com/token) are details.
Ocean Protocol provides tools for developers to _build data markets_, and to _manage datatokens_ for use in DeFi.
Ocean Protocol provides tools for developers to _build data markets_, and to _manage data NFTs and datatokens_ for use in DeFi.
**Build Data Markets.** Use Ocean Protocol software tools to build your own data marketplace, by either forking [Ocean Market](https://market.oceanprotocol.com/) code or building up with Ocean components.
**Manage Datatokens for use in DeFi.** Use Ocean [JavaScript](https://github.com/oceanprotocol/ocean.js) or [Python](https://github.com/oceanprotocol/ocean.py) drivers to manage datatokens:
**Manage datatokens and data NFTs for use in DeFi.** Use Ocean [JavaScript](https://github.com/oceanprotocol/ocean.js) or [Python](https://github.com/oceanprotocol/ocean.py) drivers to manage data NFTs and datatokens:
- _Publish and consume data services:_ downloadable files or compute-to-data. Use Ocean to deploy a new [ERC20](https://github.com/ethereum/EIPs/blob/7f4f0377730f5fc266824084188cc17cf246932e/EIPS/eip-20.md) datatoken contract for each data service, then mint datatokens.
- _Publish and consume data services:_ downloadable files or compute-to-data. Use Ocean to deploy a new [ERC721](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md) and [ERC20](https://github.com/ethereum/EIPs/blob/7f4f0377730f5fc266824084188cc17cf246932e/EIPS/eip-20.md) datatoken contract for each data service, then mint datatokens.
- _Transfer datatokens_ to another owner (or approve & transferFrom).
- _Manage pools._ Deploy OCEAN-datatoken [Balancer](https://www.balancer.finance/) pools, buy & sell datatokens (swap), and add & remove liquidity.
- _Manage pools._ Deploy OCEAN-datatoken [Balancer](https://www.balancer.fi/) pools, buy & sell datatokens (swap), and add & remove liquidity.
- _And more._ Use ERC20 support in [web3.js](https://web3js.readthedocs.io/), [web3.py](https://web3py.readthedocs.io/en/stable/examples.html#working-with-an-erc20-token-contract) and Solidity to connect datatokens with crypto wallets and other DeFi services.
**Compute-to-Data**
Ocean's "Compute-to-Data" feature gives compute access to privately-held data, which never leaves the data owners premises. Ocean-based marketplaces enable the monetization of private data while preserving privacy. [Here](/tutorials/compute-to-data-architecture/) are details.

View File

@ -3,182 +3,13 @@ title: Supported Networks
description: All the public networks the Ocean Protocol contracts are deployed to, and additional core components deployed to them.
---
Ocean Protocol contracts are deployed on multiple public networks. You can always find the most up-to-date deployment addresses for all individual contracts in the [address.json](https://github.com/oceanprotocol/contracts/blob/master/artifacts/address.json) artifact.
Ocean Protocol contracts are deployed on multiple public networks. You can always find the most up-to-date deployment addresses for all individual contracts in the [address.json](https://github.com/oceanprotocol/contracts/blob/v4main/addresses/address.json).
In each network, youll need ETH to pay for gas, and OCEAN for certain Ocean actions. Because the Ethereum mainnet is a network for production settings, ETH and OCEAN tokens have real value on there. The ETH and OCEAN tokens in each test network dont have real value and are used for testing-purposes only. They can be obtained with _faucets_ to dole out ETH and OCEAN.
The universal Aquarius Endpoint is `https://aquarius.oceanprotocol.com`.
## Ethereum Mainnet
The Ethereum Mainnet is Oceans production network.
MetaMask and other ERC20 wallets default to Ethereum mainnet, therefore your wallet is almost certainly pointing to Ethereum by default.
**Tokens**
- ETH:
- Native token to pay transaction fees
- [Exchanges to purchase](https://www.coingecko.com/en/coins/ethereum#markets)
- OCEAN:
- Address: [0x967da4048cD07aB37855c090aAF366e4ce1b9F48](https://etherscan.io/token/0x967da4048cD07aB37855c090aAF366e4ce1b9F48)
- [Exchanges to purchase](https://oceanprotocol.com/token#get)
**Additional Components**
| What | URL |
| ------------ | -------------------------------------------- |
| Explorer | https://etherscan.io |
| Ocean Market | https://market.oceanprotocol.com |
| Provider | `https://provider.mainnet.oceanprotocol.com` |
| Subgraph | `https://subgraph.mainnet.oceanprotocol.com` |
## Polygon Mainnet
Ocean is [deployed](https://blog.oceanprotocol.com/ocean-on-polygon-network-8abad19cbf47) to the [Polygon](https://polygon.technology/) production network. Polygon's native token is MATIC.
If you don't find Polygon as a predefined network in your wallet, you can connect to it manually via [this guide](/tutorials/metamask-setup/#set-up-custom-network) and the parameters below.
| What | Value |
| ------------------ | ---------------------------------------- |
| Network Name | `Matic Mainnet` |
| RPC | `https://rpc.polygon.oceanprotocol.com/` |
| Chain Id | `137` |
| Currency Symbol | `MATIC` |
| Block Explorer URL | `https://explorer.matic.network/` |
**Tokens**
- MATIC:
- Native token to pay transaction fees
- [Exchanges to purchase](https://www.coingecko.com/en/coins/polygon#markets)
- Polygon OCEAN:
- Address: [0x282d8efCe846A88B159800bd4130ad77443Fa1A1](https://polygonscan.com/token/0x282d8efCe846A88B159800bd4130ad77443Fa1A1)
- [Exchanges to purchase](https://oceanprotocol.com/token#get)
**Additional Components**
| What | URL |
| ------------ | -------------------------------------------------------------------- |
| Explorer | https://polygonscan.com/ |
| Ocean Market | Point wallet to Polygon network, at https://market.oceanprotocol.com |
| Provider | `https://provider.polygon.oceanprotocol.com` |
| Subgraph | `https://subgraph.polygon.oceanprotocol.com` |
**Bridge**
Check our [Polygon Bridge guide](/tutorials/polygon-bridge/) to learn how you can deposit, withdraw and send tokens.
## Moonriver
Ocean is deployed to [Moonriver](https://moonbeam.network/networks/moonriver/), another production network. Moonriver's native token is MOVR.
If you don't find Moonriver as a predefined network in your wallet, you can connect to it manually via [Ocean's guide](/tutorials/metamask-setup/#set-up-custom-network) and the parameters below.
| What | Value |
| ------------------ | ----------------------------------- |
| Network Name | `Moonriver` |
| RPC | `https://rpc.moonriver.moonbeam.network`|
| Chain Id | `1285` |
| Currency Symbol | `MOVR` |
| Block Explorer URL | `https://blockscout.moonriver.moonbeam.network` |
**Tokens**
- Moonriver MOVR:
- Native token to pay transaction fees
- Exchanges to purchase: [List](https://coinmarketcap.com/currencies/moonriver/markets/)
- Moonriver OCEAN:
- Address: [0x99C409E5f62E4bd2AC142f17caFb6810B8F0BAAE](https://blockscout.moonriver.moonbeam.network/address/0x99C409E5f62E4bd2AC142f17caFb6810B8F0BAAE/)
- [Exchanges to purchase](https://oceanprotocol.com/token#get)
**Additional Components**
| What | URL |
| ------------ | ---------------------------------------------------------------- |
| Explorer | https://blockscout.moonriver.moonbeam.network/ |
| Ocean Market | Point wallet to Moonriver network, at https://market.oceanprotocol.com |
| Provider | `https://provider.moonriver.oceanprotocol.com` |
| Subgraph | `https://subgraph.moonriver.oceanprotocol.com` |
**Bridge**
Use [Anyswap](https://anyswap.exchange/#/bridge) to bridge between ETH Mainnet and Moonriver
The universal Aquarius Endpoint is `https://v4.aquarius.oceanprotocol.com`.
## Energy Web Chain
Ocean is deployed to [Energy Web Chain](https://energy-web-foundation.gitbook.io/energy-web/technology/the-stack/trust-layer-energy-web-chain), another production network. Energy Web's native token is EWT.
If you don't find Energy Web Chain as a predefined network in your wallet, you can connect to it manually via [Ocean's guide](/tutorials/metamask-setup/#set-up-custom-network) and the parameters below.
| What | Value |
| ------------------ | ----------------------------------- |
| Network Name | `Energy Web Chain` |
| RPC | `https://rpc.energyweb.org` |
| Chain Id | `246` |
| Currency Symbol | `EWT` |
| Block Explorer URL | `https://explorer.energyweb.org/` |
**Tokens**
- Energy Web Chain EWT:
- Native token to pay transaction fees
- Exchanges to purchase: [List](https://coinmarketcap.com/currencies/energy-web-token/markets/)
- Energy Web Chain OCEAN:
- Address: [0x593122aae80a6fc3183b2ac0c4ab3336debee528](https://explorer.energyweb.org/tokens/0x593122AAE80A6Fc3183b2AC0c4ab3336dEbeE528)
- [Exchanges to purchase](https://oceanprotocol.com/token#get)
**Additional Components**
| What | URL |
| ------------ | ---------------------------------------------------------------- |
| Explorer | https://explorer.energyweb.org/ |
| Ocean Market | Point wallet to Energy Web Chain network, at https://market.oceanprotocol.com |
| Provider | `https://provider.energyweb.oceanprotocol.com` |
| Subgraph | `https://subgraph.energyweb.oceanprotocol.com` |
**Bridge**
Use [Carbonswap bridge](https://bridge.carbonswap.exchange/bridge) to bridge between ETH Mainnet and Energy Web Chain
## Binance Smart Chain
Ocean is deployed to [Binance Smart Chain (BSC)](https://academy.binance.com/en/articles/how-to-get-started-with-binance-smart-chain-bsc), another production network. BSC's native token is BNB - the Binance token.
If you don't find BSC as a predefined network in your wallet, you can connect to it manually via [Binance's guide](https://academy.binance.com/en/articles/connecting-metamask-to-binance-smart-chain) or [Ocean's guide](/tutorials/metamask-setup/#set-up-custom-network) and the parameters below.
| What | Value |
| ------------------ | ----------------------------------- |
| Network Name | `Smart Chain` |
| RPC | `https://bsc-dataseed.binance.org/` |
| Chain Id | `56` |
| Currency Symbol | `BNB` |
| Block Explorer URL | `https://bscscan.com` |
**Tokens**
- BSC BNB:
- Native token to pay transaction fees
- Exchanges to purchase: typically [binance.com](https://www.binance.com)
- BSC OCEAN:
- Address: [0xdce07662ca8ebc241316a15b611c89711414dd1a](https://bscscan.com/token/0xdce07662ca8ebc241316a15b611c89711414dd1a)
- [Exchanges to purchase](https://oceanprotocol.com/token#get)
**Additional Components**
| What | URL |
| ------------ | ---------------------------------------------------------------- |
| Explorer | https://bscscan.com/ |
| Ocean Market | Point wallet to BSC network, at https://market.oceanprotocol.com |
| Provider | `https://provider.bsc.oceanprotocol.com` |
| Subgraph | `https://subgraph.bsc.oceanprotocol.com` |
**Bridge**
Check our [BSC Bridge guide](/tutorials/bsc-bridge/) to learn how you can deposit, withdraw and send tokens.
## Ropsten
@ -201,8 +32,8 @@ In MetaMask and other ERC20 wallets, click on the network name dropdown, then se
| ------------ | -------------------------------------------------------------------- |
| Explorer | https://ropsten.etherscan.io |
| Ocean Market | Point wallet to Ropsten network, at https://market.oceanprotocol.com |
| Provider | `https://provider.ropsten.oceanprotocol.com` |
| Subgraph | `https://subgraph.ropsten.oceanprotocol.com` |
| Provider | `https://v4.provider.ropsten.oceanprotocol.com` |
| Subgraph | `https://v4.subgraph.ropsten.oceanprotocol.com` |
## Rinkeby
@ -225,8 +56,8 @@ In MetaMask and other ERC20 wallets, click on the network name dropdown, then se
| ------------ | -------------------------------------------------------------------- |
| Explorer | https://rinkeby.etherscan.io |
| Ocean Market | Point wallet to Rinkeby network, at https://market.oceanprotocol.com |
| Provider | `https://provider.rinkeby.oceanprotocol.com` |
| Subgraph | `https://subgraph.rinkeby.oceanprotocol.com` |
| Provider | `https://v4.provider.rinkeby.oceanprotocol.com` |
| Subgraph | `https://v4.subgraph.rinkeby.oceanprotocol.com` |
## Mumbai
@ -249,31 +80,34 @@ If you don't find Mumbai as a predefined network in your wallet, you can connect
| ------------ | ------------------------------------------------------------------- |
| Explorer | https://mumbai.polygonscan.com |
| Ocean Market | Point wallet to Mumbai network, at https://market.oceanprotocol.com |
| Provider | `https://provider.mumbai.oceanprotocol.com` |
| Subgraph | `https://subgraph.mumbai.oceanprotocol.com` |
| Provider | `https://v4.provider.mumbai.oceanprotocol.com` |
| Subgraph | `https://v4.subgraph.mumbai.oceanprotocol.com` |
## Celo Alfajores
Alfajores is a Celo test network for developers building on the Celo platform.
## Moonbase
Celo docs: https://docs.celo.org/.
Moonbase is a test network tuned for Moonbeam / Moonriver.
Wallet setup: https://celo.org/developers/wallet
If you don't find Moonbase as a predefined network in your wallet, you can connect to it manually via [Moonbase guide](https://docs.moonbeam.network/learn/platform/networks/moonbase/).
**Tokens**
- Alfajores CELO:
- Moonbase DEV:
- Native token to pay transaction fees
- [Faucet](https://celo.org/developers/faucet).
- Alfajores OCEAN:
- Address: [0xd8992Ed72C445c35Cb4A2be468568Ed1079357c8](https://alfajores-blockscout.celo-testnet.org/address/0xd8992Ed72C445c35Cb4A2be468568Ed1079357c8/)
- Facuet: See above guide You may find others by [searching](https://www.google.com/search?q=moonbase+dev+faucet).
- Moonbase OCEAN:
- Address: [0xF6410bf5d773C7a41ebFf972f38e7463FA242477](https://moonbase.moonscan.io/token/0xF6410bf5d773C7a41ebFf972f38e7463FA242477)
- [Faucet](https://faucet.moonbase.oceanprotocol.com/)
**Additional Components**
| What | URL |
| ------------ | ------------------------------------------------------------------- |
| Explorer | https://alfajores-blockscout.celo-testnet.org/ |
| Explorer | https://moonbase.moonscan.io/ |
| Ocean Market | Point wallet to Moonbase network, at https://market.oceanprotocol.com |
| Provider | `https://v4.provider.moonbase.oceanprotocol.com/` |
| Subgraph | `https://v4.subgraph.moonbase.oceanprotocol.com` |
## Local / Ganache

37
content/concepts/roles.md Normal file
View File

@ -0,0 +1,37 @@
---
title: Data NFTs and datatoken roles
description: The permissions stored on chain in the contracts control the access to the data NFT (ERC721) and datatoken (ERC20) smart contract functions.
---
The permissions are stored in the data NFT (ERC721) smart contract. The data NFT (ERC721) and datatoken (ERC20) smart contracts both use this information to restrict access to the smart contract functions. The tables below list restricted actions that are accessible only to the allowed users.
## Roles in data NFT (ERC721) smart contract
| Action &darr; / Role &rarr; | NFT Owner | Manager | ERC20 Deployer | Store Updater | Metadata Updater |
| --------------------------------- | ------------------ | ------------------ | ------------------ | ------------------ | ------------------ |
| Set token URI | | | | | |
| Add manager | <center>🗸</center> | | | | |
| Remove manager | <center>🗸</center> | | | | |
| Clean permissions | <center>🗸</center> | | | | |
| Set base URI | <center>🗸</center> | | | | |
| Set Metadata state | | | | | <center>🗸</center> |
| Set Metadata | | | | | <center>🗸</center> |
| Create new datatoken | | | <center>🗸</center> | | |
| Executes any other smart contract | | <center>🗸</center> | | | |
| Set new key-value in store | | | | <center>🗸</center> | |
## Roles in datatoken (ERC20) smart contract
| Action &darr; / Role &rarr; | ERC20 Deployer | Minter | NFT owner | Fee manager |
| --------------------------- | ------------------ | ------------------ | ------------------ | ------------------ |
| Deploy pool | <center>🗸</center> | | | |
| Create Fixed Rate exchange | <center>🗸</center> | | | |
| Create Dispenser | <center>🗸</center> | | | |
| Add minter | <center>🗸</center> | | | |
| Remove minter | <center>🗸</center> | | | |
| Add fee manager | <center>🗸</center> | | | |
| Remove fee manager | <center>🗸</center> | | | |
| Set data | <center>🗸</center> | | | |
| Clean permissions | | | <center>🗸</center> | |
| Mint | | <center>🗸</center> | | |
| Set fee collector | | | | <center>🗸</center> |

View File

@ -2,7 +2,8 @@
title: Set Up Azure Storage
description: Tutorial about how to set up Azure storage for use with Ocean.
---
*Note: This needs updating for Ocean V3.*
_Note: This needs updating for Ocean V3._
This tutorial is for publishers who want to get started using Azure to store some of their data assets. (Some data assets could also be stored in other places.)
@ -174,4 +175,3 @@ You now have a storage account, but you don't have any data stored under it yet.
Azure Storage can store blobs, files, queues and tables. To work with Ocean Network, you should store your files in [Azure Blob storage (also called object storage)](https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction), not Azure Files.
Besides Azure Storage Explorer, there are [many other Azure Storage APIs, libraries and tools](https://docs.microsoft.com/en-us/azure/storage/common/storage-introduction#storage-apis-libraries-and-tools).

View File

@ -42,7 +42,7 @@ To do so, create a Dockerfile with the appropriate instructions for dependency m
We also collect some [example images](https://github.com/oceanprotocol/algo_dockers) which you can also view in Dockerhub.
When publishing an algorithm through the [Ocean Market](https://market.oceanprotoco.com), these properties can be set via the publish UI.
When publishing an algorithm through the [Ocean Market](https://market.oceanprotocol.com), these properties can be set via the publish UI.
### Environment Examples

View File

@ -0,0 +1,94 @@
---
title: Fees
description: The Ocean Protocol defines various fees for creating a sustainability loop.
---
## Path to sustainability
Ocean Protocol achieves sustainability via the [Web3 sustainability loop](https://blog.oceanprotocol.com/the-web3-sustainability-loop-b2a4097a36e).
- The project grows and improves through the efforts of OceanDAO grant recipients.
- The OceanDAO votes to decide which proposals receive grants.
- Grant funds are sourced from the Ocean Protocol community treasury.
- The Ocean Protocol community collects fees when users interact with the protocol, thus completing the sustainability loop.
## Fee types
### Swap fee
Swap fees are collected whenever someone swaps a datatoken for base token (e.g., OCEAN) or base token for a datatoken. The swap could be inside a pool (using an automated market maker) or in a fixed-rate exchange.
These are the fees that are applied whenever a user swaps base token or datatoken:
- Publisher Marketplace swap fee
- Consumer Marketplace swap fee
- Provider Consumption Fees
- [Ocean Community Fee](#ocean-community-fee)
### Publish fee
Publish fees can be charged to a publisher when they publish an asset.
Currently, the Ocean marketplace does not charge a publishing fee. Custom marketplaces can charge a publishing fee by adding an extra transaction in the publish flow.
Based on the use case of the marketplace, the marketplace owner can decide if this fee should be charged or not.
### Consume fee
Consume fees (aka. Order fees) are charged when a user holding a datatoken exchanges it for the right to download an asset or to start a compute job that uses the asset.
These are the fees that are applied whenever a user consumes an asset:
- Consume Market Consumption Fee
- Publisher Market Consumption Fee
- Provider Consumption Fees
- [Ocean Community Fee](#ocean-community-fee)
### Ocean Community fee
Ocean's smart contracts collect **Ocean Community fees** during swap and order operations. These fees are reinvested in community projects via OceanDAO and other initiatives.
For swaps involving approved base tokens like OCEAN and H2O, the Ocean Community swap fee is 0.1%. For swaps involving other base tokens, the Ocean Community swap fee is 0.2%. The Ocean Community order fee is 0.3 DT per order operation.
These fees can be updated by the Ocean Protocol Foundation.
### Provider fee
Provider is a component of Ocean Protocol's ecosystem that facilitates data consumption, starts compute jobs, encrypts DDOs, and decrypts DDOs. Provider also validates if the user can access a particular data asset or service. To learn more about Provider, click [here](https://github.com/oceanprotocol/provider).
Provider fees are paid to the individual or organization running their Provider instance when the user orders an asset. These fees can be set to an absolute amount, not as a percentage. The provider can also specify which token the fees must be paid in - they don't have to be the same token used in the consuming market.
Provider fees can also be used to charge for computing resources. Based on the compute resources needed to run an algorithm in the Compute-to-Data environment, a consumer can choose the amount to pay according to their needs.
These fees incentivize individuals and organizations to run their provider instances and charge consumers according to resource usage.
## Fee values
The table is periodically updated. Users are advised to confirm new values through the [contracts](https://github.com/oceanprotocol/contracts) and the [market](https://github.com/oceanprotocol/market).
| Swap Fees | Value in Ocean Market, using any Provider | Value in Other Markets |
| :------------------------------------------------------------ | :----------------------------------------:| :----------------------------------------------------------------------------------------------------------------------------------------------- |
| publishMarket: Pools | 0% | Set in the market config, by the publishing market.<br>Min = 0.001%<br>Max = 10% |
| publishMarket: FixedRate | 0% | Set in the market config, by the publishing market.<br>Min = 0.001%<br>Max = 50% |
| consumeMarket: Pools | 0% | Set in market config, by the consuming market.<br>Min = 0.001%<br>Max = 10% |
| consumeMarket: FixedRate<br>ERC20Template | 0% | 0% |
| consumeMarket: FixedRate<br>EnterpriseTemplate | 0% | Set in market config, by the consuming market. |
| Ocean Community: Pools & FixedRate<br>OCEAN, H2O as base token| 0.1% | 0.1% |
| Ocean Community: Pools & FixedRate<br>other base token | 0.2% | 0.2% |
| Pool Liquidity Provider (LP) | 1% | Set by the pool creator on contract deployment.<br><b>Contracts</b> <br> Min = 0.001% <br>Max = 10%<br><b>Market</b> <br>Min = 0.1% <br>Max = 10%|
| <b>Publish Fees</b> | 0% | 0% |
| <b>Order Fees <br>1 datatoken available to get dataset acces | | |
| publishMarket<br>Absolute value, in any token. E.g. 5 USDT | 0 | Set in market config, by the publishing market. |
| consumeMarket<br>Absolute value, in any token. E.g. 2 DAI | 0 | Set in market config, by the consuming market. |
| Ocean Community<br>Fixed price in DT | 0.03 DT | 0.03 DT |
| Ocean Provider Fees | OPF Provider | 3rd party Provider |
| :------------------------------------------------------------ | :----------------------------------------:| :----------------------------------------------------------------------------------------------------------------------------------------------- |
| Token in which fee is charged: `PROVIDER_FEE_TOKEN` | OCEAN | E.g. USDC |
| Download: `COST_PER_MB` | 0 | Set in Provider envvars. |
| Compute: `COST_PER_MIN`<br> Environment: 1 CPU, 60 secs max | 0 | Set in OperatorEngine envvars. |
| Compute: `COST_PER_MIN`<br> Environment: 1 CPU, 1 hour max | 1.0 OCEAN/min | Set in OperatorEngine envvars. |
| Ocean Community | 0% of the Provider fee | 0% of the Provider fee |
## Further reading
- [The Web3 Sustainability Loop](https://blog.oceanprotocol.com/the-web3-sustainability-loop-b2a4097a36e)

View File

@ -27,8 +27,8 @@ Ocean Market provides a convenient interface for individuals as well as organiza
5. After clicking submit, approve the transactions in the wallet. Here, you can see Metamask window.
Deploy a new Datatoken contract.
![publish submit part-1](images/marketplace/submit-1.png 'Create Datatoken contract')
Deploy a new datatoken contract.
![publish submit part-1](images/marketplace/submit-1.png 'Create datatoken contract')
Contract interaction.
![publish submit part-2](images/marketplace/submit-2.png 'Contract interaction')

View File

@ -3,7 +3,7 @@ title: Swap and/or Stake Tokens
description:
---
## Swap Ocean Tokens against Datatokens
## Swap OCEAN Tokens against datatokens
1. Search for the desired asset published on the [Ocean Marketplace](https://market.oceanprotocol.com/).

View File

@ -3,43 +3,19 @@ title: Set Up a Marketplace
description:
---
In Ocean, marketplaces and publishers are different roles. A common setup is for one organization to do both. We focus on that here.
## About marketplace
## The Steps
Ocean Protocol's [marketplace](https://market.oceanprotocol.com/) provides a web interface for accessing assets published on the chain. By default, assets metadata is pulled from Aquarius, component hosted by Ocean Protocol. To extend the existing features of the marketplace, developers can fork the marketplace.
1. Develop the first cut of the app.
1. Prepare some initial data assets.
1. Deploy to production.
By doing so, developers can:
## Develop a First Cut of the App
- Change the name of the marketplace.
- Implement their own branding and style.
- Change the source of the asset information.
- Customise the fees
Here are some approaches:
## Forking marketplace
- Fork [Ocean Market](https://github.com/oceanprotocol/market) code.
- Build from [Ocean React hooks](https://github.com/oceanprotocol/react).
- Build up from [ocean.js](https://github.com/oceanprotocol/ocean.js) or [ocean.py](https://github.com/oceanprotocol/ocean.py) drivers.
To setup a marketplace follow the steps here:
## Prepare Some Initial Data Assets
When you deploy, you'll want some initial data assets for your market to offer.
Ocean supports several types, such as Azure and S3 storage. The [tutorials](/tutorials/) section provides more info.
## Deploy to Production
When developing your app, you'll likely use Barge to run all the Ocean Protocol components on your local machine.
When it comes time to go to production, you will have to run these components:
- Your marketplace/publisher app
- Aquarius (with Elasticsearch)
- Provider-py
Of course, there are many other things that must be handled in production:
- Security of the infrastructure where the software is running
- Monitoring
- Log aggregation, storage, and search
- Handling crashes or other faults
Each of those is beyond the scope of these docs.
[Launch a blockchain-based data marketplace in under 1 hour](https://blog.oceanprotocol.com/launch-a-blockchain-based-data-marketplace-in-under-1-hour-9baa85a65ece)

View File

@ -2,7 +2,8 @@
title: Set Up On-Premise Storage
description: Tutorial about how to set up on-premise storage for use with Ocean.
---
*Note: This needs updating for Ocean V3.*
_Note: This needs updating for Ocean V3._
To enable Provider to use files stored in on-premise storage (i.e. files with an URL not containing `core.windows.net` or `s3://`), there is _nothing to do, other than make sure Provider can resolve the URLs_. In particular, you don't have to set any Provider-specific configuration settings, e.g. in the `[osmosis]` section of the Provider config file or in some special Provider environment variables.

View File

@ -6,27 +6,27 @@
link: /concepts/quickstart/
- title: Architecture Overview
link: /concepts/architecture/
- title: Data NFT and Datatoken
link: /concepts/datanft-and-datatoken/
- title: Roles
link: /concepts/roles/
- title: Supported Networks
link: /concepts/networks/
- title: Deployments
link: /concepts/deployments/
- title: Projects using Ocean
link: /concepts/projects-using-ocean/
- group: Compute-to-Data
items:
- title: Introduction
- title: Overview
link: /concepts/compute-to-data/
- group: Specifying Assets
items:
- title: DIDs & DDOs
- title: DID & DDO
link: /concepts/did-ddo/
- title: DDO Metadata
link: /concepts/ddo-metadata/
- group: Contribute
items:
- title: Projects using Ocean
link: /concepts/projects-using-ocean/
- title: Ways to Contribute
link: /concepts/contributing/
- title: Get Funding

View File

@ -34,6 +34,8 @@
items:
- title: Set Up a Marketplace
link: /tutorials/marketplace/
- title: Fees
link: /tutorials/marketplace-fees/
- group: Compute-to-Data
items:

View File

@ -1,8 +1,8 @@
# API References
- [Overview](#Overview)
- [Swagger specs](#Swagger-specs)
- [TypeDoc specs](#TypeDoc-specs)
- [Overview](#overview)
- [Swagger specs](#swagger-specs)
- [TypeDoc specs](#typedoc-specs)
## Overview

View File

@ -1,8 +1,8 @@
# GitHub Data Fetching
- [Overview](#Overview)
- [GitHub GraphQL API](#GitHub-GraphQL-API)
- [GitHub REST API](#GitHub-REST-API)
- [Overview](#overview)
- [GitHub GraphQL API](#github-graphql-api)
- [GitHub REST API](#github-rest-api)
## Overview
@ -22,8 +22,7 @@ For local development, you can simply [create a personal access token](https://g
```bash
cp .env.sample .env
vi .env
# GITHUB_TOKEN=add_your_token_here
vi .env # GITHUB_TOKEN=add_your_token_here
```
An alternative to typing the above code is to just create a .env file and add this line `GITHUB_TOKEN=add_your_token_here` in it. Do not put your token in quotes.

View File

@ -155,19 +155,19 @@ module.exports = {
options: {
name: 'repo-read-the-docs',
remote: `https://github.com/oceanprotocol/readthedocs.git`,
local: 'markdowns/',
branch: 'main',
local: 'read-the-docs',
branch: 'v4',
patterns: [
'markdowns/ocean-py',
'markdowns/aquarius',
'markdowns/provider'
'read-the-docs/ocean-py',
'read-the-docs/aquarius',
'read-the-docs/provider'
]
}
},
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/markdowns/markdowns`,
path: `${__dirname}/read-the-docs/markdowns`,
name: 'markdowns'
}
},

View File

@ -59,7 +59,9 @@ exports.createPages = ({ graphql, actions }) => {
}
allRepoMarkdown: allMarkdownRemark(
filter: { fileAbsolutePath: { regex: "/markdowns/markdowns/" } }
filter: {
fileAbsolutePath: { regex: "/read-the-docs/markdowns/" }
}
) {
edges {
node {
@ -103,6 +105,62 @@ exports.createPages = ({ graphql, actions }) => {
}
}
}
aquariusRestApi: allMarkdownRemark(
filter: {
frontmatter: {
title: { eq: "API.md" }
app: { eq: "aquarius" }
}
}
) {
edges {
node {
id
html
htmlAst
tableOfContents
frontmatter {
title
description
slug
section
app
module
source
version
}
}
}
}
providerRestApi: allMarkdownRemark(
filter: {
frontmatter: {
title: { eq: "API.md" }
app: { eq: "provider" }
}
}
) {
edges {
node {
id
html
htmlAst
tableOfContents
frontmatter {
title
description
slug
section
app
module
source
version
}
}
}
}
}
`
).then(async (result) => {
@ -135,10 +193,7 @@ exports.createPages = ({ graphql, actions }) => {
// API: ocean.js
const lastRelease =
result.data.oceanJs.repository.releases.edges.filter(
({ node }) =>
!node.isPrerelease &&
!node.isDraft &&
node.releaseAssets.edges.length > 0
({ node }) => !node.isDraft && node.releaseAssets.edges.length > 0
)[0].node.releaseAssets.edges[0].node
await createTypeDocPage(
@ -165,6 +220,21 @@ exports.createPages = ({ graphql, actions }) => {
const providerList = filterMarkdownList(markdowns, 'provider')
const subgraphList = filterMarkdownList(markdowns, 'ocean-subgraph')
const aquariusRestApi = result.data.aquariusRestApi.edges[0].node
await createRestApiPage(
createPage,
aquariusRestApi,
`/references/aquarius`
)
const providerRestApi = result.data.providerRestApi.edges[0].node
await createRestApiPage(
createPage,
providerRestApi,
`/references/provider`
)
await createReadTheDocsPage(createPage, 'ocean-py', oceanPyList)
await createReadTheDocsPage(createPage, 'provider', providerList)
await createReadTheDocsPage(createPage, 'ocean-subgraph', subgraphList)
@ -292,3 +362,22 @@ const createReadTheDocsPage = async (createPage, name, list) => {
const filterMarkdownList = (markdownList, string) => {
return markdownList.filter(({ node }) => node.frontmatter.app === string)
}
const createRestApiPage = async (createPage, node, slug) => {
const template = path.resolve('./src/templates/RestApi.jsx')
createPage({
path: slug,
component: template,
context: {
node,
slug
}
})
}
// const getRestApiPageFromMarkdownList = (markdownList, string) => {
// return markdownList.filter(
// ({ node }) =>
// node.frontmatter.app === string && node.frontmatter.slug === 'API.md'
// )
// }

459
package-lock.json generated
View File

@ -3177,18 +3177,6 @@
"strip-json-comments": "^3.1.1"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"globals": {
"version": "13.11.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz",
@ -3573,10 +3561,7 @@
"cross-fetch": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
"requires": {
"node-fetch": "2.6.1"
}
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ=="
},
"form-data": {
"version": "4.0.0",
@ -5158,9 +5143,9 @@
}
},
"ajv": {
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@ -5195,34 +5180,44 @@
"integrity": "sha512-4g5Np4CVD3c5c/36Mj0jllEA5bQcuXF0dqakZcuHGeubBzw93EAhwRuQCzgFm4/ZwvyBMzFdtn9BcihOjnxIdQ=="
},
"ansi-align": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
"integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
"integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==",
"requires": {
"string-width": "^3.0.0"
"string-width": "^4.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"requires": {
"ansi-regex": "^4.1.0"
"ansi-regex": "^5.0.1"
}
}
}
@ -5798,11 +5793,18 @@
"integrity": "sha512-1uIESzroqpaTzt9uX48HO+6gfnKu3RwvWdCcWSrX4csMInJfCo1yvKPNXCwXFRpJqRW25tiASb6No0YH57PXqg=="
},
"axios": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
"requires": {
"follow-redirects": "^1.14.7"
"follow-redirects": "^1.14.8"
},
"dependencies": {
"follow-redirects": {
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
}
}
},
"axobject-query": {
@ -6581,8 +6583,7 @@
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"resolved": ""
},
"ansi-styles": {
"version": "4.3.0",
@ -6996,9 +6997,9 @@
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
},
"normalize-url": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ=="
"version": "4.5.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
"integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA=="
}
}
},
@ -7804,8 +7805,7 @@
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"resolved": ""
},
"ansi-styles": {
"version": "4.3.0",
@ -8040,6 +8040,13 @@
"integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==",
"requires": {
"node-fetch": "2.6.1"
},
"dependencies": {
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
}
}
},
"cross-spawn": {
@ -9570,9 +9577,9 @@
}
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
},
"astral-regex": {
@ -9870,9 +9877,9 @@
},
"dependencies": {
"ajv": {
"version": "8.6.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
"integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@ -9989,9 +9996,9 @@
}
},
"glob-parent": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
@ -11394,9 +11401,9 @@
}
},
"follow-redirects": {
"version": "1.14.7",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ=="
"version": "1.14.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz",
"integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w=="
},
"for-in": {
"version": "1.0.2",
@ -11791,8 +11798,7 @@
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"resolved": ""
},
"strip-ansi": {
"version": "6.0.0",
@ -12182,6 +12188,14 @@
"signal-exit": "^3.0.2",
"strip-final-newline": "^2.0.0"
}
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
}
}
},
@ -12467,8 +12481,7 @@
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"resolved": ""
},
"strip-ansi": {
"version": "6.0.0",
@ -12538,8 +12551,7 @@
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"resolved": ""
},
"ansi-styles": {
"version": "4.3.0",
@ -13355,9 +13367,9 @@
}
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"debug": {
"version": "4.3.1",
@ -14661,9 +14673,9 @@
}
},
"glob-parent": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"requires": {
"is-glob": "^4.0.1"
}
@ -15973,9 +15985,9 @@
}
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "4.2.1",
@ -16834,9 +16846,9 @@
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
"integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
"dev": true
},
"json-schema-traverse": {
@ -16887,14 +16899,14 @@
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
"integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
"dev": true,
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"json-schema": "0.4.0",
"verror": "1.10.0"
}
},
@ -17152,12 +17164,6 @@
"resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz",
"integrity": "sha1-3bG7s+8HRYwBd7oH3hRCLLAz/5s="
},
"lodash.differencewith": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.differencewith/-/lodash.differencewith-4.5.0.tgz",
"integrity": "sha1-uvr7yRi1UVTheRdqALsK76rIVLc=",
"dev": true
},
"lodash.every": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-4.6.0.tgz",
@ -17398,9 +17404,9 @@
"integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg=="
},
"markdown-it": {
"version": "12.2.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.2.0.tgz",
"integrity": "sha512-Wjws+uCrVQRqOoJvze4HCqkKl1AsSh95iFAeQDwnyfxM09divCBSXlDR1uTvyUP3Grzpn4Ru8GeCxYPM8vkCQg==",
"version": "12.3.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
"integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
"dev": true,
"requires": {
"argparse": "^2.0.1",
@ -17433,33 +17439,29 @@
}
},
"markdownlint": {
"version": "0.24.0",
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.24.0.tgz",
"integrity": "sha512-OJIGsGFV/rC9irI5E1FMy6v9hdACSwaa+EN3224Y5KG8zj2EYzdHOw0pOJovIYmjNfEZ9BtxUY4P7uYHTSNnbQ==",
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz",
"integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==",
"dev": true,
"requires": {
"markdown-it": "12.2.0"
"markdown-it": "12.3.2"
}
},
"markdownlint-cli": {
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.30.0.tgz",
"integrity": "sha512-NiG8iERjwsRZtJAIyLMDdYL2O3bJVn3fUxzDl+6Iv61/YYz9H9Nzgke/v0/cW9HfGvgZHhbfI19LFMp6gbKdyw==",
"version": "0.31.1",
"resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.1.tgz",
"integrity": "sha512-keIOMwQn+Ch7MoBwA+TdkyVMuxAeZFEGmIIlvwgV0Z1TGS5MxPnRr29XCLhkNzCHU+uNKGjU+VEjLX+Z9kli6g==",
"dev": true,
"requires": {
"commander": "~8.3.0",
"deep-extend": "~0.6.0",
"get-stdin": "~8.0.0",
"commander": "~9.0.0",
"get-stdin": "~9.0.0",
"glob": "~7.2.0",
"ignore": "~5.1.9",
"ignore": "~5.2.0",
"js-yaml": "^4.1.0",
"jsonc-parser": "~3.0.0",
"lodash.differencewith": "~4.5.0",
"lodash.flatten": "~4.4.0",
"markdownlint": "~0.24.0",
"markdownlint-rule-helpers": "~0.15.0",
"minimatch": "~3.0.4",
"minimist": "~1.2.5",
"markdownlint": "~0.25.1",
"markdownlint-rule-helpers": "~0.16.0",
"minimatch": "~3.0.5",
"run-con": "~1.2.10"
},
"dependencies": {
@ -17470,15 +17472,15 @@
"dev": true
},
"commander": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
"integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==",
"dev": true
},
"get-stdin": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
"integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
"integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
"dev": true
},
"glob": {
@ -17496,9 +17498,9 @@
}
},
"ignore": {
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz",
"integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
"dev": true
},
"js-yaml": {
@ -17509,13 +17511,22 @@
"requires": {
"argparse": "^2.0.1"
}
},
"minimatch": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
"integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
}
}
},
"markdownlint-rule-helpers": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.15.0.tgz",
"integrity": "sha512-A+9mswc3m/kkqpJCqntmte/1VKhDJ+tjZsERLz5L4h/Qr7ht2/BkGkgY5E7/wsxIhcpl+ctIfz+oS3PQrMOB2w==",
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz",
"integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==",
"dev": true
},
"md5-file": {
@ -18364,9 +18375,9 @@
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"minipass": {
"version": "3.1.3",
@ -18508,13 +18519,12 @@
}
},
"mozjpeg": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-7.0.0.tgz",
"integrity": "sha512-mH7atSbIusVTO3A4H43sEdmveN3aWn54k6V0edefzCEvOsTrbjg5murY2TsNznaztWnIgaRbWxeLVp4IgKdedQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/mozjpeg/-/mozjpeg-7.1.1.tgz",
"integrity": "sha512-iIDxWvzhWvLC9mcRJ1uSkiKaj4drF58oCqK2bITm5c2Jt6cJ8qQjSSru2PCaysG+hLIinryj8mgz5ZJzOYTv1A==",
"requires": {
"bin-build": "^3.0.0",
"bin-wrapper": "^4.0.0",
"logalot": "^2.1.0"
"bin-wrapper": "^4.0.0"
}
},
"ms": {
@ -18682,9 +18692,12 @@
"integrity": "sha1-n7CwmbzSoCGUDmA8ZCVNwAPZp6g="
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"node-forge": {
"version": "0.10.0",
@ -19826,6 +19839,11 @@
"resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz",
"integrity": "sha1-GN4vl+S/epVRrXURlCtUlverpmA="
},
"picocolors": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz",
"integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="
},
"picomatch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
@ -19872,9 +19890,9 @@
}
},
"plist": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.4.tgz",
"integrity": "sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg==",
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz",
"integrity": "sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==",
"requires": {
"base64-js": "^1.5.1",
"xmlbuilder": "^9.0.7"
@ -19950,27 +19968,18 @@
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
},
"postcss": {
"version": "7.0.35",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
"integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
"version": "7.0.39",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz",
"integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==",
"requires": {
"chalk": "^2.4.2",
"source-map": "^0.6.1",
"supports-color": "^6.1.0"
"picocolors": "^0.2.1",
"source-map": "^0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"supports-color": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
"integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
@ -20650,9 +20659,9 @@
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
},
"simple-get": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz",
"integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==",
"requires": {
"decompress-response": "^4.2.0",
"once": "^1.3.1",
@ -20673,9 +20682,9 @@
"integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
},
"prettier": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg=="
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.1.tgz",
"integrity": "sha512-8UVbTBYGwN37Bs9LERmxCPjdvPxlEowx2urIL6urHzdb3SDq4B/Z6xLFCblrSnE4iKWcS6ziJ3aOYrc1kz/E2A=="
},
"prettier-linter-helpers": {
"version": "1.0.0",
@ -20719,9 +20728,9 @@
},
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "4.3.0",
@ -22047,21 +22056,85 @@
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
},
"renderkid": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz",
"integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==",
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.7.tgz",
"integrity": "sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==",
"requires": {
"css-select": "^2.0.2",
"dom-converter": "^0.2",
"htmlparser2": "^3.10.1",
"lodash": "^4.17.20",
"strip-ansi": "^3.0.0"
"css-select": "^4.1.3",
"dom-converter": "^0.2.0",
"htmlparser2": "^6.1.0",
"lodash": "^4.17.21",
"strip-ansi": "^3.0.1"
},
"dependencies": {
"lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
"css-select": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
"integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
"requires": {
"boolbase": "^1.0.0",
"css-what": "^6.0.1",
"domhandler": "^4.3.1",
"domutils": "^2.8.0",
"nth-check": "^2.0.1"
}
},
"css-what": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.0.1.tgz",
"integrity": "sha512-z93ZGFLNc6yaoXAmVhqoSIb+BduplteCt1fepvwhBUQK6MNE4g6fgjpuZKJKp0esUe+vXWlIkwZZjNWoOKw0ZA=="
},
"dom-serializer": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
}
},
"domelementtype": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
},
"domhandler": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
"integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
"requires": {
"domelementtype": "^2.2.0"
}
},
"domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"requires": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
}
},
"htmlparser2": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"domutils": "^2.5.2",
"entities": "^2.0.0"
}
},
"nth-check": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
"requires": {
"boolbase": "^1.0.0"
}
}
}
},
@ -22532,17 +22605,6 @@
"semver": "^7.3.2"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"schema-utils": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
@ -22585,19 +22647,6 @@
"@types/json-schema": "^7.0.5",
"ajv": "^6.12.4",
"ajv-keywords": "^3.5.2"
},
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
}
}
},
"scss-tokenizer": {
@ -22940,9 +22989,9 @@
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
},
"simple-get": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.0.tgz",
"integrity": "sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ==",
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"requires": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
@ -24994,8 +25043,7 @@
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"resolved": ""
},
"ansi-styles": {
"version": "4.3.0",
@ -25183,9 +25231,9 @@
}
},
"url-parse": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
@ -26451,11 +26499,11 @@
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
},
"wide-align": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
"requires": {
"string-width": "^1.0.2 || 2"
"string-width": "^1.0.2 || 2 || 3 || 4"
}
},
"widest-line": {
@ -26468,8 +26516,7 @@
"dependencies": {
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
"resolved": ""
},
"emoji-regex": {
"version": "8.0.0",

View File

@ -10,14 +10,14 @@
"ssr": "npm run build && serve -s public/",
"format": "prettier --ignore-path .gitignore './**/*.{css,scss,yml,js,jsx,ts,tsx,json}' --write",
"lint:js": "eslint --ignore-path .gitignore --ignore-path .prettierignore --ext .js,.jsx .",
"lint:md": "markdownlint './**/*.{md,markdown}' --ignore './{node_modules,external,public,.cache,markdowns}/**/*'",
"lint:md": "markdownlint './**/*.{md,markdown}' --ignore './{node_modules,external,public,.cache,markdowns,read-the-docs}/**/*'",
"lint:yml": "prettier '**/*.{yml,yaml}' --list-different",
"lint": "run-p --continue-on-error lint:js lint:md lint:yml",
"test": "npm run lint"
},
"dependencies": {
"@oceanprotocol/art": "^3.2.0",
"axios": "^0.25.0",
"axios": "^0.26.1",
"classnames": "^2.3.1",
"gatsby": "^2.32.13",
"gatsby-image": "^3.11.0",
@ -73,10 +73,10 @@
"eslint-plugin-prettier": "^4.0.0",
"git-format-staged": "^2.1.3",
"husky": "^7.0.4",
"markdownlint-cli": "^0.30.0",
"markdownlint-cli": "^0.31.1",
"node-sass": "^5.0.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.5.1"
"prettier": "^2.6.1"
},
"repository": {
"type": "git",

View File

@ -3,6 +3,7 @@ import { Link, StaticQuery, graphql } from 'gatsby'
import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
import styles from './Header.module.scss'
import SearchButton from './Search/SearchButton'
import ToggleSwitch from './ToggleSwitch'
const query = graphql`
query {
@ -51,6 +52,9 @@ const Header = () => (
<div className={styles.section}>
<SearchButton />
</div>
<div className={styles.section}>
<ToggleSwitch />
</div>
</nav>
</div>
</header>

View File

@ -4,6 +4,7 @@ import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
import Content from '../components/Content'
import styles from './HeaderHome.module.scss'
import SearchButton from '../components/Search/SearchButton'
import ToggleSwitch from './ToggleSwitch'
const HeaderHome = () => (
<StaticQuery
@ -27,9 +28,14 @@ const HeaderHome = () => (
<h1 className={styles.headerTitle}>{siteTitle}</h1>
<p className={styles.headerDescription}>
{siteDescription}
<div className={styles.searchButtonContainer}>
<div className={styles.container}>
<SearchButton />
</div>
<div className={styles.container}>
<div style={{ display: 'inline-block' }}>
<ToggleSwitch />
</div>
</div>
</p>
</Content>
</header>

View File

@ -47,6 +47,7 @@
}
}
.searchButtonContainer {
margin-top: $spacer * 0.5 ;
.container {
margin-top: $spacer * 0.5;
align-items: 'center';
}

View File

@ -0,0 +1,23 @@
import React from 'react'
import styles from './ToggleSwitch.module.scss'
const ToggleSwitch = () => {
return (
<div className={styles.switchButton}>
<input
className={styles.switchButtonCheckbox}
type="checkbox"
onClick={() => {
if (window) {
window.open('https://v3.docs.oceanprotocol.com/', '_self')
}
}}
/>
<label className={styles.switchButtonLabel} htmlFor="">
<span className={styles.switchButtonLabelSpan}>v4</span>
</label>
</div>
)
}
export default ToggleSwitch

View File

@ -0,0 +1,69 @@
@import 'variables';
.switchButton {
background: rgba(255, 255, 255, 0.56);
border-radius: 0.5rem;
overflow: hidden;
width: $spacer * 4;
text-align: center;
font-size: $font-size-base;
letter-spacing: 1px;
color: $brand-purple;
position: relative;
padding-right: $spacer * 2;
&:before {
content: 'v3';
position: absolute;
top: 0;
bottom: 0;
right: 0;
width: $spacer * 2;
display: flex;
align-items: center;
justify-content: center;
z-index: 3;
pointer-events: none;
}
&Checkbox {
cursor: pointer;
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 100%;
height: 100%;
opacity: 0;
&:checked + .switchButtonLabel:before {
transform: translateX($spacer * 2);
transition: transform 300ms linear;
}
& + .switchButtonLabel {
position: relative;
padding: 0 0;
display: block;
user-select: none;
pointer-events: none;
&:before {
content: '';
background: $brand-grey-lighter;
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
border-radius: 0.5rem;
transform: translateX(0);
transition: transform 300ms;
}
.switchButtonLabelSpan {
position: relative;
}
}
}
}

View File

@ -68,4 +68,4 @@ $narrowWidth: 35rem;
$box-shadow-color: rgba(0, 0, 0, 0.2);
$border-color: #e2e2e2;
$background-content: #fff;
$background-content: #fff;

View File

@ -1,23 +1,23 @@
@import 'variables';
.box {
display: block;
background: $background-content;
border-radius: $border-radius;
border: 1px solid $border-color;
box-shadow: 0 6px 17px 0 $box-shadow-color;
padding: $spacer * 0.5;
}
@media (min-width: 40rem) {
.box {
padding: var($spacer);
}
}
a.box:hover,
a.box:focus {
outline: 0;
transform: translate3d(0, -0.1rem, 0);
box-shadow: 0 10px 25px 0 $box-shadow-color;
display: block;
background: $background-content;
border-radius: $border-radius;
border: 1px solid $border-color;
box-shadow: 0 6px 17px 0 $box-shadow-color;
padding: $spacer * 0.5;
}
@media (min-width: 40rem) {
.box {
padding: var($spacer);
}
}
a.box:hover,
a.box:focus {
outline: 0;
transform: translate3d(0, -0.1rem, 0);
box-shadow: 0 10px 25px 0 $box-shadow-color;
}

View File

@ -118,7 +118,7 @@ export const pageQuery = graphql`
query DocBySlug($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
id
tableOfContents(maxDepth: 2)
tableOfContents(maxDepth: 3)
html
htmlAst
frontmatter {

49
src/templates/RestApi.jsx Normal file
View File

@ -0,0 +1,49 @@
import React from 'react'
import { Helmet } from 'react-helmet'
import Layout from '../components/Layout'
import Content from '../components/Content'
import HeaderSection from '../components/HeaderSection'
import Sidebar from '../components/Sidebar'
import stylesDoc from '../templates/Doc.module.scss'
import Seo from '../components/Seo'
import DocContent from '../components/DocContent'
import PropTypes from 'prop-types'
export default function RestApiDoc({ location, pageContext }) {
const { node, slug } = pageContext
return (
<>
<Helmet>
<body className="references" />
</Helmet>
<Seo
title="Rest api documentation"
description=""
slug={slug}
article
location={location}
/>
<Layout location={location}>
<HeaderSection title="Rest Api documentation" />
<Content>
<main className={stylesDoc.wrapper}>
<aside className={stylesDoc.sidebar}>
{/* Add sidebar */}
<Sidebar location={location} sidebar="references" collapsed />
</aside>
<article className={stylesDoc.main}>
<DocContent html={node.html} htmlAst={node.htmlAst} />
</article>
</main>
</Content>
</Layout>
</>
)
}
RestApiDoc.propTypes = {
location: PropTypes.object.isRequired,
pageContext: PropTypes.object.isRequired
}