├── .github
├── 180protocol-logo-dark.png
├── 180protocol-logo.svg
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── feature_request.md
│ └── use-case.md
├── .gitignore
├── 180Dashboard
├── Dockerfile
├── LICENSE
├── package-lock.json
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── assets
│ ├── fonts
│ │ └── muli
│ │ │ ├── Muli-Black.woff
│ │ │ ├── Muli-BlackItalic.woff
│ │ │ ├── Muli-Bold.woff
│ │ │ ├── Muli-BoldItalic.woff
│ │ │ ├── Muli-ExtraBold.woff
│ │ │ ├── Muli-ExtraBoldItalic.woff
│ │ │ ├── Muli-ExtraLight.woff
│ │ │ ├── Muli-ExtraLightItalic.woff
│ │ │ ├── Muli-Italic.woff
│ │ │ ├── Muli-Light.woff
│ │ │ ├── Muli-LightItalic.woff
│ │ │ ├── Muli-Regular.woff
│ │ │ ├── Muli-SemiBold.woff
│ │ │ ├── Muli-SemiBoldItalic.woff
│ │ │ └── stylesheet.css
│ └── images
│ │ ├── dashboard.svg
│ │ ├── download.svg
│ │ ├── export.svg
│ │ ├── login_bg.png
│ │ ├── login_icn.svg
│ │ ├── logo.png
│ │ ├── logout_active.svg
│ │ ├── notification.svg
│ │ ├── refresh.svg
│ │ ├── right_angle_arrow.svg
│ │ ├── select-down-arrow.svg
│ │ ├── upload.svg
│ │ └── user.svg
│ ├── components
│ ├── AlertBox.js
│ ├── AppRoute.js
│ ├── Chart.js
│ └── Grid.js
│ ├── containers
│ ├── FormikFields.js
│ └── navs
│ │ ├── Footer
│ │ ├── Footer.jsx
│ │ ├── Footer.module.scss
│ │ └── index.js
│ │ ├── Header
│ │ ├── Header.jsx
│ │ ├── Header.module.scss
│ │ └── index.js
│ │ └── Menu
│ │ ├── Menu.jsx
│ │ ├── Menu.module.scss
│ │ └── index.js
│ ├── index.css
│ ├── index.js
│ ├── layout
│ ├── AppLayout.js
│ └── UserLayout.js
│ ├── reportWebVitals.js
│ ├── setupTests.js
│ ├── store
│ ├── actions.js
│ ├── auth
│ │ ├── actions.js
│ │ └── reducer.js
│ ├── consumer
│ │ ├── actions.js
│ │ └── reducer.js
│ ├── context.js
│ ├── provider
│ │ ├── actions.js
│ │ └── reducer.js
│ ├── reducers.js
│ └── store.js
│ ├── userInfo.yml
│ ├── utils
│ ├── helpers.js
│ └── history.js
│ └── views
│ ├── app
│ ├── consumer
│ │ ├── Dashboard
│ │ │ ├── Dashboard.jsx
│ │ │ ├── Dashboard.module.scss
│ │ │ └── index.js
│ │ └── index.js
│ ├── index.js
│ └── provider
│ │ ├── Data
│ │ ├── Data.jsx
│ │ ├── Data.module.scss
│ │ └── index.js
│ │ ├── Rewards
│ │ ├── Rewards.jsx
│ │ ├── Rewards.module.scss
│ │ └── index.js
│ │ └── index.js
│ ├── error.js
│ ├── index.js
│ └── user
│ ├── Login
│ ├── Login.jsx
│ ├── Login.module.scss
│ └── index.js
│ └── index.js
├── README.md
├── compose-codaptor.yml
├── compose-corda-network.yml
├── examples
├── automotive-example
│ ├── LICENCE
│ ├── README.md
│ ├── TRADEMARK
│ ├── build.gradle
│ ├── compose-codaptor.yml
│ ├── compose-corda-network.yml
│ ├── config
│ │ ├── dev
│ │ │ └── log4j2.xml
│ │ └── test
│ │ │ └── log4j2.xml
│ ├── constants.properties
│ ├── enclave
│ │ ├── build.gradle
│ │ ├── sample_private_key.pem
│ │ └── src
│ │ │ ├── main
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ │ └── protocol180
│ │ │ │ │ └── samples
│ │ │ │ │ └── example
│ │ │ │ │ └── aggregator
│ │ │ │ │ └── clientEnclave
│ │ │ │ │ └── ExampleAggregationEnclave.java
│ │ │ └── resources
│ │ │ │ ├── META-INF
│ │ │ │ └── native-image
│ │ │ │ │ ├── filter.json
│ │ │ │ │ ├── jni-config.json
│ │ │ │ │ ├── native-image.properties
│ │ │ │ │ ├── proxy-config.json
│ │ │ │ │ ├── reflect-config.json
│ │ │ │ │ ├── resource-config.json
│ │ │ │ │ └── serialization-config.json
│ │ │ │ └── trustedroot.cer
│ │ │ └── test
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── protocol180
│ │ │ │ └── samples
│ │ │ │ └── example
│ │ │ │ └── aggregator
│ │ │ │ └── clientEnclave
│ │ │ │ └── ExampleAggregationEnclaveTest.java
│ │ │ └── resources
│ │ │ ├── AutomotiveMarketResearchSampleData.csv
│ │ │ └── automotive.avsc
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── repositories.gradle
│ ├── settings.gradle
│ └── workflows
│ │ ├── build.gradle
│ │ └── src
│ │ └── test
│ │ ├── kotlin
│ │ └── com
│ │ │ └── protocol180
│ │ │ └── samples
│ │ │ └── example
│ │ │ ├── ExampleAggregationFlowTest.kt
│ │ │ └── ExampleEstuaryStorageAggregationFlowTest.kt
│ │ └── resources
│ │ ├── Provider1InputData.csv
│ │ ├── Provider1InputData.zip
│ │ ├── Provider2InputData.csv
│ │ ├── Provider2InputData.zip
│ │ ├── testSchema1.avsc
│ │ └── testSchema2.avsc
└── hotel-bookings
│ ├── LICENCE
│ ├── README.md
│ ├── TRADEMARK
│ ├── build.gradle
│ ├── compose-codaptor.yml
│ ├── compose-corda-network.yml
│ ├── config
│ ├── dev
│ │ └── log4j2.xml
│ └── test
│ │ └── log4j2.xml
│ ├── constants.properties
│ ├── enclave
│ ├── build.gradle
│ ├── sample_private_key.pem
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── protocol180
│ │ │ │ └── aggregator
│ │ │ │ └── sample
│ │ │ │ └── ExampleAggregationEnclave.java
│ │ └── resources
│ │ │ ├── META-INF
│ │ │ └── native-image
│ │ │ │ ├── filter.json
│ │ │ │ ├── jni-config.json
│ │ │ │ ├── native-image.properties
│ │ │ │ ├── proxy-config.json
│ │ │ │ ├── reflect-config.json
│ │ │ │ ├── resource-config.json
│ │ │ │ └── serialization-config.json
│ │ │ └── trustedroot.cer
│ │ └── test
│ │ ├── java
│ │ └── com
│ │ │ └── protocol180
│ │ │ └── aggregator
│ │ │ └── sample
│ │ │ └── ExampleAggregationEnclaveTest.java
│ │ └── resources
│ │ ├── HotelBookingsSampleData.csv
│ │ └── hotelBookings.avsc
│ ├── gradle.properties
│ ├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── repositories.gradle
│ ├── settings.gradle
│ └── workflows
│ ├── build.gradle
│ └── src
│ └── test
│ ├── kotlin
│ └── com
│ │ └── protocol180
│ │ └── aggregator
│ │ └── sample
│ │ └── ExampleAggregationFlowTest.kt
│ └── resources
│ ├── Provider1InputData.csv
│ ├── Provider1InputData.zip
│ ├── Provider2InputData.csv
│ ├── Provider2InputData.zip
│ ├── testSchema1.avsc
│ └── testSchema2.avsc
└── protocolAggregator
├── .gitignore
├── LICENCE
├── README.md
├── build.gradle
├── certificates
├── dump-cordarootca.sh
└── truststore.jks
├── config
├── dev
│ └── log4j2.xml
└── test
│ └── log4j2.xml
├── constants.properties
├── contracts
├── build.gradle
└── src
│ └── main
│ └── kotlin
│ └── com
│ └── protocol180
│ └── aggregator
│ ├── contracts
│ ├── CoalitionConfigurationContract.kt
│ ├── DataOutputContract.kt
│ └── RewardsContract.kt
│ ├── schema
│ ├── ConsumerAggregationDataOutputSchema.kt
│ ├── DecentralizedStorageEncryptionKeySchema.kt
│ ├── ProviderAggregationInputSchema.kt
│ ├── ProviderInputSchema.kt
│ └── ProviderRewardSchema.kt
│ └── states
│ ├── CoalitionConfigurationState.kt
│ ├── DataOutputState.kt
│ └── RewardsState.kt
├── enclave
├── build.gradle
├── sample_private_key.pem
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── protocol180
│ │ └── aggregator
│ │ ├── commons
│ │ └── MailType.java
│ │ └── enclave
│ │ └── AggregationEnclave.java
│ └── resources
│ ├── META-INF
│ └── native-image
│ │ ├── filter.json
│ │ ├── jni-config.json
│ │ ├── native-image.properties
│ │ ├── proxy-config.json
│ │ ├── reflect-config.json
│ │ ├── resource-config.json
│ │ └── serialization-config.json
│ └── trustedroot.cer
├── estuaryStorage
├── build.gradle
├── shadowJar
│ └── build.gradle
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── protocol180
│ │ │ └── aggregator
│ │ │ └── storage
│ │ │ ├── estuary
│ │ │ └── EstuaryStorageService.java
│ │ │ ├── keyVault
│ │ │ └── AzureKeyVaultService.java
│ │ │ └── utils
│ │ │ └── AESUtil.java
│ └── kotlin
│ │ └── com
│ │ └── protocol180
│ │ └── aggregator
│ │ └── storage
│ │ └── flow
│ │ ├── DecentralizedStorageEncryptionKeyRetrievalFlow.kt
│ │ ├── DecentralizedStorageEncryptionKeyService.kt
│ │ ├── DecentralizedStorageEncryptionKeyUpdateFlow.kt
│ │ ├── EstauryStorageProviderAggregationInputFlow.kt
│ │ ├── EstuaryStorageConsumerAggregationFlow.kt
│ │ ├── EstuaryStorageConsumerDataOutputRetrievalFlow.kt
│ │ └── EstuaryStorageProviderAggregationResponseFlow.kt
│ └── test
│ ├── java
│ └── com
│ │ └── protocol180
│ │ └── aggregator
│ │ └── storage
│ │ └── keyVault
│ │ └── AzureKeyVaultServiceTest.java
│ ├── kotlin
│ └── com
│ │ └── protocol180
│ │ └── aggregator
│ │ └── storage
│ │ └── flow
│ │ ├── DecentralizedStorageEncryptionKeyTest.kt
│ │ ├── EstuaryStorageConsumerAggregationFlowTest.kt
│ │ ├── EstuaryStorageFlow.kt
│ │ └── EstuaryStorageFlowTest.kt
│ └── resources
│ ├── Provider1InputData.csv
│ ├── Provider1InputData.zip
│ ├── Provider2InputData.csv
│ ├── Provider2InputData.zip
│ └── testSchema1.avsc
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── repositories.gradle
├── sampleEnclave
├── build.gradle
├── sample_private_key.pem
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── protocol180
│ │ └── aggregator
│ │ └── sample
│ │ └── ExampleAggregationEnclave.java
│ └── resources
│ ├── META-INF
│ └── native-image
│ │ ├── filter.json
│ │ ├── jni-config.json
│ │ ├── native-image.properties
│ │ ├── proxy-config.json
│ │ ├── reflect-config.json
│ │ ├── resource-config.json
│ │ └── serialization-config.json
│ └── trustedroot.cer
├── settings.gradle
└── workflows
├── build.gradle
└── src
├── main
├── java
│ └── com
│ │ └── protocol180
│ │ └── aggregator
│ │ └── flow
│ │ └── EnclaveHostService.java
├── kotlin
│ └── com
│ │ └── protocol180
│ │ └── aggregator
│ │ └── flow
│ │ ├── CoalitionConfigurationStateService.kt
│ │ ├── CoalitionConfigurationUpdateFlow.kt
│ │ ├── ConsumerAggregationFlow.kt
│ │ ├── ConsumerDBStoreService.kt
│ │ ├── ConsumerDataOutputRetrievalFlow.kt
│ │ ├── EnclaveClientService.kt
│ │ ├── NetworkParticipantService.kt
│ │ ├── ProviderAggregationInputFlow.kt
│ │ ├── ProviderAggregationResponseFlow.kt
│ │ ├── ProviderDBStoreService.kt
│ │ └── ProviderRewardOutputRetrievalFlow.kt
└── resources
│ ├── envelope.avsc
│ ├── testSchema1.avsc
│ └── testSchema2.avsc
└── test
├── kotlin
└── com
│ └── protocol180
│ └── aggregator
│ └── flow
│ ├── CoalitionConfigurationTest.kt
│ └── ConsumerAggregationFlowTest.kt
└── resources
├── Provider1InputData.csv
├── Provider1InputData.zip
├── Provider2InputData.csv
├── Provider2InputData.zip
├── logging.xml
└── testSchema1.avsc
/.github/180protocol-logo-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/.github/180protocol-logo-dark.png
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/use-case.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Use case
3 | about: Potential use case for 180Protocol
4 | title: ''
5 | labels: use case
6 | assignees: ''
7 |
8 | ---
9 |
10 | # 180P Use Case Proposal: `Title`
11 |
12 | **Proposer:** `replace with your GitHub username`
13 |
14 | ## Business case
15 |
16 |
17 |
18 |
19 |
20 |
21 | ## Implementation details
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore Gradle project-specific cache directory
2 | **/.gradle
3 |
4 | # Ignore Gradle build output directory
5 | **/build
6 |
7 | .idea
8 | **/logs
9 | 180Dashboard/node_modules/**
10 | *.iml
11 |
12 | #Ignore docs
13 | protocolAggregator/github-docs/**
14 |
15 | etc
16 |
17 | #bin folders
18 | **/bin
19 | **/protocol180_0x1BDCF7ED_SECRET.pgp
--------------------------------------------------------------------------------
/180Dashboard/Dockerfile:
--------------------------------------------------------------------------------
1 | # The Node version that we'll be running for our version of React.
2 | # You may have to search the Node directory for a version that fits
3 | # the version of React you're using.
4 | FROM node:16-alpine
5 | # Create a work directory and copy over our dependency manifest files.
6 | RUN mkdir /app
7 | # Giving access to 'node' user for work directory
8 | RUN chown node:node /app
9 | USER node
10 | WORKDIR /app
11 | COPY --chown=node:node 180Dashboard/src /app/src
12 | COPY --chown=node:node ["180Dashboard/package.json", "180Dashboard/package-lock.json*", "./"]
13 | RUN CI=true
14 | RUN npm install --silent
15 | # Expose PORT 3000 on our virtual machine so we can run our server
16 | EXPOSE 3000
--------------------------------------------------------------------------------
/180Dashboard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "180-dashboard",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@devexpress/dx-react-core": "^2.7.6",
7 | "@devexpress/dx-react-grid": "^2.7.6",
8 | "@devexpress/dx-react-grid-bootstrap4": "^2.7.6",
9 | "@emotion/core": "^11.0.0",
10 | "@nivo/core": "^0.74.0",
11 | "@nivo/pie": "^0.74.0",
12 | "@testing-library/jest-dom": "^5.14.1",
13 | "@testing-library/react": "^11.2.7",
14 | "@testing-library/user-event": "^12.8.3",
15 | "bootstrap": "^5.1.3",
16 | "formik": "^2.2.9",
17 | "moment": "^2.29.1",
18 | "node-sass": "^6.0.1",
19 | "react": "^17.0.2",
20 | "react-dom": "^17.0.2",
21 | "react-dropzone": "^11.4.2",
22 | "react-popup-alert": "^2.0.0",
23 | "react-router-dom": "^5.3.0",
24 | "react-scripts": "4.0.3",
25 | "react-select": "^5.1.0",
26 | "react-spinners": "^0.13.3",
27 | "react-step-progress-bar": "^1.0.3",
28 | "web-vitals": "^1.1.2",
29 | "yamljs": "^0.3.0"
30 | },
31 | "scripts": {
32 | "start": "react-scripts start",
33 | "build": "react-scripts build",
34 | "test": "react-scripts test",
35 | "eject": "react-scripts eject"
36 | },
37 | "eslintConfig": {
38 | "extends": [
39 | "react-app",
40 | "react-app/jest"
41 | ]
42 | },
43 | "browserslist": {
44 | "production": [
45 | ">0.2%",
46 | "not dead",
47 | "not op_mini all"
48 | ],
49 | "development": [
50 | "last 1 chrome version",
51 | "last 1 firefox version",
52 | "last 1 safari version"
53 | ]
54 | },
55 | "devDependencies": {
56 | "miragejs": "^0.1.42"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/180Dashboard/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/public/favicon.ico
--------------------------------------------------------------------------------
/180Dashboard/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | 180 Dashboard
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/180Dashboard/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/public/logo192.png
--------------------------------------------------------------------------------
/180Dashboard/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/public/logo512.png
--------------------------------------------------------------------------------
/180Dashboard/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/180Dashboard/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/180Dashboard/src/App.js:
--------------------------------------------------------------------------------
1 | import React, {useEffect} from "react";
2 | import {BrowserRouter as Router, Switch, Route, Redirect} from "react-router-dom";
3 |
4 | import "bootstrap/dist/css/bootstrap.min.css";
5 | import "./App.css";
6 |
7 | import {history} from "./utils/history";
8 | import {AuthProvider} from "./store/context";
9 | import AppRoutes from "./components/AppRoute";
10 | import user from "./views/user";
11 | import app from "./views/app";
12 | import error from "./views/error";
13 | import main from "./views"
14 |
15 | const App = () => {
16 | return (
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | );
29 | };
30 |
31 | export default App;
32 |
--------------------------------------------------------------------------------
/180Dashboard/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-Black.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-Black.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-BlackItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-BlackItalic.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-Bold.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-BoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-BoldItalic.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-ExtraBold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-ExtraBold.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-ExtraBoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-ExtraBoldItalic.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-ExtraLight.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-ExtraLight.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-ExtraLightItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-ExtraLightItalic.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-Italic.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-Light.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-LightItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-LightItalic.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-Regular.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-SemiBold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-SemiBold.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/Muli-SemiBoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/fonts/muli/Muli-SemiBoldItalic.woff
--------------------------------------------------------------------------------
/180Dashboard/src/assets/fonts/muli/stylesheet.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Muli';
3 | font-style: normal;
4 | font-weight: normal;
5 | src: local('Muli Regular'), url('./Muli-Regular.woff') format('woff');
6 | }
7 |
8 |
9 | @font-face {
10 | font-family: 'Muli Light';
11 | font-style: normal;
12 | font-weight: normal;
13 | src: local('Muli Light'), url('./Muli-Light.woff') format('woff');
14 | }
15 |
16 | @font-face {
17 | font-family: 'Muli SemiBold';
18 | font-style: normal;
19 | font-weight: normal;
20 | src: local('Muli SemiBold'), url('./Muli-SemiBold.woff') format('woff');
21 | }
22 |
23 | @font-face {
24 | font-family: 'Muli Bold';
25 | font-style: normal;
26 | font-weight: normal;
27 | src: local('Muli Bold'), url('./Muli-Bold.woff') format('woff');
28 | }
29 |
30 | @font-face {
31 | font-family: 'Muli ExtraBold';
32 | font-style: normal;
33 | font-weight: normal;
34 | src: local('Muli ExtraBold'), url('./Muli-ExtraBold.woff') format('woff');
35 | }
36 |
37 | @font-face {
38 | font-family: 'Muli Black';
39 | font-style: normal;
40 | font-weight: normal;
41 | src: local('Muli Black'), url('./Muli-Black.woff') format('woff');
42 | }
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/dashboard.svg:
--------------------------------------------------------------------------------
1 |
15 |
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/login_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/images/login_bg.png
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/login_icn.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/180Dashboard/src/assets/images/logo.png
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/logout_active.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/notification.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/refresh.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/right_angle_arrow.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/select-down-arrow.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/180Dashboard/src/assets/images/user.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/180Dashboard/src/components/AlertBox.js:
--------------------------------------------------------------------------------
1 | import Alert from 'react-popup-alert'
2 | import 'react-popup-alert/dist/index.css'
3 | import {forwardRef, useImperativeHandle, useState} from "react";
4 |
5 | const AlertBox = forwardRef((props, ref) => {
6 | const [alert, setAlert] = useState({
7 | type: '',
8 | text: '',
9 | show: false
10 | })
11 |
12 | useImperativeHandle(
13 | ref,
14 | () => ({
15 | showAlert(type, text) {
16 | setAlert({
17 | type: type,
18 | text: text,
19 | show: true
20 | })
21 | }
22 | }),
23 | )
24 |
25 | const onCloseAlert = () => {
26 | setAlert({
27 | type: '',
28 | text: '',
29 | show: false
30 | })
31 | }
32 |
33 | return (
34 |
61 | )
62 | })
63 |
64 | export default AlertBox;
--------------------------------------------------------------------------------
/180Dashboard/src/components/AppRoute.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Redirect, Route} from 'react-router-dom';
3 | import {useAuthState} from '../store/context';
4 |
5 | const AppRoutes = ({component: Component, path, ...rest}) => {
6 | const userDetails = useAuthState();
7 | return (
8 |
11 | !Boolean(userDetails.user) ? (
12 |
15 | ) : (
16 |
17 | )
18 | }
19 | />
20 | );
21 | };
22 |
23 | export default AppRoutes;
24 |
--------------------------------------------------------------------------------
/180Dashboard/src/components/Chart.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {ResponsivePie} from '@nivo/pie'
3 |
4 | const MyResponsivePie = ({data}) => (
5 | (
18 | id ?
19 |
20 | {id}: {value}
21 | : null
22 | )}
23 | />
24 | )
25 |
26 | export default MyResponsivePie;
--------------------------------------------------------------------------------
/180Dashboard/src/containers/FormikFields.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Select from "react-select";
3 |
4 | export class FormikReactSelect extends React.Component {
5 | handleChange = value => {
6 | this.props.onChange(this.props.name, value);
7 | };
8 | handleBlur = () => {
9 | this.props.onBlur(this.props.name, true);
10 | };
11 |
12 | render() {
13 | return (
14 |
24 | );
25 | }
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Footer/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styles from './Footer.module.scss';
3 |
4 | const Footer = () => {
5 | let now = new Date();
6 |
7 | return (
8 | <>
9 |
20 | >
21 | )
22 | }
23 |
24 | export default Footer;
25 |
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Footer/Footer.module.scss:
--------------------------------------------------------------------------------
1 | @import '../../../App.css';
2 |
3 | footer {
4 | background-color: #607185;
5 | padding:10px 15px;
6 |
7 | .footerText {
8 | display: flex;
9 | justify-content: space-between;
10 | align-items: center;
11 | font-size: 14px;
12 |
13 | p {
14 | color: #ffffff !important;
15 | margin-bottom: 0px;
16 |
17 | a {
18 | color: inherit !important;
19 | text-decoration: none;
20 |
21 | &:hover {
22 | color: #8fc5eb !important;
23 | }
24 | }
25 | }
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Footer/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./Footer";
2 |
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Header/Header.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styles from './Header.module.scss';
3 | import {useAuthDispatch, useAuthState} from "../../../store/context";
4 | import {logout} from "../../../store/auth/actions";
5 |
6 | // Images
7 | import logo from "../../../assets/images/logo.png";
8 | import notificationIcon from "../../../assets/images/notification.svg";
9 | import userIcon from "../../../assets/images/user.svg";
10 | import logoutIcon from "../../../assets/images/logout_active.svg";
11 |
12 | const Header = () => {
13 | const dispatch = useAuthDispatch();
14 | const userDetails = useAuthState();
15 |
16 | const handleLogout = async () => {
17 | await logout(dispatch);
18 | };
19 |
20 | return (
21 | <>
22 |
23 |
24 |
53 |
54 |
55 | >
56 | )
57 | }
58 |
59 | export default Header;
60 |
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Header/Header.module.scss:
--------------------------------------------------------------------------------
1 | @import '../../../App.css';
2 |
3 | .header {
4 | position: relative;
5 |
6 | .bgGradient {
7 | height: 300px;
8 | background-image: linear-gradient(#35607E, #1E303E);
9 | }
10 |
11 | .headerContainer {
12 | padding-top: 12px;
13 | padding-bottom: 12px;
14 | }
15 |
16 | .logo {
17 | width: 100%;
18 | height: auto;
19 | max-width: 180px;
20 | }
21 |
22 | .headerRightBar {
23 | display: inline-flex;
24 | align-items: center;
25 | justify-content: center;
26 |
27 | h3 {
28 | margin-right: 20px;
29 | font-family: 'Muli Bold';
30 | font-style: normal;
31 | font-weight: normal;
32 | text-transform: uppercase;
33 | font-size: 20px;
34 | color: #2F314A;
35 | margin-bottom: 0 !important;
36 | letter-spacing: 0.5px;
37 | }
38 |
39 | }
40 |
41 | .navbarNav {
42 | flex-direction: row;
43 |
44 | li {
45 | display: inline-flex;
46 | align-items: center;
47 | justify-content: center;
48 |
49 | &:not(:first-child) {
50 | margin-left: 20px;
51 | }
52 |
53 | &:last-child {
54 | margin-right: 10px;
55 | }
56 | }
57 | }
58 |
59 | .notificationIconClass {
60 | position: relative;
61 | font-family: 'Muli Bold' !important;
62 |
63 | .notificationCount {
64 | position: absolute;
65 | background-color: #FAC17C;
66 | width: 20px;
67 | height: 20px;
68 | border-radius: 60px;
69 | display: flex;
70 | align-items: center;
71 | justify-content: center;
72 | top: -5px;
73 | right: -5px;
74 | color: #ffffff;
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Header/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./Header";
2 |
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Menu/Menu.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styles from './Menu.module.scss';
3 | import {Link} from "react-router-dom";
4 |
5 | const Menu = () => {
6 | return (
7 | <>
8 |
15 | >
16 | )
17 | }
18 |
19 | export default Menu;
20 |
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Menu/Menu.module.scss:
--------------------------------------------------------------------------------
1 | @import '../../../App.css';
2 |
3 | .headerContainer {
4 | padding-top: 12px;
5 | padding-bottom: 12px;
6 | text-align: center;
7 |
8 | .headerLinksUl {
9 | display: inline-flex;
10 | text-align: center;
11 | list-style: none !important;
12 | padding-left: 0;
13 | margin-top: 0.5rem;
14 | margin-bottom: 0.5rem;
15 |
16 | li {
17 | display: inline-block;
18 | list-style: none !important;
19 | margin: 0 15px;
20 |
21 | a.menuLink {
22 | text-decoration: none;
23 | display: block;
24 | font-family: 'Muli SemiBold';
25 |
26 | &:hover {
27 | text-decoration: underline;
28 | }
29 | }
30 | }
31 | }
32 |
33 | }
--------------------------------------------------------------------------------
/180Dashboard/src/containers/navs/Menu/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./Menu";
2 |
--------------------------------------------------------------------------------
/180Dashboard/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/180Dashboard/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import 'bootstrap/dist/css/bootstrap.min.css';
5 | import '@devexpress/dx-react-grid-bootstrap4/dist/dx-react-grid-bootstrap4.css';
6 | import App from './App';
7 | import reportWebVitals from './reportWebVitals';
8 | import {StoreProvider} from "./store/store";
9 |
10 | ReactDOM.render(
11 |
12 |
13 |
14 |
15 | ,
16 | document.getElementById('root')
17 | );
18 |
19 | // If you want to start measuring performance in your app, pass a function
20 | // to log results (for example: reportWebVitals(console.log))
21 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
22 | reportWebVitals();
23 |
--------------------------------------------------------------------------------
/180Dashboard/src/layout/AppLayout.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Header from "../containers/navs/Header";
3 | import Footer from "../containers/navs/Footer";
4 |
5 | export default (props) => {
6 | return (
7 | <>
8 |
9 | {props.children}
10 |
11 | >
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/180Dashboard/src/layout/UserLayout.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Header from "../containers/navs/Header";
3 | import Footer from "../containers/navs/Footer";
4 |
5 | export default (props) => {
6 | return (
7 |
8 |
9 | {props.children}
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/180Dashboard/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/180Dashboard/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/180Dashboard/src/store/actions.js:
--------------------------------------------------------------------------------
1 | /* AUTH */
2 | export const LOGIN = "LOGIN";
3 | export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
4 | export const LOGIN_ERROR = "LOGIN_ERROR";
5 | export const LOGOUT = "LOGOUT";
6 |
7 | /* PROVIDER */
8 | export const UPLOAD = "UPLOAD";
9 | export const UPLOAD_SUCCESS = "UPLOAD_SUCCESS";
10 | export const UPLOAD_ERROR = "UPLOAD_ERROR";
11 | export const FETCH_ENCRYPTED_REWARDS_DATA = "FETCH_ENCRYPTED_REWARDS_DATA";
12 | export const FETCH_ENCRYPTED_REWARDS_DATA_SUCCESS = "FETCH_ENCRYPTED_REWARDS_DATA_SUCCESS";
13 | export const FETCH_ENCRYPTED_REWARDS_DATA_ERROR = "FETCH_ENCRYPTED_REWARDS_DATA_ERROR";
14 | export const FETCH_DECRYPTED_REWARDS_DATA = "FETCH_DECRYPTED_REWARDS_DATA";
15 | export const FETCH_DECRYPTED_REWARDS_DATA_SUCCESS = "FETCH_DECRYPTED_REWARDS_DATA_SUCCESS";
16 | export const FETCH_DECRYPTED_REWARDS_DATA_ERROR = "FETCH_DECRYPTED_REWARDS_DATA_ERROR";
17 |
18 | /* CONSUMER */
19 | export const UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY = "UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY";
20 | export const UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS = "UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS";
21 | export const UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR = "UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR";
22 | export const RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY = "RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY";
23 | export const RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS = "RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS";
24 | export const RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR = "RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR";
25 | export const AGGREGATION_REQUEST = "AGGREGATION_REQUEST";
26 | export const AGGREGATION_REQUEST_SUCCESS = "AGGREGATION_REQUEST_SUCCESS";
27 | export const AGGREGATION_REQUEST_ERROR = "AGGREGATION_REQUEST_ERROR";
28 | export const FETCH_ENCRYPTED_DATA_OUTPUT = "FETCH_ENCRYPTED_DATA_OUTPUT";
29 | export const FETCH_ENCRYPTED_DATA_OUTPUT_SUCCESS = "FETCH_ENCRYPTED_DATA_OUTPUT_SUCCESS";
30 | export const FETCH_ENCRYPTED_DATA_OUTPUT_ERROR = "FETCH_ENCRYPTED_DATA_OUTPUT_ERROR";
31 | export const FETCH_DECRYPTED_DATA_OUTPUT = "FETCH_DECRYPTED_DATA_OUTPUT";
32 | export const FETCH_DECRYPTED_DATA_OUTPUT_SUCCESS = "FETCH_DECRYPTED_DATA_OUTPUT_SUCCESS";
33 | export const FETCH_DECRYPTED_DATA_OUTPUT_ERROR = "FETCH_DECRYPTED_DATA_OUTPUT_ERROR";
--------------------------------------------------------------------------------
/180Dashboard/src/store/auth/actions.js:
--------------------------------------------------------------------------------
1 | import {getYamlInfo} from "../../utils/helpers";
2 |
3 | export async function login(dispatch, payload) {
4 | try {
5 | dispatch({type: 'LOGIN'});
6 | let info = await getYamlInfo();
7 | let nodeInfo = Object.values(info.nodes).find((item) => {
8 | return item.username === payload.username && item.password === payload.password ? item : null
9 | });
10 |
11 | if (nodeInfo) {
12 | delete nodeInfo.password;
13 | dispatch({type: 'LOGIN_SUCCESS', payload: nodeInfo});
14 | localStorage.setItem('user', JSON.stringify(nodeInfo));
15 | localStorage.setItem('rewards', JSON.stringify(info.rewards));
16 | localStorage.setItem('dataTypeOptions', JSON.stringify(info.dataTypes));
17 | localStorage.setItem('storageTypeOptions', JSON.stringify(info.storageTypes));
18 | return nodeInfo;
19 | } else {
20 | dispatch({type: 'LOGIN_ERROR', error: 'Error'});
21 | return null;
22 | }
23 | } catch (error) {
24 | dispatch({type: 'LOGIN_ERROR', error: error});
25 | console.log(error);
26 | }
27 | }
28 |
29 | export async function logout(dispatch) {
30 | dispatch({type: 'LOGOUT'});
31 | localStorage.removeItem('user');
32 | localStorage.removeItem('rewards');
33 | window.location.reload();
34 | }
--------------------------------------------------------------------------------
/180Dashboard/src/store/auth/reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | LOGIN,
3 | LOGIN_SUCCESS,
4 | LOGIN_ERROR,
5 | LOGOUT
6 | } from "../actions";
7 |
8 | export const initialState = {
9 | user: localStorage.getItem("user")
10 | ? JSON.parse(localStorage.getItem("user"))
11 | : null,
12 | loading: false
13 | };
14 |
15 | export default (state = initialState, action) => {
16 | switch (action.type) {
17 | case LOGIN:
18 | return {...state, loading: true};
19 | case LOGIN_SUCCESS:
20 | return {...state, loading: false, user: action.payload};
21 | case LOGIN_ERROR:
22 | return {...state, loading: false};
23 | case LOGOUT:
24 | return {...state, user: null};
25 | default:
26 | return state;
27 | }
28 | };
--------------------------------------------------------------------------------
/180Dashboard/src/store/consumer/reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | AGGREGATION_REQUEST,
3 | AGGREGATION_REQUEST_ERROR,
4 | AGGREGATION_REQUEST_SUCCESS,
5 | FETCH_DECRYPTED_DATA_OUTPUT,
6 | FETCH_DECRYPTED_DATA_OUTPUT_ERROR,
7 | FETCH_DECRYPTED_DATA_OUTPUT_SUCCESS,
8 | FETCH_ENCRYPTED_DATA_OUTPUT,
9 | FETCH_ENCRYPTED_DATA_OUTPUT_ERROR,
10 | FETCH_ENCRYPTED_DATA_OUTPUT_SUCCESS,
11 | UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY,
12 | UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS,
13 | UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR,
14 | RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY,
15 | RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS,
16 | RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR
17 | } from "../actions";
18 |
19 | export const initialState = {
20 | updateDecentralizedStorageEncryptionKey: {},
21 | retrievalDecentralizedStorageEncryptionKey: {},
22 | aggregationRequest: {},
23 | encryptedDataOutput: [],
24 | decryptedDataOutput: [],
25 | loading: false
26 | };
27 |
28 | export default (state = initialState, action) => {
29 | switch (action.type) {
30 | case UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY:
31 | return {...state, loading: true};
32 | case UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS:
33 | return {...state, loading: false, updateDecentralizedStorageEncryptionKey: action.payload};
34 | case UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR:
35 | return {...state, loading: false};
36 | case RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY:
37 | return {...state, loading: true};
38 | case RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS:
39 | return {...state, loading: false, retrievalDecentralizedStorageEncryptionKey: action.payload};
40 | case RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR:
41 | return {...state, loading: false};
42 | case AGGREGATION_REQUEST:
43 | return {...state, loading: true};
44 | case AGGREGATION_REQUEST_SUCCESS:
45 | return {...state, loading: false, aggregationRequest: action.payload};
46 | case AGGREGATION_REQUEST_ERROR:
47 | return {...state, loading: false};
48 | case FETCH_ENCRYPTED_DATA_OUTPUT:
49 | return {...state, loading: true};
50 | case FETCH_ENCRYPTED_DATA_OUTPUT_SUCCESS:
51 | return {...state, loading: false, encryptedDataOutput: action.payload};
52 | case FETCH_ENCRYPTED_DATA_OUTPUT_ERROR:
53 | return {...state, loading: false};
54 | case FETCH_DECRYPTED_DATA_OUTPUT:
55 | return {...state, loading: true};
56 | case FETCH_DECRYPTED_DATA_OUTPUT_SUCCESS:
57 | return {...state, loading: false, decryptedDataOutput: action.payload};
58 | case FETCH_DECRYPTED_DATA_OUTPUT_ERROR:
59 | return {...state, loading: false};
60 | default:
61 | return state;
62 | }
63 | };
--------------------------------------------------------------------------------
/180Dashboard/src/store/context.js:
--------------------------------------------------------------------------------
1 | import React, {useReducer} from 'react';
2 | import AuthReducer, {initialState} from './auth/reducer';
3 |
4 | const AuthStateContext = React.createContext();
5 | const AuthDispatchContext = React.createContext();
6 |
7 | export function useAuthState() {
8 | const context = React.useContext(AuthStateContext);
9 | if (context === undefined) {
10 | throw new Error('useAuthState must be used within a AuthProvider');
11 | }
12 |
13 | return context;
14 | }
15 |
16 | export function useAuthDispatch() {
17 | const context = React.useContext(AuthDispatchContext);
18 | if (context === undefined) {
19 | throw new Error('useAuthDispatch must be used within a AuthProvider');
20 | }
21 |
22 | return context;
23 | }
24 |
25 | export const AuthProvider = ({children}) => {
26 | const [user, dispatch] = useReducer(AuthReducer, initialState);
27 |
28 | return (
29 |
30 |
31 | {children}
32 |
33 |
34 | );
35 | };
36 |
--------------------------------------------------------------------------------
/180Dashboard/src/store/provider/reducer.js:
--------------------------------------------------------------------------------
1 | import {
2 | UPLOAD,
3 | UPLOAD_SUCCESS,
4 | UPLOAD_ERROR,
5 | FETCH_ENCRYPTED_REWARDS_DATA,
6 | FETCH_ENCRYPTED_REWARDS_DATA_SUCCESS,
7 | FETCH_ENCRYPTED_REWARDS_DATA_ERROR,
8 | FETCH_DECRYPTED_REWARDS_DATA,
9 | FETCH_DECRYPTED_REWARDS_DATA_SUCCESS,
10 | FETCH_DECRYPTED_REWARDS_DATA_ERROR,
11 | UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY,
12 | UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS,
13 | UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR,
14 | RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY,
15 | RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS,
16 | RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR
17 | } from "../actions";
18 |
19 | export const initialState = {
20 | updateDecentralizedStorageEncryptionKey: {},
21 | retrievalDecentralizedStorageEncryptionKey: {},
22 | uploadData: {},
23 | encryptedRewardsData: [],
24 | decryptedRewardsData: {},
25 | loading: false
26 | };
27 |
28 | export default (state = initialState, action) => {
29 | switch (action.type) {
30 | case UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY:
31 | return {...state, loading: true};
32 | case UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS:
33 | return {...state, loading: false, updateDecentralizedStorageEncryptionKey: action.payload};
34 | case UPDATE_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR:
35 | return {...state, loading: false};
36 | case RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY:
37 | return {...state, loading: true};
38 | case RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_SUCCESS:
39 | return {...state, loading: false, retrievalDecentralizedStorageEncryptionKey: action.payload};
40 | case RETRIEVAL_DECENTRALIZED_STORAGE_ENCRYPTION_KEY_ERROR:
41 | return {...state, loading: false};
42 | case UPLOAD:
43 | return {...state, loading: true};
44 | case UPLOAD_SUCCESS:
45 | return {...state, loading: false, uploadData: action.payload};
46 | case UPLOAD_ERROR:
47 | return {...state, loading: false};
48 | case FETCH_ENCRYPTED_REWARDS_DATA:
49 | return {...state, loading: true};
50 | case FETCH_ENCRYPTED_REWARDS_DATA_SUCCESS:
51 | return {...state, loading: false, encryptedRewardsData: action.payload};
52 | case FETCH_ENCRYPTED_REWARDS_DATA_ERROR:
53 | return {...state, loading: false};
54 | case FETCH_DECRYPTED_REWARDS_DATA:
55 | return {...state, loading: true};
56 | case FETCH_DECRYPTED_REWARDS_DATA_SUCCESS:
57 | return {...state, loading: false, decryptedRewardsData: action.payload};
58 | case FETCH_DECRYPTED_REWARDS_DATA_ERROR:
59 | return {...state, loading: false};
60 | default:
61 | return state;
62 | }
63 | };
--------------------------------------------------------------------------------
/180Dashboard/src/store/reducers.js:
--------------------------------------------------------------------------------
1 | import auth from "./auth/reducer";
2 | import provider from "./provider/reducer";
3 | import consumer from "./consumer/reducer";
4 | import {combineReducers} from "./../utils/helpers"
5 |
6 | const reducers = combineReducers({
7 | auth,
8 | provider,
9 | consumer
10 | });
11 |
12 | export default reducers;
13 |
--------------------------------------------------------------------------------
/180Dashboard/src/store/store.js:
--------------------------------------------------------------------------------
1 | import React, {createContext, useReducer} from 'react';
2 | import reducers from './reducers';
3 |
4 | export const Store = createContext({});
5 |
6 | export const StoreProvider = ({children}) => {
7 | const [state, dispatch] = useReducer(reducers, {});
8 |
9 | return {children};
10 | };
--------------------------------------------------------------------------------
/180Dashboard/src/userInfo.yml:
--------------------------------------------------------------------------------
1 | nodes:
2 | providerA:
3 | username: providerA
4 | password: test
5 | port: 9500
6 | role: provider
7 | name: O=Host,L=London,C=GB
8 | providerB:
9 | username: providerB
10 | password: test
11 | port: 7500
12 | role: provider
13 | name: O=ProviderB,L=New York,C=US
14 | providerD:
15 | username: providerD
16 | password: test
17 | port: 5500
18 | role: provider
19 | name: O=ProviderD,L=New York,C=US
20 | consumerC:
21 | username: consumerC
22 | password: test
23 | port: 6500
24 | role: consumer
25 | name: O=ConsumerC,L=Chicago,C=US
26 | rewards:
27 | amountProvided: 20
28 | completeness: 30
29 | uniqueness: 20
30 | updateFrequency: 30
31 | dataTypes:
32 | - value: testSchema1
33 | label: Automotive Data
34 | storageTypes:
35 | - value: local
36 | label: Local
37 | - value: filecoin
38 | label: Filecoin
--------------------------------------------------------------------------------
/180Dashboard/src/utils/helpers.js:
--------------------------------------------------------------------------------
1 | import userInfo from "./../userInfo.yml";
2 | import jsYaml from "yamljs";
3 |
4 | export const combineReducers = (slices) => (state, action) =>
5 | Object.keys(slices).reduce( // use for..in loop, if you prefer it
6 | (acc, prop) => ({
7 | ...acc,
8 | [prop]: slices[prop](acc[prop], action),
9 | }),
10 | state
11 | );
12 |
13 | export const average = (arr, field) => {
14 | return (arr.reduce(function (sum, item) {
15 | return sum + parseFloat(item[field]);
16 | }, 0) / arr.length).toFixed(1);
17 | }
18 |
19 | export const sum = (arr, field) => {
20 | return (arr.reduce(function (sum, item) {
21 | return sum + parseFloat(item[field]);
22 | }, 0)).toFixed(1);
23 | }
24 |
25 | export const ucWords = (str) => {
26 | const result = str.replace(/([A-Z])/g, " $1");
27 | return result.charAt(0).toUpperCase() + result.slice(1);
28 | }
29 |
30 | export const getYamlInfo = async () => {
31 | let response = await fetch(userInfo);
32 | let data = await response.text();
33 | return jsYaml.parse(data);
34 | }
--------------------------------------------------------------------------------
/180Dashboard/src/utils/history.js:
--------------------------------------------------------------------------------
1 | import { createBrowserHistory } from "history";
2 |
3 | export const history = createBrowserHistory();
4 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/app/consumer/Dashboard/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./Dashboard";
2 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/app/consumer/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {Route, Switch, Redirect} from "react-router-dom";
3 | import AppLayout from "../../../layout/AppLayout";
4 | import Dashboard from "./Dashboard";
5 |
6 | export default (props) => {
7 | const {match} = props.property;
8 |
9 | return (
10 |
11 |
12 |
13 | }/>
14 |
15 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/app/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Provider from "./provider";
3 | import Consumer from "./consumer";
4 | import {useAuthState} from "../../store/context";
5 |
6 | const renderRoleBasedComponent = (user, props) => {
7 | const apiUrl = 'http://localhost:' + user.port || '3000';
8 |
9 | switch (user.role) {
10 | case 'consumer':
11 | return ;
12 | case 'provider':
13 | return ;
14 | default:
15 | return null
16 | }
17 | }
18 |
19 | export default (props) => {
20 | const userDetails = useAuthState();
21 |
22 | return (
23 | userDetails.user && userDetails.user.role ? renderRoleBasedComponent(userDetails.user, props) : null
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/app/provider/Data/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./Data";
2 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/app/provider/Rewards/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./Rewards";
2 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/app/provider/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {Route, Switch, Redirect} from "react-router-dom";
3 | import AppLayout from "../../../layout/AppLayout";
4 | import Data from "./Data";
5 | import Rewards from "./Rewards";
6 |
7 | export default (props) => {
8 | const {match} = props.property;
9 |
10 | return (
11 |
12 |
13 |
14 | }/>
15 | }/>
16 |
17 |
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/error.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Error = () => {
4 | return Error
5 | }
6 |
7 | export default Error;
8 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/index.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from "react";
2 | import {Redirect} from "react-router-dom";
3 |
4 | class Main extends Component {
5 | render() {
6 | return
7 | }
8 | }
9 |
10 | export default Main;
11 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/user/Login/Login.module.scss:
--------------------------------------------------------------------------------
1 | .header {
2 | position: relative;
3 |
4 | .headerContainer {
5 | padding-top: 12px;
6 | padding-bottom: 12px;
7 | }
8 |
9 | .logo {
10 | width: 150px;
11 | }
12 |
13 | }
14 |
15 | .login {
16 | width: 100%;
17 | height: 100%;
18 |
19 | }
20 |
21 | footer {
22 | background-color: #607185;
23 | padding: 10px 15px;
24 |
25 | .footerText {
26 | display: flex;
27 | justify-content: space-between;
28 | align-items: center;
29 |
30 | p {
31 | color: #ffffff !important;
32 | margin-bottom: 0px;
33 |
34 | a {
35 | color: inherit !important;
36 | text-decoration: none;
37 |
38 | &:hover {
39 | color: #cdfdff !important;
40 | }
41 | }
42 | }
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/180Dashboard/src/views/user/Login/index.js:
--------------------------------------------------------------------------------
1 | export { default } from "./Login";
2 |
--------------------------------------------------------------------------------
/180Dashboard/src/views/user/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {Route, Switch, Redirect} from "react-router-dom";
3 | import UserLayout from "../../layout/UserLayout";
4 | import Login from "./Login";
5 |
6 | export default (props) => {
7 | const {match} = props;
8 |
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/examples/automotive-example/TRADEMARK:
--------------------------------------------------------------------------------
1 | Corda and the Corda logo are trademarks of R3CEV LLC and its affiliates. All rights reserved.
2 |
3 | For R3CEV LLC's trademark and logo usage information, please consult our Trademark Usage Policy at
4 | https://www.r3.com/trademark-policy/.
5 |
--------------------------------------------------------------------------------
/examples/automotive-example/compose-codaptor.yml:
--------------------------------------------------------------------------------
1 | # use docker-compose up -d to start the network
2 | # version 3 does not support setting memory limits for docker-compose
3 | version: '2'
4 | services:
5 | codaptora:
6 | image: b180tech/cordaptor:0.4.1-corda4.7
7 | hostname: codaptora
8 | mem_limit: 512m
9 | environment:
10 | - CORDA_RPC_NODE_ADDRESS=host-node:10005 # using hostname known within the Docker network
11 | - CORDA_RPC_USERNAME=user1 # this must match build.gradle
12 | - CORDA_RPC_PASSWORD=test # this must match build.gradle
13 | # we must override Cordaptor's default of binding to the loopback interface,
14 | # because we want its port to be visible on the Docker network
15 | - CORDAPTOR_API_LISTEN_ADDRESS=0.0.0.0:8500
16 | # this is necessary to allow Cordaptor to generate URLs (e.g. for OpenAPI bindings or Location headers)
17 | # using URL resolvable outside the Docker network
18 | - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:9500 # this must be consistent with the ports directive below
19 | ports:
20 | - "9500:8500"
21 | - "9008:8008"
22 | volumes:
23 | # Corda RPC requires CorDapp JARs to be available in the classpath
24 | - ./build/nodes/Host/cordapps:/cordaptor/cordapps
25 | codaptorb:
26 | image: b180tech/cordaptor:0.4.1-corda4.7
27 | hostname: codaptorb
28 | mem_limit: 512m
29 | environment:
30 | - CORDA_RPC_NODE_ADDRESS=providerb-node:10007 # using hostname known within the Docker network
31 | - CORDA_RPC_USERNAME=user1 # this must match build.gradle
32 | - CORDA_RPC_PASSWORD=test # this must match build.gradle
33 | # we must override Cordaptor's default of binding to the loopback interface,
34 | # because we want its port to be visible on the Docker network
35 | - CORDAPTOR_API_LISTEN_ADDRESS=0.0.0.0:8500
36 | # this is necessary to allow Cordaptor to generate URLs (e.g. for OpenAPI bindings or Location headers)
37 | # using URL resolvable outside the Docker network
38 | - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:7500 # this must be consistent with the ports directive below
39 | ports:
40 | - "7500:8500"
41 | - "7008:8008"
42 | volumes:
43 | # Corda RPC requires CorDapp JARs to be available in the classpath
44 | - ./build/nodes/ProviderB/cordapps:/cordaptor/cordapps
45 | codaptorc:
46 | image: b180tech/cordaptor:0.4.1-corda4.7
47 | hostname: codaptorc
48 | mem_limit: 512m
49 | environment:
50 | - CORDA_RPC_NODE_ADDRESS=consumerc-node:10009 # using hostname known within the Docker network
51 | - CORDA_RPC_USERNAME=user1 # this must match build.gradle
52 | - CORDA_RPC_PASSWORD=test # this must match build.gradle
53 | # we must override Cordaptor's default of binding to the loopback interface,
54 | # because we want its port to be visible on the Docker network
55 | - CORDAPTOR_API_LISTEN_ADDRESS=0.0.0.0:8500
56 | # this is necessary to allow Cordaptor to generate URLs (e.g. for OpenAPI bindings or Location headers)
57 | # using URL resolvable outside the Docker network
58 | - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:6500 # this must be consistent with the ports directive below
59 | ports:
60 | - "6500:8500"
61 | - "6008:8008"
62 | volumes:
63 | # Corda RPC requires CorDapp JARs to be available in the classpath
64 | - ./build/nodes/ConsumerC/cordapps:/cordaptor/cordapps
--------------------------------------------------------------------------------
/examples/automotive-example/config/dev/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | logs
6 | node-${hostName}
7 | ${log-path}/archive
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | %highlight{%level{length=1} %d{HH:mm:ss} %T %c{1}.%M - %msg%n}{INFO=white,WARN=red,FATAL=bright red blink}
17 | >
18 |
19 |
20 |
21 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/examples/automotive-example/config/test/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | [%-5level] %d{HH:mm:ss.SSS} [%t] %c{1}.%M - %msg%n
8 | >
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/automotive-example/constants.properties:
--------------------------------------------------------------------------------
1 | cordaReleaseGroup=net.corda
2 | cordaCoreReleaseGroup=net.corda
3 | cordaVersion=4.7
4 | cordaCoreVersion=4.7
5 | gradlePluginsVersion=5.0.12
6 | kotlinVersion=1.2.71
7 | java8MinUpdateVersion=171
8 | junitVersion=4.12
9 | log4jVersion =2.11.2
10 | platformVersion=9
11 | slf4jVersion=1.7.25
12 | quasarVersion=0.7.10
13 |
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.r3.conclave.enclave'
3 | }
4 |
5 | dependencies {
6 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
7 | implementation "com.r3.conclave:conclave-enclave"
8 |
9 | testImplementation "com.r3.conclave:conclave-host"
10 | testImplementation "org.junit.jupiter:junit-jupiter:5.6.0"
11 |
12 | compile 'com.protocol180:protocol-aggregator-enclave:0.2.0'
13 |
14 | compile group: 'org.apache.avro', name: 'avro', version: '1.10.2'
15 | compile group: 'com.github.luben', name: 'zstd-jni', version: '1.4.9-5'
16 | compile group: 'org.xerial.snappy', name: 'snappy-java', version: '1.1.8.2'
17 | compile group: 'org.tukaani', name: 'xz', version: '1.9'
18 | compile group: 'org.brotli', name: 'dec', version: '0.1.2'
19 | compile group: 'org.osgi', name: 'org.osgi.framework', version: '1.10.0'
20 | }
21 |
22 | conclave {
23 | productID = 1
24 | revocationLevel = 0
25 |
26 | simulation {
27 | signingType = privateKey
28 | signingKey = file("sample_private_key.pem")
29 | }
30 |
31 | debug {
32 | signingType = privateKey
33 | signingKey = file("sample_private_key.pem")
34 | }
35 |
36 | release {
37 | signingType = privateKey
38 | signingKey = file("sample_private_key.pem")
39 | }
40 | }
41 |
42 | test {
43 | useJUnitPlatform()
44 | }
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/sample_private_key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | 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
39 | -----END RSA PRIVATE KEY-----
40 |
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/src/main/resources/META-INF/native-image/filter.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": [
3 | {
4 | "excludeClasses": "java.net.**"
5 | },
6 | {
7 | "excludeClasses": "com.r3.conclave.host.**"
8 | }
9 | ]
10 | }
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/src/main/resources/META-INF/native-image/jni-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "sun.management.VMManagementImpl",
4 | "fields": [
5 | {
6 | "name": "bootClassPathSupport"
7 | },
8 | {
9 | "name": "compTimeMonitoringSupport"
10 | },
11 | {
12 | "name": "currentThreadCpuTimeSupport"
13 | },
14 | {
15 | "name": "gcNotificationSupport"
16 | },
17 | {
18 | "name": "objectMonitorUsageSupport"
19 | },
20 | {
21 | "name": "otherThreadCpuTimeSupport"
22 | },
23 | {
24 | "name": "remoteDiagnosticCommandsSupport"
25 | },
26 | {
27 | "name": "synchronizerUsageSupport"
28 | },
29 | {
30 | "name": "threadAllocatedMemorySupport"
31 | },
32 | {
33 | "name": "threadContentionMonitoringSupport"
34 | }
35 | ]
36 | }
37 | ]
38 |
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/src/main/resources/META-INF/native-image/native-image.properties:
--------------------------------------------------------------------------------
1 | Args = -H:IncludeResources=trustedroot.cer
2 |
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/src/main/resources/META-INF/native-image/proxy-config.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/src/main/resources/META-INF/native-image/resource-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "resources": {
3 | "includes": [
4 | {
5 | "pattern": "\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E"
6 | }
7 | ]
8 | },
9 | "bundles": []
10 | }
11 |
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/src/main/resources/META-INF/native-image/serialization-config.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/src/main/resources/trustedroot.cer:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICCTCCAbCgAwIBAgIIcFe0qctqSucwCgYIKoZIzj0EAwIwWDEbMBkGA1UEAwwS
3 | Q29yZGEgTm9kZSBSb290IENBMQswCQYDVQQKDAJSMzEOMAwGA1UECwwFY29yZGEx
4 | DzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUswHhcNMTcwNTIyMDAwMDAwWhcN
5 | MjcwNTIwMDAwMDAwWjBYMRswGQYDVQQDDBJDb3JkYSBOb2RlIFJvb3QgQ0ExCzAJ
6 | BgNVBAoMAlIzMQ4wDAYDVQQLDAVjb3JkYTEPMA0GA1UEBwwGTG9uZG9uMQswCQYD
7 | VQQGEwJVSzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGlm6LFHrVkzfuUHin36
8 | Jrm1aUMarX/NUZXw8n8gSiJmsZPlUEplJ+f/lzZMky5EZPTtCciG34pnOP0eiMd/
9 | JTCjZDBiMB0GA1UdDgQWBBR8rqnfuUgBKxOJC5rmRYUcORcHczALBgNVHQ8EBAMC
10 | AYYwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMA8GA1UdEwEB
11 | /wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgDaL4SguKsNeTT7SeUkFdoCBACeG8
12 | GqO4M1KlfimphQwCICiq00hDanT5W8bTLqE7GIGuplf/O8AABlpWrUg6uiUB
13 | -----END CERTIFICATE-----
14 |
--------------------------------------------------------------------------------
/examples/automotive-example/enclave/src/test/resources/AutomotiveMarketResearchSampleData.csv:
--------------------------------------------------------------------------------
1 | manufacturer|brand|model|type|ev|date|country|units|average_price|total_sales
2 | "Honda"|"Acura"|"CDX"|"SUV"|""|"2021-10-01"|"Argentina"|5|75326.09941226066|376630.49706130335
3 | "Honda"|"Acura"|"CDX"|"SUV"|""|"2021-10-01"|"Australia"|11|74653.40074696894|821187.4082166583
4 | "Honda"|"Acura"|"CDX"|"SUV"|""|"2021-10-01"|"Brazil"|54|68479.72213745091|3697904.9954223493
5 | "Tesla"|"Tesla"|"Model 3"|"Sedan"|"EV"|"2021-10-01"|"Argentina"|7|63525.16894743328|444676.18263203296
6 | "Tesla"|"Tesla"|"Model 3"|"Sedan"|"EV"|"2021-10-01"|"Australia"|60|63307.449682902035|3798446.980974122
7 | "Tesla"|"Tesla"|"Model 3"|"Sedan"|"EV"|"2021-10-01"|"Brazil"|138|63115.02566106154|8709873.541226493
8 | "Tesla"|"Tesla"|"Model 3"|"Sedan"|"EV"|"2021-10-31"|"Canada"|101|61418.442626873446|6203262.705314218
9 | "Honda"|"Honda"|"XR-V"|"SUV"|""|"2021-12-30"|"Chile"|4|19365.207946454368|77460.83178581747
10 | "Honda"|"Honda"|"XR-V"|"SUV"|""|"2021-12-30"|"China"|537|21523.902082053053|11558335.41806249
11 | "Honda"|"Honda"|"XR-V"|"SUV"|""|"2021-12-30"|"France"|153|20724.411656743563|3170834.9834817653
12 | "Honda"|"Honda"|"XR-V"|"SUV"|""|"2021-12-30"|"Germany"|35|21762.989212617933|761704.6224416277
13 | "Volkswagen"|"Skoda"|"Superb"|"Sedan"|""|"2021-10-01"|"Chile"|9|33078.19396357815|297703.74567220337
14 | "Volkswagen"|"Skoda"|"Superb"|"Sedan"|""|"2021-10-01"|"China"|2404|34391.9902125565|82678344.47098583
15 | "Volkswagen"|"Skoda"|"Superb"|"Sedan"|""|"2021-12-31"|"France"|47|35744.06963084006|1679971.2726494828
16 | "Volkswagen"|"Skoda"|"Superb"|"Sedan"|""|"2021-12-31"|"Germany"|52|35895.12662313691|1866546.5844031193
17 | "Ford"|"Lincoln"|"Navigator"|"SUV"|""|"2021-12-30"|"Chile"|8|64134.23393977269|513073.8715181815
18 | "Ford"|"Lincoln"|"Navigator"|"SUV"|""|"2021-12-30"|"China"|738|65605.09303787399|48416558.661951005
19 | "Ford"|"Lincoln"|"Navigator"|"SUV"|""|"2021-12-30"|"France"|44|60374.37882341187|2656472.6682301224
20 | "Ford"|"Lincoln"|"Navigator"|"SUV"|""|"2021-12-30"|"Germany"|251|62953.076865719835|15801222.293295678
21 |
--------------------------------------------------------------------------------
/examples/automotive-example/gradle.properties:
--------------------------------------------------------------------------------
1 | conclaveVersion=1.2.1
2 | conclaveRepo=../../../conclave-sdk-1.2.1/repo
3 | org.gradle.jvmargs=-Xmx4096m
4 |
5 | name=Example Cordapp
6 | group=com.example
7 | version=1.0
8 | kotlin.incremental=false
--------------------------------------------------------------------------------
/examples/automotive-example/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/examples/automotive-example/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/examples/automotive-example/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/examples/automotive-example/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
34 |
35 | @rem Find java.exe
36 | if defined JAVA_HOME goto findJavaFromJavaHome
37 |
38 | set JAVA_EXE=java.exe
39 | %JAVA_EXE% -version >NUL 2>&1
40 | if "%ERRORLEVEL%" == "0" goto init
41 |
42 | echo.
43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
44 | echo.
45 | echo Please set the JAVA_HOME variable in your environment to match the
46 | echo location of your Java installation.
47 |
48 | goto fail
49 |
50 | :findJavaFromJavaHome
51 | set JAVA_HOME=%JAVA_HOME:"=%
52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
53 |
54 | if exist "%JAVA_EXE%" goto init
55 |
56 | echo.
57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
58 | echo.
59 | echo Please set the JAVA_HOME variable in your environment to match the
60 | echo location of your Java installation.
61 |
62 | goto fail
63 |
64 | :init
65 | @rem Get command-line arguments, handling Windows variants
66 |
67 | if not "%OS%" == "Windows_NT" goto win9xME_args
68 |
69 | :win9xME_args
70 | @rem Slurp the command line arguments.
71 | set CMD_LINE_ARGS=
72 | set _SKIP=2
73 |
74 | :win9xME_args_slurp
75 | if "x%~1" == "x" goto execute
76 |
77 | set CMD_LINE_ARGS=%*
78 |
79 | :execute
80 | @rem Setup the command line
81 |
82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
83 |
84 | @rem Execute Gradle
85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
86 |
87 | :end
88 | @rem End local scope for the variables with windows NT shell
89 | if "%ERRORLEVEL%"=="0" goto mainEnd
90 |
91 | :fail
92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
93 | rem the _cmd.exe /c_ return code!
94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
95 | exit /b 1
96 |
97 | :mainEnd
98 | if "%OS%"=="Windows_NT" endlocal
99 |
100 | :omega
101 |
--------------------------------------------------------------------------------
/examples/automotive-example/repositories.gradle:
--------------------------------------------------------------------------------
1 | repositories {
2 | mavenLocal()
3 | mavenCentral()
4 | jcenter()
5 | maven { url 'https://jitpack.io' }
6 | maven { url 'https://software.r3.com/artifactory/corda' }
7 | maven { url 'https://repo.gradle.org/gradle/libs-releases' }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/automotive-example/settings.gradle:
--------------------------------------------------------------------------------
1 | import java.nio.file.Files
2 | import java.nio.file.Paths
3 |
4 | pluginManagement {
5 | repositories {
6 | maven {
7 | def path = Paths.get(rootDir.absolutePath).resolve(conclaveRepo).toAbsolutePath().normalize()
8 | if (!Files.isDirectory(path.resolve("com"))) {
9 | if (Files.isDirectory(Paths.get("/repo/com"))) {
10 | path = Paths.get("/repo")
11 | } else {
12 | throw new Exception("Neither $path nor /repo seem to exist, or they aren't Maven repositories; it should be the SDK 'repo' subdirectory. " +
13 | "If on macOS, try using the container-gradle script to execute run the tests. See the Conclave CorDapp tutorial on https://docs.conclave.net/writing-cordapps.html")
14 | }
15 | }
16 | url = path.toFile()
17 | }
18 | // Add standard repositories back.
19 | gradlePluginPortal()
20 | jcenter()
21 | mavenCentral()
22 | }
23 |
24 | plugins {
25 | id 'com.r3.conclave.enclave' version conclaveVersion apply false
26 | }
27 | }
28 |
29 | include 'workflows'
30 | include 'enclave'
--------------------------------------------------------------------------------
/examples/automotive-example/workflows/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'net.corda.plugins.cordapp'
2 | apply plugin: 'net.corda.plugins.quasar-utils'
3 |
4 | cordapp {
5 | targetPlatformVersion corda_platform_version
6 | minimumPlatformVersion corda_platform_version
7 | workflow {
8 | name "Example-Cordapp Flows"
9 | vendor "Corda Open Source"
10 | licence "Apache License, Version 2.0"
11 | versionId 1
12 | }
13 | signing {
14 | enabled false
15 | }
16 | }
17 |
18 | sourceSets {
19 | main {
20 | resources {
21 | srcDir rootProject.file("config/dev")
22 | }
23 | }
24 | test {
25 | resources {
26 | srcDir rootProject.file("config/test")
27 | }
28 | }
29 | }
30 |
31 | // Override the default (simulation) with -PenclaveMode=
32 | def mode = findProperty("enclaveMode")?.toString()?.toLowerCase() ?: "mock"
33 |
34 | // Create a task that can be used for generating signing materials
35 | tasks.register("prepareForSigning") {
36 | it.dependsOn(":enclave:generateEnclaveSigningMaterial" + mode.capitalize())
37 | }
38 |
39 | dependencies {
40 | compile project(path: ":enclave", configuration: mode)
41 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
42 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
43 | testCompile "junit:junit:$junit_version"
44 |
45 | // Corda dependencies.
46 | cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
47 | cordaRuntime "$corda_release_group:corda:$corda_release_version"
48 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
49 |
50 | cordapp 'com.protocol180:protocol-aggregator-contracts:0.2.0'
51 | cordapp 'com.protocol180:protocol-aggregator-workflows:0.2.0'
52 | cordapp 'com.protocol180:protocol-aggregator-estuaryStorage:0.2.0'
53 | }
54 |
55 | test {
56 | maxHeapSize = "1024m"
57 | useJUnitPlatform {
58 | includeEngines = ['junit-jupiter', 'junit-vintage']
59 | systemProperty 'junit.jupiter.execution.parallel.enabled', 'true'
60 | systemProperty 'enclaveMode', mode
61 | }
62 | }
--------------------------------------------------------------------------------
/examples/automotive-example/workflows/src/test/resources/Provider1InputData.csv:
--------------------------------------------------------------------------------
1 | manufacturer,brand,model,type,ev,date,country,units,average_price,total_sales
2 | "Tesla","Tesla","Model 3","Sedan","EV","2021-10-01","Argentina",7,63525.16894743328,444676.18263203296
3 | "Tesla","Tesla","Model 3","Sedan","EV","2021-10-01","Australia",60,63307.449682902035,3798446.980974122
4 | "Tesla","Tesla","Model 3","Sedan","EV","2021-10-01","Brazil",138,63115.02566106154,8709873.541226493
5 | "Tesla","Tesla","Model 3","Sedan","EV","2021-10-31","Canada",101,61418.442626873446,6203262.705314218
6 | "Honda","Honda","XR-V","SUV","","2021-12-30","Chile",4,19365.207946454368,77460.83178581747
7 | "Honda","Honda","XR-V","SUV","","2021-12-30","China",537,21523.902082053053,11558335.41806249
8 | "Honda","Honda","XR-V","SUV","","2021-12-30","France",153,20724.411656743563,3170834.9834817653
9 | "Honda","Honda","XR-V","SUV","","2021-12-30","Germany",35,21762.989212617933,761704.6224416277
10 | "Volkswagen","Skoda","Superb","Sedan","","2021-10-01","Chile",9,33078.19396357815,297703.74567220337
11 | "Volkswagen","Skoda","Superb","Sedan","","2021-10-01","China",2404,34391.9902125565,82678344.47098583
12 | "Volkswagen","Skoda","Superb","Sedan","","2021-12-31","France",47,35744.06963084006,1679971.2726494828
13 | "Volkswagen","Skoda","Superb","Sedan","","2021-12-31","Germany",52,35895.12662313691,1866546.5844031193
14 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","Chile",8,64134.23393977269,513073.8715181815
15 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","China",738,65605.09303787399,48416558.661951005
16 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","France",44,60374.37882341187,2656472.6682301224
17 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","Germany",251,62953.076865719835,15801222.293295678
--------------------------------------------------------------------------------
/examples/automotive-example/workflows/src/test/resources/Provider1InputData.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/examples/automotive-example/workflows/src/test/resources/Provider1InputData.zip
--------------------------------------------------------------------------------
/examples/automotive-example/workflows/src/test/resources/Provider2InputData.csv:
--------------------------------------------------------------------------------
1 | manufacturer,brand,model,type,ev,date,country,units,average_price,total_sales
2 | "Honda","Acura","CDX","SUV","","2021-10-01","Argentina",5,75326.09941226066,376630.49706130335
3 | "Honda","Acura","CDX","SUV","","2021-10-01","Australia",11,74653.40074696894,821187.4082166583
4 | "Honda","Acura","CDX","SUV","","2021-10-01","Brazil",54,68479.72213745091,3697904.9954223493
5 | "Honda","Acura","CDX","SUV","","2021-10-01","Canada",14,72434.11654423374,1014077.6316192723
6 | "General Motors","Cadillac","Escalade","SUV","","2021-11-10","Norway",7,99182.18197744276,694275.2738420994
7 | "General Motors","Cadillac","Escalade","SUV","","2021-11-10","Russia",22,106416.56396013765,2341164.4071230283
8 | "General Motors","Cadillac","Escalade","SUV","","2021-11-10","South Africa",26,108109.36702919398,2810843.5427590436
9 | "General Motors","Cadillac","Escalade","SUV","","2021-11-10","Spain",19,103140.33035415388,1959666.2767289237
10 | "Jaguar Land Rover","Jaguar","XKR-S","Sports Car","","2021-12-14","South Africa",5,147221.4711019171,736107.3555095855
11 | "Jaguar Land Rover","Jaguar","XKR-S","Sports Car","","2021-12-14","Spain",12,136625.79607436442,1639509.552892373
12 | "Jaguar Land Rover","Jaguar","XKR-S","Sports Car","","2021-12-14","Sweden",5,139369.71016302545,696848.5508151272
13 | "Jaguar Land Rover","Jaguar","XKR-S","Sports Car","","2021-12-14","Switzerland",4,143537.4915712596,574149.9662850384
14 | "Tesla","Tesla","Model X","SUV","EV","2021-11-20","Germany",191,74166.70726888506,14165841.088357046
15 | "Tesla","Tesla","Model X","SUV","EV","2021-11-20","India",510,73859.754115585,37668474.59894835
16 | "Tesla","Tesla","Model X","SUV","EV","2021-11-20","Indonesia",56,73434.96543153652,4112358.064166045
17 | "Tesla","Tesla","Model X","SUV","EV","2021-11-20","Italy",34,68126.55881431565,2316302.999686732
--------------------------------------------------------------------------------
/examples/automotive-example/workflows/src/test/resources/Provider2InputData.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/examples/automotive-example/workflows/src/test/resources/Provider2InputData.zip
--------------------------------------------------------------------------------
/examples/hotel-bookings/TRADEMARK:
--------------------------------------------------------------------------------
1 | Corda and the Corda logo are trademarks of R3CEV LLC and its affiliates. All rights reserved.
2 |
3 | For R3CEV LLC's trademark and logo usage information, please consult our Trademark Usage Policy at
4 | https://www.r3.com/trademark-policy/.
5 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/compose-codaptor.yml:
--------------------------------------------------------------------------------
1 | # use docker-compose up -d to start the network
2 | # version 3 does not support setting memory limits for docker-compose
3 | version: '2'
4 | services:
5 | codaptora:
6 | image: b180tech/cordaptor:0.4.1-corda4.7
7 | hostname: codaptora
8 | mem_limit: 512m
9 | environment:
10 | - CORDA_RPC_NODE_ADDRESS=host-node:10005 # using hostname known within the Docker network
11 | - CORDA_RPC_USERNAME=user1 # this must match build.gradle
12 | - CORDA_RPC_PASSWORD=test # this must match build.gradle
13 | # we must override Cordaptor's default of binding to the loopback interface,
14 | # because we want its port to be visible on the Docker network
15 | - CORDAPTOR_API_LISTEN_ADDRESS=0.0.0.0:8500
16 | # this is necessary to allow Cordaptor to generate URLs (e.g. for OpenAPI bindings or Location headers)
17 | # using URL resolvable outside the Docker network
18 | - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:9500 # this must be consistent with the ports directive below
19 | ports:
20 | - "9500:8500"
21 | - "9008:8008"
22 | volumes:
23 | # Corda RPC requires CorDapp JARs to be available in the classpath
24 | - ./build/nodes/Host/cordapps:/cordaptor/cordapps
25 | codaptorb:
26 | image: b180tech/cordaptor:0.4.1-corda4.7
27 | hostname: codaptorb
28 | mem_limit: 512m
29 | environment:
30 | - CORDA_RPC_NODE_ADDRESS=providerb-node:10007 # using hostname known within the Docker network
31 | - CORDA_RPC_USERNAME=user1 # this must match build.gradle
32 | - CORDA_RPC_PASSWORD=test # this must match build.gradle
33 | # we must override Cordaptor's default of binding to the loopback interface,
34 | # because we want its port to be visible on the Docker network
35 | - CORDAPTOR_API_LISTEN_ADDRESS=0.0.0.0:8500
36 | # this is necessary to allow Cordaptor to generate URLs (e.g. for OpenAPI bindings or Location headers)
37 | # using URL resolvable outside the Docker network
38 | - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:7500 # this must be consistent with the ports directive below
39 | ports:
40 | - "7500:8500"
41 | - "7008:8008"
42 | volumes:
43 | # Corda RPC requires CorDapp JARs to be available in the classpath
44 | - ./build/nodes/ProviderB/cordapps:/cordaptor/cordapps
45 | codaptorc:
46 | image: b180tech/cordaptor:0.4.1-corda4.7
47 | hostname: codaptorc
48 | mem_limit: 512m
49 | environment:
50 | - CORDA_RPC_NODE_ADDRESS=consumerc-node:10009 # using hostname known within the Docker network
51 | - CORDA_RPC_USERNAME=user1 # this must match build.gradle
52 | - CORDA_RPC_PASSWORD=test # this must match build.gradle
53 | # we must override Cordaptor's default of binding to the loopback interface,
54 | # because we want its port to be visible on the Docker network
55 | - CORDAPTOR_API_LISTEN_ADDRESS=0.0.0.0:8500
56 | # this is necessary to allow Cordaptor to generate URLs (e.g. for OpenAPI bindings or Location headers)
57 | # using URL resolvable outside the Docker network
58 | - CORDAPTOR_API_EXTERNAL_ADDRESS=localhost:6500 # this must be consistent with the ports directive below
59 | ports:
60 | - "6500:8500"
61 | - "6008:8008"
62 | volumes:
63 | # Corda RPC requires CorDapp JARs to be available in the classpath
64 | - ./build/nodes/ConsumerC/cordapps:/cordaptor/cordapps
--------------------------------------------------------------------------------
/examples/hotel-bookings/config/dev/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | logs
6 | node-${hostName}
7 | ${log-path}/archive
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | %highlight{%level{length=1} %d{HH:mm:ss} %T %c{1}.%M - %msg%n}{INFO=white,WARN=red,FATAL=bright red blink}
17 | >
18 |
19 |
20 |
21 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/config/test/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | [%-5level] %d{HH:mm:ss.SSS} [%t] %c{1}.%M - %msg%n
8 | >
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/constants.properties:
--------------------------------------------------------------------------------
1 | cordaReleaseGroup=net.corda
2 | cordaCoreReleaseGroup=net.corda
3 | cordaVersion=4.7
4 | cordaCoreVersion=4.7
5 | gradlePluginsVersion=5.0.12
6 | kotlinVersion=1.2.71
7 | java8MinUpdateVersion=171
8 | junitVersion=4.12
9 | log4jVersion =2.11.2
10 | platformVersion=9
11 | slf4jVersion=1.7.25
12 | quasarVersion=0.7.10
13 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.r3.conclave.enclave'
3 | }
4 |
5 | dependencies {
6 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
7 | implementation "com.r3.conclave:conclave-enclave"
8 |
9 | testImplementation "com.r3.conclave:conclave-host"
10 | testImplementation "org.junit.jupiter:junit-jupiter:5.6.0"
11 |
12 | compile 'com.protocol180:protocol-aggregator-enclave:0.1.6'
13 |
14 | compile group: 'org.apache.avro', name: 'avro', version: '1.10.2'
15 | compile group: 'com.github.luben', name: 'zstd-jni', version: '1.4.9-5'
16 | compile group: 'org.xerial.snappy', name: 'snappy-java', version: '1.1.8.2'
17 | compile group: 'org.tukaani', name: 'xz', version: '1.9'
18 | compile group: 'org.brotli', name: 'dec', version: '0.1.2'
19 | compile group: 'org.osgi', name: 'org.osgi.framework', version: '1.10.0'
20 | }
21 |
22 | conclave {
23 | productID = 1
24 | revocationLevel = 0
25 |
26 | simulation {
27 | signingType = privateKey
28 | signingKey = file("sample_private_key.pem")
29 | }
30 |
31 | debug {
32 | signingType = privateKey
33 | signingKey = file("sample_private_key.pem")
34 | }
35 |
36 | release {
37 | signingType = privateKey
38 | signingKey = file("sample_private_key.pem")
39 | }
40 | }
41 |
42 | test {
43 | useJUnitPlatform()
44 | }
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/sample_private_key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | 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
39 | -----END RSA PRIVATE KEY-----
40 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/src/main/resources/META-INF/native-image/filter.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": [
3 | {
4 | "excludeClasses": "java.net.**"
5 | },
6 | {
7 | "excludeClasses": "com.r3.conclave.host.**"
8 | }
9 | ]
10 | }
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/src/main/resources/META-INF/native-image/jni-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "sun.management.VMManagementImpl",
4 | "fields": [
5 | {
6 | "name": "bootClassPathSupport"
7 | },
8 | {
9 | "name": "compTimeMonitoringSupport"
10 | },
11 | {
12 | "name": "currentThreadCpuTimeSupport"
13 | },
14 | {
15 | "name": "gcNotificationSupport"
16 | },
17 | {
18 | "name": "objectMonitorUsageSupport"
19 | },
20 | {
21 | "name": "otherThreadCpuTimeSupport"
22 | },
23 | {
24 | "name": "remoteDiagnosticCommandsSupport"
25 | },
26 | {
27 | "name": "synchronizerUsageSupport"
28 | },
29 | {
30 | "name": "threadAllocatedMemorySupport"
31 | },
32 | {
33 | "name": "threadContentionMonitoringSupport"
34 | }
35 | ]
36 | }
37 | ]
38 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/src/main/resources/META-INF/native-image/native-image.properties:
--------------------------------------------------------------------------------
1 | Args = -H:IncludeResources=trustedroot.cer
2 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/src/main/resources/META-INF/native-image/proxy-config.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/src/main/resources/META-INF/native-image/resource-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "resources": {
3 | "includes": [
4 | {
5 | "pattern": "\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E"
6 | }
7 | ]
8 | },
9 | "bundles": []
10 | }
11 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/src/main/resources/META-INF/native-image/serialization-config.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/src/main/resources/trustedroot.cer:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICCTCCAbCgAwIBAgIIcFe0qctqSucwCgYIKoZIzj0EAwIwWDEbMBkGA1UEAwwS
3 | Q29yZGEgTm9kZSBSb290IENBMQswCQYDVQQKDAJSMzEOMAwGA1UECwwFY29yZGEx
4 | DzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUswHhcNMTcwNTIyMDAwMDAwWhcN
5 | MjcwNTIwMDAwMDAwWjBYMRswGQYDVQQDDBJDb3JkYSBOb2RlIFJvb3QgQ0ExCzAJ
6 | BgNVBAoMAlIzMQ4wDAYDVQQLDAVjb3JkYTEPMA0GA1UEBwwGTG9uZG9uMQswCQYD
7 | VQQGEwJVSzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGlm6LFHrVkzfuUHin36
8 | Jrm1aUMarX/NUZXw8n8gSiJmsZPlUEplJ+f/lzZMky5EZPTtCciG34pnOP0eiMd/
9 | JTCjZDBiMB0GA1UdDgQWBBR8rqnfuUgBKxOJC5rmRYUcORcHczALBgNVHQ8EBAMC
10 | AYYwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMA8GA1UdEwEB
11 | /wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgDaL4SguKsNeTT7SeUkFdoCBACeG8
12 | GqO4M1KlfimphQwCICiq00hDanT5W8bTLqE7GIGuplf/O8AABlpWrUg6uiUB
13 | -----END CERTIFICATE-----
14 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/enclave/src/test/resources/HotelBookingsSampleData.csv:
--------------------------------------------------------------------------------
1 | customerAge,customerAddress,partySize,bookingDate,roomPrice,hotelLocation,furnished,bookedOnline,cancellation
2 | 34, "village", 5, "2021-03", 42, "City", True, True, True
3 | 44, "small city", 6, "2021-12", 44, "small city", True, True, True
4 | 28, "rural", 6, "2022-01", 33, "London", True, True, True
5 | 42, "small city", 1, "2021-07", 54, "town", False, True, False
6 | 26, "rural", 1, "2021-03", 27, "London", False, True, False
7 | 29, "London", 1, "2021-03", 40, "village", True, True, False
8 | 18, "small city", 4, "2021-07", 23, "City", False, True, True
9 | 48, "small city", 4, "2022-02", 34, "City", True, True, True
10 | 18, "rural", 4, "2021-03", 27, "London", False, True, True
11 | 28, "rural", 4, "2022-02", 41, "London", True, True, True
12 | 18, "rural", 1, "2022-02", 30, "London", False, True, False
13 | 55, "rural", 3, "2021-07", 66, "London", False, True, False
14 | 47, "small city", 1, "2021-07", 61, "City", False, True, False
15 | 66, "town", 6, "2021-12", 66, "small city", False, True, True
16 | 61, "London", 6, "2021-09", 59, "village", True, True, True
17 | 26, "rural", 6, "2021-03", 37, "London", True, True, True
18 | 18, "small city", 4, "2021-06", 32, "village", True, True, False
19 | 27, "village", 4, "2021-04", 31, "City", True, True, True
20 | 37, "City", 1, "2021-08", 51, "village", False, True, True
21 | 21, "rural", 1, "2022-02", 24, "London", False, True, False
--------------------------------------------------------------------------------
/examples/hotel-bookings/gradle.properties:
--------------------------------------------------------------------------------
1 | conclaveVersion=1.2.1
2 | conclaveRepo=../../../conclave-sdk-1.2.1/repo
3 | org.gradle.jvmargs=-Xmx4096m
4 |
5 | name=Hotel Bookings
6 | group=com.protocol180
7 | version=1.0
8 | kotlin.incremental=false
--------------------------------------------------------------------------------
/examples/hotel-bookings/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/examples/hotel-bookings/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/examples/hotel-bookings/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
34 |
35 | @rem Find java.exe
36 | if defined JAVA_HOME goto findJavaFromJavaHome
37 |
38 | set JAVA_EXE=java.exe
39 | %JAVA_EXE% -version >NUL 2>&1
40 | if "%ERRORLEVEL%" == "0" goto init
41 |
42 | echo.
43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
44 | echo.
45 | echo Please set the JAVA_HOME variable in your environment to match the
46 | echo location of your Java installation.
47 |
48 | goto fail
49 |
50 | :findJavaFromJavaHome
51 | set JAVA_HOME=%JAVA_HOME:"=%
52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
53 |
54 | if exist "%JAVA_EXE%" goto init
55 |
56 | echo.
57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
58 | echo.
59 | echo Please set the JAVA_HOME variable in your environment to match the
60 | echo location of your Java installation.
61 |
62 | goto fail
63 |
64 | :init
65 | @rem Get command-line arguments, handling Windows variants
66 |
67 | if not "%OS%" == "Windows_NT" goto win9xME_args
68 |
69 | :win9xME_args
70 | @rem Slurp the command line arguments.
71 | set CMD_LINE_ARGS=
72 | set _SKIP=2
73 |
74 | :win9xME_args_slurp
75 | if "x%~1" == "x" goto execute
76 |
77 | set CMD_LINE_ARGS=%*
78 |
79 | :execute
80 | @rem Setup the command line
81 |
82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
83 |
84 | @rem Execute Gradle
85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
86 |
87 | :end
88 | @rem End local scope for the variables with windows NT shell
89 | if "%ERRORLEVEL%"=="0" goto mainEnd
90 |
91 | :fail
92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
93 | rem the _cmd.exe /c_ return code!
94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
95 | exit /b 1
96 |
97 | :mainEnd
98 | if "%OS%"=="Windows_NT" endlocal
99 |
100 | :omega
101 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/repositories.gradle:
--------------------------------------------------------------------------------
1 | repositories {
2 | mavenLocal()
3 | mavenCentral()
4 | jcenter()
5 | maven { url 'https://jitpack.io' }
6 | maven { url 'https://software.r3.com/artifactory/corda' }
7 | maven { url 'https://repo.gradle.org/gradle/libs-releases' }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/hotel-bookings/settings.gradle:
--------------------------------------------------------------------------------
1 | import java.nio.file.Files
2 | import java.nio.file.Paths
3 |
4 | pluginManagement {
5 | repositories {
6 | maven {
7 | def path = Paths.get(rootDir.absolutePath).resolve(conclaveRepo).toAbsolutePath().normalize()
8 | if (!Files.isDirectory(path.resolve("com"))) {
9 | if (Files.isDirectory(Paths.get("/repo/com"))) {
10 | path = Paths.get("/repo")
11 | } else {
12 | throw new Exception("Neither $path nor /repo seem to exist, or they aren't Maven repositories; it should be the SDK 'repo' subdirectory. " +
13 | "If on macOS, try using the container-gradle script to execute run the tests. See the Conclave CorDapp tutorial on https://docs.conclave.net/writing-cordapps.html")
14 | }
15 | }
16 | url = path.toFile()
17 | }
18 | // Add standard repositories back.
19 | gradlePluginPortal()
20 | jcenter()
21 | mavenCentral()
22 | }
23 |
24 | plugins {
25 | id 'com.r3.conclave.enclave' version conclaveVersion apply false
26 | }
27 | }
28 |
29 | include 'workflows'
30 | include 'enclave'
--------------------------------------------------------------------------------
/examples/hotel-bookings/workflows/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'net.corda.plugins.cordapp'
2 | apply plugin: 'net.corda.plugins.quasar-utils'
3 |
4 | cordapp {
5 | targetPlatformVersion corda_platform_version
6 | minimumPlatformVersion corda_platform_version
7 | workflow {
8 | name "Example-Cordapp Flows"
9 | vendor "Corda Open Source"
10 | licence "Apache License, Version 2.0"
11 | versionId 1
12 | }
13 | signing {
14 | enabled false
15 | }
16 | }
17 |
18 | sourceSets {
19 | main {
20 | resources {
21 | srcDir rootProject.file("config/dev")
22 | }
23 | }
24 | test {
25 | resources {
26 | srcDir rootProject.file("config/test")
27 | }
28 | }
29 | }
30 |
31 | // Override the default (simulation) with -PenclaveMode=
32 | def mode = findProperty("enclaveMode")?.toString()?.toLowerCase() ?: "mock"
33 |
34 | // Create a task that can be used for generating signing materials
35 | tasks.register("prepareForSigning") {
36 | it.dependsOn(":enclave:generateEnclaveSigningMaterial" + mode.capitalize())
37 | }
38 |
39 | dependencies {
40 | compile project(path: ":enclave", configuration: mode)
41 | compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
42 | testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
43 | testCompile "junit:junit:$junit_version"
44 |
45 | // Corda dependencies.
46 | cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
47 | cordaRuntime "$corda_release_group:corda:$corda_release_version"
48 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
49 |
50 | cordapp 'com.protocol180:protocol-aggregator-contracts:0.1.6'
51 | cordapp 'com.protocol180:protocol-aggregator-workflows:0.1.6'
52 | }
--------------------------------------------------------------------------------
/examples/hotel-bookings/workflows/src/test/resources/Provider1InputData.csv:
--------------------------------------------------------------------------------
1 | customerAge,customerAddress,partySize,bookingDate,roomPrice,hotelLocation,furnished,bookedOnline,cancellation
2 | 34, "village", 5, "2021-03", 42, "City", True, True, True
3 | 44, "small city", 6, "2021-12", 44, "small city", True, True, True
4 | 28, "rural", 6, "2022-01", 33, "London", True, True, True
5 | 42, "small city", 1, "2021-07", 54, "town", False, True, False
6 | 26, "rural", 1, "2021-03", 27, "London", False, True, False
7 | 29, "London", 1, "2021-03", 40, "village", True, True, False
8 | 18, "small city", 4, "2021-07", 23, "City", False, True, True
9 | 48, "small city", 4, "2022-02", 34, "City", True, True, True
10 | 18, "rural", 4, "2021-03", 27, "London", False, True, True
11 | 28, "rural", 4, "2022-02", 41, "London", True, True, True
12 | 18, "rural", 1, "2022-02", 30, "London", False, True, False
13 | 55, "rural", 3, "2021-07", 66, "London", False, True, False
14 | 47, "small city", 1, "2021-07", 61, "City", False, True, False
15 | 66, "town", 6, "2021-12", 66, "small city", False, True, True
16 | 61, "London", 6, "2021-09", 59, "village", True, True, True
17 | 26, "rural", 6, "2021-03", 37, "London", True, True, True
18 | 18, "small city", 4, "2021-06", 32, "village", True, True, False
19 | 27, "village", 4, "2021-04", 31, "City", True, True, True
20 | 37, "City", 1, "2021-08", 51, "village", False, True, True
21 | 21, "rural", 1, "2022-02", 24, "London", False, True, False
--------------------------------------------------------------------------------
/examples/hotel-bookings/workflows/src/test/resources/Provider1InputData.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/examples/hotel-bookings/workflows/src/test/resources/Provider1InputData.zip
--------------------------------------------------------------------------------
/examples/hotel-bookings/workflows/src/test/resources/Provider2InputData.csv:
--------------------------------------------------------------------------------
1 | customerAge,customerAddress,partySize,bookingDate,roomPrice,hotelLocation,furnished,bookedOnline,cancellation
2 | 30, "City", 2, "Mar", 42, "small city", False, True, True
3 | 48, "London", 2, "Feb", 65, "rural", False, True, True
4 | 37, "City", 5, "Dec", 28, "village", False, True, True
5 | 20, "town", 8, "Jul", 37, "City", True, True, True
6 | 40, "rural", 4, "Jul", 38, "London", True, True, True
7 | 50, "London", 4, "Mar", 45, "rural", True, True, True
8 | 18, "rural", 1, "Jun", 24, "London", False, True, False
9 | 20, "town", 2, "Mar", 28, "small city", False, True, False
10 | 55, "rural", 2, "Jun", 55, "London", False, True, False
11 | 76, "small city", 1, "Mar", 79, "town", False, True, False
12 | 18, "rural", 4, "Mar", 29, "London", False, True, True
13 | 40, "small city", 3, "Aug", 39, "town", True, True, False
14 | 22, "small city", 5, "Jul", 29, "small city", False, True, True
15 | 61, "town", 6, "Feb", 62, "City", False, True, True
16 | 55, "town", 3, "Dec", 60, "small city", False, True, False
17 | 63, "town", 7, "Feb", 69, "small city", False, True, True
18 | 45, "London", 2, "Mar", 47, "rural", True, True, False
19 | 56, "City", 6, "Jul", 55, "town", False, True, True
20 | 62, "village", 2, "Jul", 73, "City", False, True, False
21 | 18, "town", 6, "Jul", 34, "London", True, True, True
22 | 18, "rural", 6, "Jul", 16, "London", False, True, True
23 | 18, "town", 5, "Jul", 24, "London", False, True, True
24 | 18, "town", 8, "Jul", 34, "London", True, True, True
25 | 70, "village", 7, "Apr", 58, "London", False, True, True
26 | 40, "village", 2, "Aug", 61, "City", False, True, False
27 | 40, "town", 1, "Apr", 49, "small city", True, True, False
28 | 55, "rural", 3, "Sep", 50, "London", False, True, False
29 | 43, "village", 1, "Jun", 53, "London", False, True, False
30 | 80, "rural", 7, "Mar", 81, "London", False, True, True
31 | 42, "London", 6, "Mar", 41, "village", True, True, True
32 | 39, "London", 3, "Apr", 48, "village", True, True, True
33 | 43, "town", 3, "Dec", 59, "small city", False, True, False
34 | 27, "town", 3, "Jul", 40, "small city", True, True, True
35 | 47, "town", 5, "Feb", 45, "City", True, True, True
36 | 55, "rural", 4, "Jul", 60, "London", False, True, True
37 | 44, "small city", 5, "Jun", 45, "small city", True, True, True
38 | 36, "City", 1, "Mar", 50, "rural", False, True, False
39 | 54, "small city", 5, "Oct", 57, "small city", False, True, True
40 | 46, "town", 1, "Jul", 55, "small city", False, True, False
41 | 61, "village", 7, "Dec", 59, "London", False, True, True
--------------------------------------------------------------------------------
/examples/hotel-bookings/workflows/src/test/resources/Provider2InputData.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/examples/hotel-bookings/workflows/src/test/resources/Provider2InputData.zip
--------------------------------------------------------------------------------
/protocolAggregator/.gitignore:
--------------------------------------------------------------------------------
1 | # These are some examples of commonly ignored file patterns.
2 | # You should customize this list as applicable to your project.
3 | # Learn more about .gitignore:
4 | # https://www.atlassian.com/git/tutorials/saving-changes/gitignore
5 |
6 | # Node artifact files
7 | node_modules/
8 | dist/
9 |
10 | # Compiled Java class files
11 | *.class
12 |
13 | # Compiled Python bytecode
14 | *.py[cod]
15 |
16 | # Log files
17 | *.log
18 |
19 | # Package files
20 | *.jar
21 |
22 | # Maven
23 | target/
24 | dist/
25 |
26 | # JetBrains IDE
27 | .idea/
28 |
29 | # Unit test reports
30 | TEST*.xml
31 |
32 | # Generated by MacOS
33 | .DS_Store
34 |
35 | # Generated by Windows
36 | Thumbs.db
37 |
38 | # Applications
39 | *.app
40 | *.exe
41 | *.war
42 |
43 | # Large media files
44 | *.mp4
45 | *.tiff
46 | *.avi
47 | *.flv
48 | *.mov
49 | *.wmv
50 |
51 |
--------------------------------------------------------------------------------
/protocolAggregator/certificates/dump-cordarootca.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | keytool -rfc -export -keystore truststore.jks -alias cordarootca -storepass trustpass
3 |
--------------------------------------------------------------------------------
/protocolAggregator/certificates/truststore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/protocolAggregator/certificates/truststore.jks
--------------------------------------------------------------------------------
/protocolAggregator/config/dev/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | logs
6 | node-${hostName}
7 | ${log-path}/archive
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | %highlight{%level{length=1} %d{HH:mm:ss} %T %c{1}.%M - %msg%n}{INFO=white,WARN=red,FATAL=bright red blink}
17 | >
18 |
19 |
20 |
21 |
23 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/protocolAggregator/config/test/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | [%-5level] %d{HH:mm:ss.SSS} [%t] %c{1}.%M - %msg%n
8 | >
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/protocolAggregator/constants.properties:
--------------------------------------------------------------------------------
1 | cordaReleaseGroup=net.corda
2 | cordaCoreReleaseGroup=net.corda
3 | cordaVersion=4.7
4 | cordaCoreVersion=4.7
5 | gradlePluginsVersion=5.0.12
6 | kotlinVersion=1.2.71
7 | java8MinUpdateVersion=171
8 | junitVersion=4.12
9 | log4jVersion =2.11.2
10 | platformVersion=9
11 | slf4jVersion=1.7.25
12 | dokkaVersion=0.9.17
--------------------------------------------------------------------------------
/protocolAggregator/contracts/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'net.corda.plugins.cordapp'
2 | apply plugin: 'net.corda.plugins.cordformation'
3 | apply plugin: 'net.corda.plugins.quasar-utils'
4 | apply plugin: 'org.jetbrains.dokka'
5 |
6 | cordapp {
7 | targetPlatformVersion corda_platform_version
8 | minimumPlatformVersion corda_platform_version
9 | contract {
10 | name "180Protocol Broker Contracts"
11 | vendor "180Protocol Pte Ltd"
12 | licence "GNU AFFERO GENERAL PUBLIC LICENSE, Version 3.0"
13 | versionId 1
14 | }
15 | }
16 |
17 | sourceSets {
18 | main{
19 | java {
20 | srcDir 'src/main/java'
21 | java.outputDir = file('bin/main')
22 | }
23 | }
24 | test{
25 | java {
26 | srcDir 'src/test/java'
27 | java.outputDir = file('bin/test')
28 | }
29 | }
30 | }
31 |
32 | dokka {
33 | outputFormat = 'gfm'
34 | outputDirectory = "$rootDir/github-docs"
35 | }
36 |
37 | dependencies {
38 | compile "com.r3.conclave:conclave-client:$conclaveVersion"
39 | // Corda dependencies.
40 | cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
41 | cordaRuntime "$corda_release_group:corda:$corda_release_version"
42 | compileOnly "$corda_release_group:corda-testserver-impl:$corda_release_version"
43 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/contracts/CoalitionConfigurationContract.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.contracts
2 |
3 | import com.protocol180.aggregator.states.CoalitionConfigurationState
4 | import net.corda.core.contracts.*
5 | import net.corda.core.transactions.LedgerTransaction
6 |
7 | class CoalitionConfigurationContract : Contract {
8 | companion object {
9 | @JvmStatic
10 | val ID = "com.protocol180.aggregator.contracts.CoalitionConfigurationContract"
11 | }
12 |
13 | /**
14 | * Contract to verify
15 | * @see com.protocol180.aggregator.states.CoalitionConfigurationState produced during the
16 | * @see com.protocol180.aggregator.flow.CoalitionConfigurationUpdateFlow
17 | */
18 | override fun verify(tx: LedgerTransaction) {
19 | val command = tx.commands.requireSingleCommand()
20 |
21 | when (command.value) {
22 | is Commands.Issue -> requireThat {
23 | "No inputs should be consumed when issuing a data output state." using (tx.inputs.isEmpty())
24 | "Only one output state should be created when issuing a data output state." using (tx.outputs.size == 1)
25 | val coalitionConfigurationState = tx.outputsOfType().single()
26 | //TODO: add checks for coalition config state roles and supported data types
27 | }
28 | is Commands.Update -> requireThat {
29 | "Only one input should be consumed when updating a data output state." using (tx.inputs.size == 1)
30 | "Only one output state should be created when issuing a data output state." using (tx.outputs.size == 1)
31 | val coalitionConfigurationState = tx.outputsOfType().single()
32 | //TODO: add checks for coalition config state roles and supported data types
33 | }
34 | }
35 | }
36 |
37 | /**
38 | * Add any commands required for this contract as classes within this interface.
39 | * Commands.Issue - Issues the given state
40 | * Commands.Update - Updates the given state
41 | * function to check for a number of commands which implement this interface.
42 | */
43 | interface Commands : CommandData {
44 |
45 | class Issue : TypeOnlyCommandData(), Commands
46 | class Update : TypeOnlyCommandData(), Commands
47 | }
48 | }
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/contracts/DataOutputContract.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.contracts
2 |
3 | import com.protocol180.aggregator.states.DataOutputState
4 | import net.corda.core.contracts.*
5 | import net.corda.core.transactions.LedgerTransaction
6 |
7 | class DataOutputContract : Contract {
8 | companion object {
9 | @JvmStatic
10 | val ID = "com.protocol180.aggregator.contracts.DataOutputContract"
11 | }
12 |
13 | /**
14 | * Contract to verify
15 | * @see com.protocol180.aggregator.states.DataOutputState produced during the
16 | * @see com.protocol180.aggregator.flow.ConsumerAggregationFlow
17 | */
18 | override fun verify(tx: LedgerTransaction) {
19 | val command = tx.commands.requireSingleCommand()
20 |
21 | when (command.value) {
22 | is Commands.Issue -> requireThat {
23 | "No inputs should be consumed when issuing a data output state." using (tx.inputs.isEmpty())
24 | "Only one output state should be created when issuing a data output state." using (tx.outputs.size == 1)
25 | val dataOutputState = tx.outputsOfType().single()
26 | "A newly issued data output must have a consumer & host" using
27 | (dataOutputState.consumer != null && dataOutputState.host != null)
28 | "The enclave attestation used to create the data output must not be null" using
29 | (dataOutputState.enclaveAttestation != null)
30 | "The data type requested to create the data output must not be null" using
31 | (dataOutputState.dataType != null)
32 | "The description provided to create the data output must not be null" using
33 | (dataOutputState.description != null)
34 | "The flow topic used to create the data output must not be null" using
35 | (dataOutputState.flowTopic != null)
36 | "Only the consumer and host may sign the Data Output State Transaction" using
37 | (command.signers.toSet() == dataOutputState.participants.map { it.owningKey }.toSet())
38 | }
39 |
40 | }
41 | }
42 |
43 | /**
44 | * Add any commands required for this contract as classes within this interface.
45 | * Commands.Issue - Issues the given state
46 | * function to check for a number of commands which implement this interface.
47 | */
48 | interface Commands : CommandData {
49 |
50 | class Issue : TypeOnlyCommandData(), Commands
51 | }
52 | }
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/contracts/RewardsContract.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.contracts
2 |
3 | import com.protocol180.aggregator.states.RewardsState
4 | import net.corda.core.contracts.*
5 | import net.corda.core.transactions.LedgerTransaction
6 |
7 | class RewardsContract: Contract {
8 | companion object {
9 | @JvmStatic
10 | val ID = "com.protocol180.aggregator.contracts.RewardsContract"
11 | }
12 |
13 | /**
14 | * Contract to verify
15 | * @see com.protocol180.aggregator.states.RewardsState produced during the
16 | * @see com.protocol180.aggregator.flow.ConsumerAggregationFlow
17 | */
18 | override fun verify(tx: LedgerTransaction) {
19 | val command = tx.commands.requireSingleCommand()
20 |
21 | when (command.value) {
22 | is Commands.Create -> requireThat {
23 | "No inputs should be consumed when issuing a rewards state." using (tx.inputs.isEmpty())
24 | "Only one rewards state should be created when issuing a rewards state." using (tx.outputs.size == 1)
25 | val rewardsState = tx.outputsOfType().single()
26 | "A newly issued rewards must have a provider & host" using
27 | (rewardsState.provider != null && rewardsState.host != null)
28 | "The enclave attestation used to create the rewards must not be null" using
29 | (rewardsState.enclaveAttestation != null)
30 | "The flow topic used to create the rewards must not be null" using
31 | (rewardsState.flowTopic != null)
32 | "Only the provider and host may sign the Rewards State Transaction" using
33 | (command.signers.toSet() == rewardsState.participants.map { it.owningKey }.toSet())
34 | }
35 |
36 | }
37 | }
38 |
39 | /**
40 | * Add any commands required for this contract as classes within this interface.
41 | * Commands.Issue - Issues the given state
42 | * function to check for a number of commands which implement this interface.
43 | */
44 | interface Commands : CommandData {
45 |
46 | class Create : TypeOnlyCommandData(), Commands
47 | }
48 | }
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/schema/ConsumerAggregationDataOutputSchema.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.schema
2 |
3 | import net.corda.core.schemas.MappedSchema
4 | import java.io.Serializable
5 | import javax.persistence.Column
6 | import javax.persistence.Entity
7 | import javax.persistence.Id
8 | import javax.persistence.Lob
9 | import javax.persistence.Table
10 |
11 | /**
12 | * Schema for storing Consumer Data Outputs generated from
13 | * @see com.protocol180.aggregator.flow.ConsumerDataOutputRetrievalFlow
14 | */
15 | object ConsumerAggregationDataOutputSchema
16 |
17 | object ConsumerAggregationDataOutputSchemaV1 : MappedSchema(schemaFamily = ConsumerAggregationDataOutputSchema.javaClass,
18 | version = 1,
19 | mappedTypes = listOf(ConsumerDataOutput::class.java)) {
20 | @Entity
21 | @Table(name = "CONSUMER_DATA_OUTPUT")
22 | class ConsumerDataOutput(@Id
23 | @Column(name = "flow_id", nullable = false, unique = true)
24 | var flowId: String,
25 | @Lob
26 | @Column(name = "consumer_data_output_bytes", nullable = false)
27 | val consumerDataOutputBytes: ByteArray,
28 | @Column(name = "consumer_output_data_type", nullable = false)
29 | val consumerOutputDataType: String
30 | ) : Serializable {
31 | constructor() : this("", ByteArray(0), "")
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/schema/DecentralizedStorageEncryptionKeySchema.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.schema
2 |
3 | import net.corda.core.schemas.MappedSchema
4 | import java.io.Serializable
5 | import java.time.Instant
6 | import javax.persistence.*
7 |
8 | object DecentralizedStorageEncryptionKeySchema
9 |
10 | object DecentralizedStorageEncryptionKeySchemaV1 : MappedSchema(
11 | schemaFamily = DecentralizedStorageEncryptionKeySchema.javaClass,
12 | version = 1,
13 | mappedTypes = listOf(EncryptionKeyStorage::class.java)
14 | ) {
15 | @Entity
16 | @Table(name = "DECENTRALIZED_STORAGE_ENCRYPTION_KEY")
17 | class EncryptionKeyStorage(
18 | @Id
19 | @Column(name = "flow_id", nullable = false, unique = true)
20 | var flowId: String,
21 | @Lob
22 | @Column(name = "key", nullable = false)
23 | val key: ByteArray,
24 | @Column(name = "ivParameterSpec", nullable = false)
25 | val ivParameterSpec: ByteArray,
26 | @Column(name = "dateCreated", nullable = false)
27 | val dateCreated: Instant
28 | ) : Serializable {
29 | constructor() : this("", ByteArray(0), ByteArray(0), Instant.now())
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/schema/ProviderAggregationInputSchema.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.schema
2 |
3 | import net.corda.core.schemas.MappedSchema
4 | import java.io.Serializable
5 | import javax.persistence.*
6 |
7 | object ProviderAggregationInputSchema
8 |
9 | object ProviderAggregationInputSchemaV1 : MappedSchema(
10 | schemaFamily = ProviderAggregationInputSchema.javaClass,
11 | version = 1,
12 | mappedTypes = listOf(ProviderAggregationInput::class.java)
13 | ) {
14 | @Entity
15 | @Table(name = "PROVIDER_AGGREGATION_INPUT")
16 | class ProviderAggregationInput(
17 | @Id
18 | @Column(name = "dataType", nullable = false, unique = true)
19 | var dataType: String,
20 | @Lob
21 | @Column(name = "input", nullable = false)
22 | val input: ByteArray,
23 | @Column(name = "storageType", nullable = false)
24 | var storageType: String,
25 | @Column(name = "cid", nullable = true)
26 | var cid: String,
27 | @Column(name = "encryptionKeyId", nullable = true)
28 | var encryptionKeyId: String
29 | ) : Serializable {
30 | constructor() : this("", ByteArray(0), "", "", "")
31 | }
32 | }
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/schema/ProviderInputSchema.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.schema
2 |
3 | import net.corda.core.schemas.MappedSchema
4 | import java.io.Serializable
5 | import javax.persistence.*
6 |
7 | /**
8 | * Schema for storing Provider Data Inputs to be used during event based rewards
9 | * @see com.protocol180.aggregator.flow.ConsumerAggregationFlow
10 | */
11 | object ProviderInputSchema
12 |
13 | object ProviderInputSchemaV1 : MappedSchema(schemaFamily = ProviderInputSchema.javaClass,
14 | version = 1,
15 | mappedTypes = listOf(ProviderInput::class.java, DataOutput::class.java)) {
16 | @Entity
17 | @Table(name = "PROVIDER_INPUT")
18 | class ProviderInput(@Id
19 | @GeneratedValue(strategy = GenerationType.IDENTITY)
20 | val id: Int = 0,
21 | @Column(name = "public_key", nullable = false)
22 | var publicKey: String,
23 | @Column(name = "input", nullable = false)
24 | val input: ByteArray
25 | ) : Serializable {
26 | constructor() : this(0, "", ByteArray(0))
27 | constructor(publicKey: String, providerInput: ByteArray) : this(
28 | 0, publicKey, providerInput)
29 | }
30 |
31 | @Entity
32 | @Table(name = "DATA_OUTPUT")
33 | class DataOutput(@Id
34 | @Column(name = "state_ref", nullable = false, unique = true)
35 | val stateRef: String,
36 | @OneToMany(fetch = FetchType.EAGER, cascade = [CascadeType.ALL])
37 | val providerInputs: List
38 | ) : Serializable {
39 | constructor() : this("", listOf())
40 |
41 | }
42 | }
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/schema/ProviderRewardSchema.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.schema
2 |
3 | import net.corda.core.schemas.MappedSchema
4 | import java.io.Serializable
5 | import javax.persistence.Column
6 | import javax.persistence.Entity
7 | import javax.persistence.Id
8 | import javax.persistence.Lob
9 | import javax.persistence.Table
10 |
11 | /**
12 | * Schema for storing Provider Reward Output generated during
13 | * @see com.protocol180.aggregator.flow.ProviderRewardOutputRetrievalFlow
14 | */
15 | object ProviderRewardSchema
16 |
17 | object ProviderRewardSchemaV1 : MappedSchema(schemaFamily = ProviderRewardSchema.javaClass,
18 | version = 1,
19 | mappedTypes = listOf(ProviderReward::class.java)) {
20 | @Entity
21 | @Table(name = "PROVIDER_REWARD")
22 | class ProviderReward(@Id
23 | @Column(name = "flow_id", nullable = false, unique = true)
24 | var flowId: String,
25 | @Lob
26 | @Column(name = "reward_generic_record_bytes", nullable = false)
27 | val rewardGenericRecordBytes: ByteArray,
28 | @Column(name = "reward_output_data_type", nullable = false)
29 | val rewardOutputDataType: String
30 | ) : Serializable {
31 | constructor() : this("", ByteArray(0), "")
32 | }
33 |
34 | }
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/states/DataOutputState.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.states
2 |
3 | import com.protocol180.aggregator.contracts.DataOutputContract
4 | import net.corda.core.contracts.BelongsToContract
5 | import net.corda.core.contracts.ContractState
6 | import net.corda.core.identity.AbstractParty
7 | import net.corda.core.identity.Party
8 | import java.time.Instant
9 |
10 | /**
11 | * State acting as receipt of Data Output compute by host on behalf of client
12 | * @see consumer - consumer for Data Output
13 | * @see host - host running enclave that computes the Data Output
14 | * @see enclaveAttestation - Enclave attestation bytes for verification
15 | * @see dataType - dataType provided by consumer
16 | * @see description - description provided by consumer
17 | * @see flowTopic - Flow topic that resulted in creation of state
18 | * @see encryptionKeyId - Data encryption key ID utilized for encrypting data
19 | * @see storageType - Storage type for the data output state
20 | * @see cid - Filecoin cid for the output in case of Filecoin storage type
21 | */
22 | @BelongsToContract(DataOutputContract::class)
23 | data class DataOutputState(val consumer: Party,
24 | val host: Party,
25 | val dataType: String,
26 | val description: String,
27 | val dateCreated: Instant,
28 | val enclaveAttestation: ByteArray,
29 | val flowTopic: String,
30 | val encryptionKeyId: String,
31 | val storageType: String,
32 | val cid: String
33 | ) : ContractState {
34 |
35 | /**
36 | * This property holds a list of the nodes which can "use" this state in a valid transaction. In this case, the
37 | * consumer or host.
38 | */
39 | override val participants: List get() = listOf(consumer, host)
40 | override fun equals(other: Any?): Boolean {
41 | if (this === other) return true
42 | if (javaClass != other?.javaClass) return false
43 |
44 | other as DataOutputState
45 |
46 | if (consumer != other.consumer) return false
47 | if (host != other.host) return false
48 | if (dataType != other.dataType) return false
49 | if (description != other.description) return false
50 | if (dateCreated != other.dateCreated) return false
51 | if (enclaveAttestation != other.enclaveAttestation) return false
52 | if (flowTopic != other.flowTopic) return false
53 |
54 | return true
55 | }
56 |
57 | override fun hashCode(): Int {
58 | var result = consumer.hashCode()
59 | result = 31 * result + host.hashCode()
60 | result = 31 * result + dateCreated.hashCode()
61 | result = 31 * result + enclaveAttestation.hashCode()
62 | result = 31 * result + flowTopic.hashCode()
63 | return result
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/protocolAggregator/contracts/src/main/kotlin/com/protocol180/aggregator/states/RewardsState.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.states
2 |
3 | import com.protocol180.aggregator.contracts.RewardsContract
4 | import net.corda.core.contracts.BelongsToContract
5 | import net.corda.core.contracts.ContractState
6 | import net.corda.core.identity.AbstractParty
7 | import net.corda.core.identity.Party
8 | import java.time.Instant
9 |
10 | /**
11 | * State acting as rewards receipt for providers who have shared data during aggregations
12 | * @see provider - provider entity sharing data that has been rewarded for
13 | * @see host - host running enclave that computes the Data Output
14 | * @see decryptedRewardsBytes - rewards bytes for provider generated by encalve based rewards engine
15 | * @see enclaveAttestation - Enclave attestation bytes for verification
16 | * @see flowTopic - Flow topic that resulted in creation of state
17 | */
18 | @BelongsToContract(RewardsContract::class)
19 | data class RewardsState(val provider: Party,
20 | val host: Party,
21 | val decryptedRewardsBytes: ByteArray,
22 | val dateCreated: Instant,
23 | val enclaveAttestation: ByteArray,
24 | val flowTopic: String) : ContractState {
25 |
26 | /**
27 | * This property holds a list of the nodes which can "use" this state in a valid transaction. In this case, the
28 | * consumer or host.
29 | */
30 | override val participants: List get() = listOf(host, provider)
31 | override fun equals(other: Any?): Boolean {
32 | if (this === other) return true
33 | if (javaClass != other?.javaClass) return false
34 |
35 | other as RewardsState
36 |
37 | if (provider != other.provider) return false
38 | if (host != other.host) return false
39 | if (!decryptedRewardsBytes.contentEquals(other.decryptedRewardsBytes)) return false
40 | if (dateCreated != other.dateCreated) return false
41 | if (enclaveAttestation != other.enclaveAttestation) return false
42 | if (flowTopic != other.flowTopic) return false
43 |
44 | return true
45 | }
46 |
47 | override fun hashCode(): Int {
48 | var result = provider.hashCode()
49 | result = 31 * result + host.hashCode()
50 | result = 31 * result + decryptedRewardsBytes.contentHashCode()
51 | result = 31 * result + dateCreated.hashCode()
52 | result = 31 * result + enclaveAttestation.hashCode()
53 | result = 31 * result + flowTopic.hashCode()
54 | return result
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/protocolAggregator/enclave/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.r3.conclave.enclave'
3 | id 'org.jetbrains.dokka'
4 | }
5 |
6 | dependencies {
7 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
8 | implementation "com.r3.conclave:conclave-enclave"
9 |
10 | testImplementation "com.r3.conclave:conclave-host"
11 | testImplementation "org.junit.jupiter:junit-jupiter:5.6.0"
12 |
13 | compile group: 'org.apache.avro', name: 'avro', version: '1.11.0'
14 | }
15 |
16 | dokka {
17 | outputFormat = 'gfm'
18 | outputDirectory = "$rootDir/github-docs"
19 | }
20 |
21 | conclave {
22 | productID = 1
23 | revocationLevel = 0
24 |
25 | simulation {
26 | signingType = privateKey
27 | signingKey = file("sample_private_key.pem")
28 | }
29 |
30 | debug {
31 | signingType = privateKey
32 | signingKey = file("sample_private_key.pem")
33 | }
34 |
35 | release {
36 | signingType = privateKey
37 | signingKey = file("sample_private_key.pem")
38 | }
39 | }
40 |
41 | test {
42 | useJUnitPlatform()
43 | }
--------------------------------------------------------------------------------
/protocolAggregator/enclave/sample_private_key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | 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
39 | -----END RSA PRIVATE KEY-----
40 |
--------------------------------------------------------------------------------
/protocolAggregator/enclave/src/main/java/com/protocol180/aggregator/commons/MailType.java:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.commons;
2 |
3 | /**
4 | * Mail Types that can be configured inside a supported coalition Avro schema file
5 | */
6 | public enum MailType {
7 |
8 | TYPE_SCHEMA("schema"),
9 | TYPE_IDENTITIES("identities"),
10 | TYPE_CONSUMER("consumer"),
11 | TYPE_PROVIDER("provider"),
12 | TYPE_REWARDS("rewards");
13 |
14 | public final String type;
15 |
16 | private MailType(String type) {
17 | this.type = type;
18 | }
19 |
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/protocolAggregator/enclave/src/main/resources/META-INF/native-image/filter.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": [
3 | {
4 | "excludeClasses": "java.net.**"
5 | },
6 | {
7 | "excludeClasses": "com.r3.conclave.host.**"
8 | }
9 | ]
10 | }
--------------------------------------------------------------------------------
/protocolAggregator/enclave/src/main/resources/META-INF/native-image/jni-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "sun.management.VMManagementImpl",
4 | "fields": [
5 | {
6 | "name": "bootClassPathSupport"
7 | },
8 | {
9 | "name": "compTimeMonitoringSupport"
10 | },
11 | {
12 | "name": "currentThreadCpuTimeSupport"
13 | },
14 | {
15 | "name": "gcNotificationSupport"
16 | },
17 | {
18 | "name": "objectMonitorUsageSupport"
19 | },
20 | {
21 | "name": "otherThreadCpuTimeSupport"
22 | },
23 | {
24 | "name": "remoteDiagnosticCommandsSupport"
25 | },
26 | {
27 | "name": "synchronizerUsageSupport"
28 | },
29 | {
30 | "name": "threadAllocatedMemorySupport"
31 | },
32 | {
33 | "name": "threadContentionMonitoringSupport"
34 | }
35 | ]
36 | }
37 | ]
38 |
--------------------------------------------------------------------------------
/protocolAggregator/enclave/src/main/resources/META-INF/native-image/native-image.properties:
--------------------------------------------------------------------------------
1 | Args = -H:IncludeResources=trustedroot.cer
2 |
--------------------------------------------------------------------------------
/protocolAggregator/enclave/src/main/resources/META-INF/native-image/proxy-config.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/protocolAggregator/enclave/src/main/resources/META-INF/native-image/resource-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "resources": {
3 | "includes": [
4 | {
5 | "pattern": "\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E"
6 | }
7 | ]
8 | },
9 | "bundles": []
10 | }
11 |
--------------------------------------------------------------------------------
/protocolAggregator/enclave/src/main/resources/META-INF/native-image/serialization-config.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/protocolAggregator/enclave/src/main/resources/trustedroot.cer:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICCTCCAbCgAwIBAgIIcFe0qctqSucwCgYIKoZIzj0EAwIwWDEbMBkGA1UEAwwS
3 | Q29yZGEgTm9kZSBSb290IENBMQswCQYDVQQKDAJSMzEOMAwGA1UECwwFY29yZGEx
4 | DzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUswHhcNMTcwNTIyMDAwMDAwWhcN
5 | MjcwNTIwMDAwMDAwWjBYMRswGQYDVQQDDBJDb3JkYSBOb2RlIFJvb3QgQ0ExCzAJ
6 | BgNVBAoMAlIzMQ4wDAYDVQQLDAVjb3JkYTEPMA0GA1UEBwwGTG9uZG9uMQswCQYD
7 | VQQGEwJVSzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGlm6LFHrVkzfuUHin36
8 | Jrm1aUMarX/NUZXw8n8gSiJmsZPlUEplJ+f/lzZMky5EZPTtCciG34pnOP0eiMd/
9 | JTCjZDBiMB0GA1UdDgQWBBR8rqnfuUgBKxOJC5rmRYUcORcHczALBgNVHQ8EBAMC
10 | AYYwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMA8GA1UdEwEB
11 | /wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgDaL4SguKsNeTT7SeUkFdoCBACeG8
12 | GqO4M1KlfimphQwCICiq00hDanT5W8bTLqE7GIGuplf/O8AABlpWrUg6uiUB
13 | -----END CERTIFICATE-----
14 |
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'net.corda.plugins.cordapp'
2 | apply plugin: 'net.corda.plugins.quasar-utils'
3 |
4 | cordapp {
5 | targetPlatformVersion corda_platform_version
6 | minimumPlatformVersion corda_platform_version
7 | workflow {
8 | name "180 Protocol Estuary Storage"
9 | vendor "180Protocol Pte Ltd"
10 | licence "GNU AFFERO GENERAL PUBLIC LICENSE, Version 3.0"
11 | versionId 1
12 | }
13 | }
14 |
15 | repositories {
16 | jcenter()
17 | }
18 |
19 | dependencies {
20 | compile group: "com.mashape.unirest", name: "unirest-java", version: "1.4.4"
21 | compile group: "com.azure", name: "azure-security-keyvault-keys", version: "4.2.3"
22 | compile group: "com.azure", name: "azure-identity", version: "1.2.0"
23 | testImplementation "org.junit.jupiter:junit-jupiter:5.6.0"
24 |
25 | cordapp project(":contracts")
26 | cordapp project(":workflows")
27 | //corda dependencies
28 | cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
29 | cordaRuntime "$corda_release_group:corda:$corda_release_version"
30 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
31 | }
32 |
33 | test {
34 | useJUnit()
35 | }
36 |
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/shadowJar/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.github.johnrengelman.shadow' version '5.1.0'
3 | id 'java'
4 | }
5 |
6 | java {
7 | sourceCompatibility = JavaVersion.VERSION_1_8
8 | targetCompatibility = JavaVersion.VERSION_1_8
9 | }
10 |
11 | repositories {
12 | jcenter()
13 | }
14 |
15 | dependencies {
16 | implementation 'com.azure:azure-security-keyvault-keys:4.2.3'
17 | implementation 'com.azure:azure-identity:1.2.0'
18 | }
19 |
20 | shadowJar {
21 | relocate 'io.netty', 'azure.shaded.io.netty'
22 | relocate 'META-INF/native/libnetty', 'META-INF/native/libazure_shaded_netty'
23 | relocate 'META-INF/native/netty', 'META-INF/native/azure_shaded_netty'
24 | archiveName = 'azure-keyvault-with-deps.jar'
25 | }
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/main/java/com/protocol180/aggregator/storage/estuary/EstuaryStorageService.java:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.estuary;
2 |
3 | import com.mashape.unirest.http.HttpResponse;
4 | import com.mashape.unirest.http.JsonNode;
5 | import com.mashape.unirest.http.Unirest;
6 | import com.mashape.unirest.http.exceptions.UnirestException;
7 | import net.corda.core.node.AppServiceHub;
8 | import net.corda.core.node.services.CordaService;
9 | import net.corda.core.serialization.SingletonSerializeAsToken;
10 | import org.json.JSONArray;
11 |
12 | import java.io.*;
13 | import java.net.URL;
14 |
15 | @CordaService
16 | public class EstuaryStorageService extends SingletonSerializeAsToken {
17 |
18 | private final AppServiceHub serviceHub;
19 |
20 | public EstuaryStorageService(AppServiceHub serviceHub) {
21 | this.serviceHub = serviceHub;
22 | }
23 |
24 | public String uploadContent(File file, String token) throws EstuaryAPICallException {
25 | try {
26 | HttpResponse jsonResponse = Unirest.post("https://shuttle-4.estuary.tech/content/add")
27 | .header("authorization", "Bearer " + token)
28 | .field("data", file)
29 | .asJson();
30 |
31 | return jsonResponse.getBody().getObject().get("cid").toString();
32 | } catch (UnirestException e) {
33 | throw new EstuaryAPICallException("Api call failed" + e.getMessage());
34 | }
35 | }
36 |
37 | public JSONArray fetchContent(String token) throws EstuaryAPICallException {
38 | try {
39 | HttpResponse jsonResponse = Unirest.get("https://api.estuary.tech/content/list")
40 | .header("authorization", "Bearer " + token)
41 | .asJson();
42 |
43 | return jsonResponse.getBody().getArray();
44 | } catch (UnirestException e) {
45 | throw new EstuaryAPICallException("Api call failed" + e.getMessage());
46 | }
47 | }
48 |
49 | public JSONArray fetchContentByCid(String token, String cid) throws EstuaryAPICallException {
50 | try {
51 | HttpResponse jsonResponse = Unirest.get("https://api.estuary.tech/content/by-cid/" + cid)
52 | .header("authorization", "Bearer " + token)
53 | .asJson();
54 |
55 | return jsonResponse.getBody().getArray();
56 | } catch (UnirestException e) {
57 | throw new EstuaryAPICallException("Api call failed" + e.getMessage());
58 | }
59 | }
60 |
61 | public void downloadFileFromEstuary(String cid) throws IOException, EstuaryAPICallException {
62 | File downloadedFile = new File("downloaded.encrypted");
63 | downloadedFile.createNewFile();
64 | try (BufferedInputStream in = new BufferedInputStream(new URL("https://dweb.link/ipfs/" + cid).openStream());
65 | FileOutputStream fileOutputStream = new FileOutputStream("downloaded.encrypted")) {
66 | byte[] dataBuffer = new byte[1024];
67 | int bytesRead;
68 | while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
69 | fileOutputStream.write(dataBuffer, 0, bytesRead);
70 | }
71 | } catch (IOException e) {
72 | throw new EstuaryAPICallException("Download file from estuary storage failed" + e.getMessage());
73 | }
74 | }
75 | }
76 |
77 | class EstuaryAPICallException extends Exception {
78 | public EstuaryAPICallException(String errorMessage) {
79 | super(errorMessage);
80 | }
81 | }
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/main/java/com/protocol180/aggregator/storage/keyVault/AzureKeyVaultService.java:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.keyVault;
2 |
3 | import com.azure.identity.ClientSecretCredential;
4 | import com.azure.identity.ClientSecretCredentialBuilder;
5 | import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
6 | import com.azure.security.keyvault.keys.cryptography.CryptographyClientBuilder;
7 | import com.azure.security.keyvault.keys.cryptography.models.KeyWrapAlgorithm;
8 | import com.azure.security.keyvault.keys.cryptography.models.UnwrapResult;
9 | import com.azure.security.keyvault.keys.cryptography.models.WrapResult;
10 | import net.corda.core.node.AppServiceHub;
11 | import net.corda.core.node.services.CordaService;
12 | import net.corda.core.serialization.SingletonSerializeAsToken;
13 |
14 | import java.security.NoSuchAlgorithmException;
15 |
16 | @CordaService
17 | public class AzureKeyVaultService extends SingletonSerializeAsToken {
18 |
19 | private final AppServiceHub serviceHub;
20 |
21 | public AzureKeyVaultService(AppServiceHub serviceHub) {
22 | this.serviceHub = serviceHub;
23 | }
24 |
25 | public byte[] wrapKey(String tenantId, String clientId, String clientSecret, String keyIdentifier, byte[] key) throws IllegalArgumentException, NoSuchAlgorithmException {
26 | ClientSecretCredential credential =
27 | new ClientSecretCredentialBuilder().tenantId(tenantId).clientId(clientId).clientSecret(clientSecret).build();
28 |
29 | CryptographyClient cryptoClient = new CryptographyClientBuilder()
30 | .credential(credential)
31 | .keyIdentifier(keyIdentifier)
32 | .buildClient();
33 |
34 | WrapResult wrapResult = cryptoClient.wrapKey(KeyWrapAlgorithm.RSA_OAEP, key);
35 | return wrapResult.getEncryptedKey();
36 | }
37 |
38 | public byte[] unWrapKey(String tenantId, String clientId, String clientSecret, String keyIdentifier, byte[] key) throws IllegalArgumentException, NoSuchAlgorithmException {
39 | ClientSecretCredential credential =
40 | new ClientSecretCredentialBuilder().tenantId(tenantId).clientId(clientId).clientSecret(clientSecret).build();
41 |
42 | CryptographyClient cryptoClient = new CryptographyClientBuilder()
43 | .credential(credential)
44 | .keyIdentifier(keyIdentifier)
45 | .buildClient();
46 |
47 | UnwrapResult unwrapResult = cryptoClient.unwrapKey(KeyWrapAlgorithm.RSA_OAEP, key);
48 | return unwrapResult.getKey();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/main/kotlin/com/protocol180/aggregator/storage/flow/DecentralizedStorageEncryptionKeyRetrievalFlow.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.flow
2 |
3 | import co.paralleluniverse.fibers.Suspendable
4 | import net.corda.core.flows.FlowLogic
5 | import net.corda.core.flows.InitiatingFlow
6 | import net.corda.core.flows.StartableByRPC
7 | import net.corda.core.utilities.ProgressTracker
8 |
9 |
10 | /**
11 | * DecentralizedStorageEncryptionKeyFlow allows storing secret key and ivParameterSpec into db.
12 | */
13 |
14 | @InitiatingFlow
15 | @StartableByRPC
16 | class DecentralizedStorageEncryptionKeyRetrievalFlow : FlowLogic() {
17 | override val progressTracker = ProgressTracker()
18 |
19 | @Suspendable
20 | override fun call(): String {
21 | val decentralizedStorageEncryptionKeyService =
22 | serviceHub.cordaService(DecentralizedStorageEncryptionKeyService::class.java)
23 |
24 | val decentralizedStorageEncryptionKeyRecord =
25 | decentralizedStorageEncryptionKeyService.retrieveLatestDecentralizedStorageEncryptionKey();
26 | return decentralizedStorageEncryptionKeyRecord!!.flowId;
27 | }
28 | }
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/main/kotlin/com/protocol180/aggregator/storage/flow/DecentralizedStorageEncryptionKeyService.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.flow
2 |
3 | import com.protocol180.aggregator.schema.DecentralizedStorageEncryptionKeySchemaV1;
4 | import net.corda.core.node.AppServiceHub
5 | import net.corda.core.node.services.CordaService
6 | import net.corda.core.serialization.SingletonSerializeAsToken
7 | import java.time.Instant
8 |
9 | /**
10 | * Service for Decentralized Storage Encryption Key State vault queries used in the flows.
11 | */
12 | @CordaService
13 | class DecentralizedStorageEncryptionKeyService(val services: AppServiceHub) : SingletonSerializeAsToken() {
14 | /**
15 | * Adds a decentralized storage encryption key into encryption key db store.
16 | */
17 | fun addDecentralizedStorageEncryptionKeyWithFlowId(
18 | flowId: String,
19 | key: ByteArray,
20 | ivParameterSpec: ByteArray
21 | ) {
22 | val decentralizedStorageEncryptionKey =
23 | DecentralizedStorageEncryptionKeySchemaV1.EncryptionKeyStorage(flowId, key, ivParameterSpec, Instant.now())
24 | services.withEntityManager {
25 | persist(decentralizedStorageEncryptionKey)
26 | }
27 | }
28 |
29 | /**
30 | * Retrieves a decentralized storage encryption key using flow id from encryption key db store.
31 | */
32 | fun retrieveDecentralizedStorageEncryptionKeyWithFlowId(flowId: String): DecentralizedStorageEncryptionKeySchemaV1.EncryptionKeyStorage? {
33 | var result: MutableList? = null
34 | services.withEntityManager {
35 | val query =
36 | criteriaBuilder.createQuery(DecentralizedStorageEncryptionKeySchemaV1.EncryptionKeyStorage::class.java)
37 | val type = query.from(DecentralizedStorageEncryptionKeySchemaV1.EncryptionKeyStorage::class.java)
38 | query.select(type).where(criteriaBuilder.equal(type.get>("flowId"), flowId))
39 | result = createQuery(query).resultList
40 | }
41 | if (result?.size == 0)
42 | return null
43 |
44 | return result?.get(0)
45 | }
46 |
47 | /**
48 | * Retrieves the latest decentralized storage encryption key from encryption key db store.
49 | */
50 | fun retrieveLatestDecentralizedStorageEncryptionKey(): DecentralizedStorageEncryptionKeySchemaV1.EncryptionKeyStorage? {
51 | var result: MutableList? = null
52 | services.withEntityManager {
53 | val query =
54 | criteriaBuilder.createQuery(DecentralizedStorageEncryptionKeySchemaV1.EncryptionKeyStorage::class.java)
55 | val type = query.from(DecentralizedStorageEncryptionKeySchemaV1.EncryptionKeyStorage::class.java)
56 | query.select(type).orderBy(criteriaBuilder.desc(type.get("dateCreated")));
57 | result = createQuery(query).resultList
58 | }
59 | if (result?.size == 0)
60 | return null
61 |
62 | return result?.get(0);
63 | }
64 | }
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/main/kotlin/com/protocol180/aggregator/storage/flow/DecentralizedStorageEncryptionKeyUpdateFlow.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.flow
2 |
3 | import co.paralleluniverse.fibers.Suspendable
4 | import com.protocol180.aggregator.flow.NetworkParticipantService
5 | import com.protocol180.aggregator.storage.keyVault.AzureKeyVaultService
6 | import com.protocol180.aggregator.storage.utils.AESUtil
7 | import net.corda.core.flows.FlowLogic
8 | import net.corda.core.flows.InitiatingFlow
9 | import net.corda.core.flows.StartableByRPC
10 | import net.corda.core.utilities.ProgressTracker
11 |
12 |
13 | /**
14 | * DecentralizedStorageEncryptionKeyFlow allows storing secret key and ivParameterSpec into db.
15 | */
16 |
17 | @InitiatingFlow
18 | @StartableByRPC
19 | class DecentralizedStorageEncryptionKeyUpdateFlow() : FlowLogic() {
20 | override val progressTracker = ProgressTracker()
21 |
22 | @Suspendable
23 | override fun call(): String {
24 | val decentralizedStorageEncryptionKeyService =
25 | serviceHub.cordaService(DecentralizedStorageEncryptionKeyService::class.java)
26 | val azureKeyVaultService = serviceHub.cordaService(AzureKeyVaultService::class.java)
27 | val tenantId = serviceHub.cordaService(NetworkParticipantService::class.java).tenantId;
28 | val clientId = serviceHub.cordaService(NetworkParticipantService::class.java).clientId;
29 | val clientSecret = serviceHub.cordaService(NetworkParticipantService::class.java).clientSecret;
30 | val keyIdentifier = serviceHub.cordaService(NetworkParticipantService::class.java).keyIdentifier;
31 |
32 | val dek = AESUtil.convertSecretKeyToBytes(AESUtil.generateKey(256));
33 | val ivParameterSpec = AESUtil.generateIv()
34 | val encryptedDek = azureKeyVaultService.wrapKey(tenantId, clientId, clientSecret, keyIdentifier, dek);
35 |
36 | decentralizedStorageEncryptionKeyService.addDecentralizedStorageEncryptionKeyWithFlowId(
37 | this.runId.uuid.toString(),
38 | encryptedDek,
39 | ivParameterSpec.iv
40 | )
41 |
42 | return this.runId.uuid.toString()
43 | }
44 | }
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/main/kotlin/com/protocol180/aggregator/storage/flow/EstauryStorageProviderAggregationInputFlow.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.flow
2 |
3 | import com.protocol180.aggregator.flow.NetworkParticipantService
4 | import com.protocol180.aggregator.flow.ProviderAggregationInputFlow
5 | import com.protocol180.aggregator.flow.ProviderDBStoreService
6 | import com.protocol180.aggregator.storage.estuary.EstuaryStorageService
7 | import com.protocol180.aggregator.storage.keyVault.AzureKeyVaultService
8 | import com.protocol180.aggregator.storage.utils.AESUtil
9 | import net.corda.core.flows.StartableByRPC
10 | import net.corda.core.utilities.ProgressTracker
11 | import net.corda.core.utilities.loggerFor
12 | import java.io.File
13 | import java.io.InputStream
14 | import javax.crypto.spec.IvParameterSpec
15 |
16 | @StartableByRPC
17 | class EstauryStorageProviderAggregationInputFlow(
18 | private val file: ByteArray,
19 | private val dataType: String,
20 | private val storageType: String,
21 | private val encryptionKeyId: String
22 | ) : ProviderAggregationInputFlow(file, dataType, storageType, encryptionKeyId) {
23 | companion object {
24 | private val log = loggerFor()
25 | }
26 |
27 | override val progressTracker = ProgressTracker()
28 |
29 | override fun storeData(aggregationInputBytes: ByteArray, encryptionKeyId: String) {
30 | val providerDbStoreService = serviceHub.cordaService(ProviderDBStoreService::class.java)
31 | val decentralizedStorageEncryptionKeyService = serviceHub.cordaService(DecentralizedStorageEncryptionKeyService::class.java)
32 | val estuaryStorageService = serviceHub.cordaService(EstuaryStorageService::class.java);
33 | val azureKeyVaultService = serviceHub.cordaService(AzureKeyVaultService::class.java);
34 | val token = serviceHub.cordaService(NetworkParticipantService::class.java).token;
35 | val tenantId = serviceHub.cordaService(NetworkParticipantService::class.java).tenantId;
36 | val clientId = serviceHub.cordaService(NetworkParticipantService::class.java).clientId;
37 | val clientSecret = serviceHub.cordaService(NetworkParticipantService::class.java).clientSecret;
38 | val keyIdentifier = serviceHub.cordaService(NetworkParticipantService::class.java).keyIdentifier;
39 |
40 | val decentralizedStorageEncryptionKeyRecord =
41 | decentralizedStorageEncryptionKeyService.retrieveDecentralizedStorageEncryptionKeyWithFlowId(encryptionKeyId);
42 | val encryptedFile = File("document.encrypted")
43 | val decryptedDek = azureKeyVaultService.unWrapKey(tenantId, clientId, clientSecret, keyIdentifier, decentralizedStorageEncryptionKeyRecord!!.key);
44 | AESUtil.encryptFile(
45 | AESUtil.convertBytesToSecretKey(decryptedDek),
46 | IvParameterSpec(decentralizedStorageEncryptionKeyRecord!!.ivParameterSpec),
47 | aggregationInputBytes,
48 | encryptedFile
49 | )
50 | val uploadFile = File(File("document.encrypted").path)
51 | val cid = estuaryStorageService.uploadContent(uploadFile, token)
52 | val encryptionId = decentralizedStorageEncryptionKeyRecord!!.flowId;
53 | encryptedFile.delete();
54 |
55 | return providerDbStoreService.addProviderAggregationInput(
56 | dataType,
57 | aggregationInputBytes,
58 | storageType,
59 | cid,
60 | encryptionId
61 | )
62 | }
63 | }
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/test/java/com/protocol180/aggregator/storage/keyVault/AzureKeyVaultServiceTest.java:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.keyVault;
2 |
3 | import com.azure.identity.ClientSecretCredential;
4 | import com.azure.identity.ClientSecretCredentialBuilder;
5 | import com.azure.security.keyvault.keys.cryptography.CryptographyClient;
6 | import com.azure.security.keyvault.keys.cryptography.CryptographyClientBuilder;
7 | import com.azure.security.keyvault.keys.cryptography.models.UnwrapResult;
8 | import com.azure.security.keyvault.keys.cryptography.models.WrapResult;
9 | import com.azure.security.keyvault.keys.cryptography.models.KeyWrapAlgorithm;
10 | import com.protocol180.aggregator.storage.utils.AESUtil;
11 | import org.junit.Test;
12 |
13 | import java.security.NoSuchAlgorithmException;
14 |
15 | import static org.junit.jupiter.api.Assertions.assertEquals;
16 |
17 | public class AzureKeyVaultServiceTest {
18 | String tenantId = "c7e48871-70ff-48d5-8934-a8e594bc040b";
19 | String clientId = "dd115d03-42ee-43db-98e1-8b6a475275f8";
20 | String clientSecret = "KEZmQT-~mvUlNS61E1ZBj75W~DrSTZtYKO";
21 | String keyIdentifier = "https://keyvaulttest180p.vault.azure.net/keys/180PTest/06ff554fc7af4be685eec9f841ce2e60";
22 |
23 | /**
24 | * Authenticates with the key vault and shows how to set, get, update and delete a key in the key vault.
25 | *
26 | * @throws IllegalArgumentException when invalid key vault endpoint is passed.
27 | */
28 | @Test
29 | public void keyWrapUnwrapTest() throws IllegalArgumentException, NoSuchAlgorithmException {
30 | // Instantiate a key client that will be used to call the service. Notice that the client is using default Azure
31 | // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
32 | // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
33 | ClientSecretCredential credential =
34 | new ClientSecretCredentialBuilder().tenantId(tenantId).clientId(clientId).clientSecret(clientSecret).build();
35 |
36 | CryptographyClient cryptoClient = new CryptographyClientBuilder()
37 | .credential(credential)
38 | .keyIdentifier(keyIdentifier)
39 | .buildClient();
40 |
41 | byte[] key = AESUtil.generateKey(256).getEncoded();
42 | System.out.println(key.length);
43 |
44 | // Let's wrap a simple dummy key content.
45 | WrapResult wrapResult = cryptoClient.wrapKey(KeyWrapAlgorithm.RSA_OAEP, key);
46 | System.out.printf("Returned encrypted key size is %d bytes with algorithm %s\n", wrapResult.getEncryptedKey().length, wrapResult.getAlgorithm().toString());
47 |
48 | //Let's unwrap the encrypted key response.
49 | UnwrapResult unwrapResult = cryptoClient.unwrapKey(KeyWrapAlgorithm.RSA_OAEP, wrapResult.getEncryptedKey());
50 | System.out.printf("Returned unwrapped key size is %d bytes\n", unwrapResult.getKey().length);
51 |
52 | assertEquals(key.length, unwrapResult.getKey().length);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/test/kotlin/com/protocol180/aggregator/storage/flow/EstuaryStorageFlow.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.flow
2 |
3 | import co.paralleluniverse.fibers.Suspendable
4 | import com.protocol180.aggregator.storage.estuary.EstuaryStorageService
5 | import com.protocol180.aggregator.storage.utils.AESUtil
6 | import net.corda.core.flows.FlowException
7 | import net.corda.core.flows.FlowLogic
8 | import net.corda.core.flows.InitiatingFlow
9 | import net.corda.core.flows.StartableByRPC
10 | import net.corda.core.internal.readFully
11 | import net.corda.core.utilities.ProgressTracker
12 | import java.io.File
13 |
14 |
15 | /**
16 | * EstuaryStorageFlow utilized to test EstuaryStorageService
17 | */
18 |
19 | @InitiatingFlow
20 | @StartableByRPC
21 | class EstuaryStorageFlow(private val token: String) : FlowLogic() {
22 | override val progressTracker = ProgressTracker()
23 |
24 | @Suspendable
25 | @Throws(EstuaryStorageFlowException::class)
26 | override fun call() {
27 | val estuaryStorageService = serviceHub.cordaService(EstuaryStorageService::class.java)
28 | val inputFile = ClassLoader.getSystemClassLoader().getResourceAsStream("Provider2InputData.csv").readFully();
29 | val key = AESUtil.generateKey(256);
30 | val ivParameterSpec = AESUtil.generateIv();
31 | val encryptedFile = File("document.encrypted");
32 | AESUtil.encryptFile(key, ivParameterSpec, inputFile, encryptedFile);
33 | var cid = "";
34 | try {
35 | cid = estuaryStorageService.uploadContent(encryptedFile, token);
36 | } catch (e: Exception) {
37 | throw e.message?.let { EstuaryStorageFlowException(it) }!!;
38 | }
39 |
40 | try {
41 | estuaryStorageService.downloadFileFromEstuary(cid);
42 | val downloadedEncryptedFile = File("downloaded.encrypted");
43 | val downloadedDecryptedFile = File("downloaded.decrypted");
44 | AESUtil.decryptFile(key, ivParameterSpec, downloadedEncryptedFile, downloadedDecryptedFile);
45 | } catch (e: Exception) {
46 | throw e.message?.let { EstuaryStorageFlowException(it) }!!;
47 | }
48 | }
49 | }
50 |
51 | /**
52 | * Thrown when the Estuary Storage Flow fails
53 | */
54 | class EstuaryStorageFlowException(private val reason: String) :
55 | FlowException("Estuary Storage Flow failed: $reason")
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/test/kotlin/com/protocol180/aggregator/storage/flow/EstuaryStorageFlowTest.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.storage.flow
2 |
3 | import net.corda.core.internal.readFully
4 | import net.corda.core.utilities.getOrThrow
5 | import net.corda.testing.node.*
6 | import org.junit.After
7 | import org.junit.Before
8 | import org.junit.Test
9 | import java.io.File
10 | import java.io.IOException
11 | import java.nio.file.Files
12 | import java.nio.file.Paths
13 | import kotlin.test.assertFailsWith
14 | import kotlin.test.assertTrue
15 |
16 | class EstuaryStorageFlowTest {
17 | lateinit var network: MockNetwork
18 | lateinit var consumer: StartedMockNode
19 |
20 | @Before
21 | fun setup() {
22 | network = MockNetwork(
23 | MockNetworkParameters(
24 | cordappsForAllNodes = listOf(
25 | TestCordapp.findCordapp("com.protocol180.aggregator.storage")
26 | )
27 | )
28 | )
29 | consumer = network.createPartyNode(null);
30 | network.runNetwork()
31 | }
32 |
33 | @After
34 | fun tearDown() {
35 | deleteFiles()
36 | network.stopNodes()
37 | }
38 |
39 | private fun deleteFiles() {
40 | try {
41 | val encryptedFile = Paths.get(File("document.encrypted").path);
42 | val downloadedDecryptedFile = Paths.get(File("downloaded.decrypted").path);
43 | val downloadedEncryptedFile = Paths.get(File("downloaded.encrypted").path);
44 | val encryptedFileDeleteResult = Files.deleteIfExists(encryptedFile);
45 | if (encryptedFileDeleteResult) {
46 | println("Encrypted file deleted successfully.")
47 | } else {
48 | println("Encrypted file deletion failed.")
49 | }
50 | val decryptedFileDeleteResult = Files.deleteIfExists(downloadedDecryptedFile);
51 | if (decryptedFileDeleteResult) {
52 | println("Decrypted file deleted successfully.")
53 | } else {
54 | println("Decrypted file deletion failed.")
55 | }
56 | val downloadedFileDeleteResult = Files.deleteIfExists(downloadedEncryptedFile);
57 | if (downloadedFileDeleteResult) {
58 | println("Download file deleted successfully.")
59 | } else {
60 | println("Download file deletion failed.")
61 | }
62 | }catch (e: IOException) {
63 | println("Deletion failed.")
64 | e.printStackTrace()
65 | }
66 | }
67 |
68 | @Test
69 | fun estuaryStorageEncryptionDecryptionFlowFailTest() {
70 | val token = "ESTXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"; // Api key to authenticate estuary apis.
71 | val failFlow = EstuaryStorageFlow(token)
72 | val future = consumer.startFlow(failFlow)
73 | network.runNetwork()
74 | assertFailsWith(EstuaryStorageFlowException::class) { future.getOrThrow() }
75 | deleteFiles()
76 | }
77 |
78 | @Test
79 | fun estuaryStorageEncryptionDecryptionFlowTest() {
80 | val token = "ESTXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"; // Api key to authenticate estuary apis.
81 | val successFlow = EstuaryStorageFlow(token)
82 | val future = consumer.startFlow(successFlow)
83 | network.runNetwork()
84 | //val encoded: ByteArray = ClassLoader.getSystemClassLoader().getResourceAsStream("downloaded.decrypted").readFully()
85 | val encoded: ByteArray = Files.readAllBytes(Paths.get("downloaded.decrypted"))
86 | assertTrue(encoded.isNotEmpty())
87 | println("Download file byte array: $encoded")
88 | deleteFiles()
89 | }
90 | }
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/test/resources/Provider1InputData.csv:
--------------------------------------------------------------------------------
1 | manufacturer,brand,model,type,ev,date,country,units,average_price,total_sales
2 | "Tesla","Tesla","Model 3","Sedan","EV","2021-10-01","Argentina",7,63525.16894743328,444676.18263203296
3 | "Tesla","Tesla","Model 3","Sedan","EV","2021-10-01","Australia",60,63307.449682902035,3798446.980974122
4 | "Tesla","Tesla","Model 3","Sedan","EV","2021-10-01","Brazil",138,63115.02566106154,8709873.541226493
5 | "Tesla","Tesla","Model 3","Sedan","EV","2021-10-31","Canada",101,61418.442626873446,6203262.705314218
6 | "Honda","Honda","XR-V","SUV","","2021-12-30","Chile",4,19365.207946454368,77460.83178581747
7 | "Honda","Honda","XR-V","SUV","","2021-12-30","China",537,21523.902082053053,11558335.41806249
8 | "Honda","Honda","XR-V","SUV","","2021-12-30","France",153,20724.411656743563,3170834.9834817653
9 | "Honda","Honda","XR-V","SUV","","2021-12-30","Germany",35,21762.989212617933,761704.6224416277
10 | "Volkswagen","Skoda","Superb","Sedan","","2021-10-01","Chile",9,33078.19396357815,297703.74567220337
11 | "Volkswagen","Skoda","Superb","Sedan","","2021-10-01","China",2404,34391.9902125565,82678344.47098583
12 | "Volkswagen","Skoda","Superb","Sedan","","2021-12-31","France",47,35744.06963084006,1679971.2726494828
13 | "Volkswagen","Skoda","Superb","Sedan","","2021-12-31","Germany",52,35895.12662313691,1866546.5844031193
14 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","Chile",8,64134.23393977269,513073.8715181815
15 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","China",738,65605.09303787399,48416558.661951005
16 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","France",44,60374.37882341187,2656472.6682301224
17 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","Germany",251,62953.076865719835,15801222.293295678
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/test/resources/Provider1InputData.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/protocolAggregator/estuaryStorage/src/test/resources/Provider1InputData.zip
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/test/resources/Provider2InputData.csv:
--------------------------------------------------------------------------------
1 | manufacturer,brand,model,type,ev,date,country,units,average_price,total_sales
2 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Argentina",7,63525.16894743328,444676.18263203296
3 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Australia",60,63307.449682902035,3798446.980974122
4 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Brazil",138,63115.02566106154,8709873.541226493
5 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Canada",101,61418.442626873446,6203262.705314218
6 | "Honda","Honda","XR-V","SUV","","2022-02-24","Chile",4,19365.207946454368,77460.83178581747
7 | "Honda","Honda","XR-V","SUV","","2022-02-24","China",537,21523.902082053053,11558335.41806249
8 | "Honda","Honda","XR-V","SUV","","2022-02-24","France",153,20724.411656743563,3170834.9834817653
9 | "Honda","Honda","XR-V","SUV","","2022-02-24","Germany",35,21762.989212617933,761704.6224416277
--------------------------------------------------------------------------------
/protocolAggregator/estuaryStorage/src/test/resources/Provider2InputData.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/protocolAggregator/estuaryStorage/src/test/resources/Provider2InputData.zip
--------------------------------------------------------------------------------
/protocolAggregator/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | #Fri Jun 25 14:40:09 GMT 2021
3 | conclaveVersion=1.2.1
4 | version=0.1.8
5 | name=ProtocolBrokerEnclave
6 | conclaveRepo=../../conclave-sdk-1.2.1/repo
7 | group=com.180protocol
8 | org.gradle.jvmargs=-Xmx4096m
9 |
10 | # build versions (-SNAPSHOT at the end triggers deployment to snapshots repo, as opposed to Maven Central)
11 | protocol_aggregator_version=0.1.8-SNAPSHOT
12 |
--------------------------------------------------------------------------------
/protocolAggregator/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/protocolAggregator/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/protocolAggregator/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Aug 25 12:50:39 BST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
7 |
--------------------------------------------------------------------------------
/protocolAggregator/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/protocolAggregator/repositories.gradle:
--------------------------------------------------------------------------------
1 | repositories {
2 | mavenLocal()
3 | mavenCentral()
4 | jcenter()
5 | maven { url 'https://jitpack.io' }
6 | maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
7 | maven { url 'https://repo.gradle.org/gradle/libs-releases' }
8 | }
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'com.r3.conclave.enclave'
3 | id 'org.jetbrains.dokka'
4 | }
5 |
6 | dependencies {
7 | implementation project(':enclave')
8 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
9 | implementation "com.r3.conclave:conclave-enclave"
10 |
11 | testImplementation "com.r3.conclave:conclave-host"
12 | testImplementation "org.junit.jupiter:junit-jupiter:5.6.0"
13 |
14 | compile group: 'org.apache.avro', name: 'avro', version: '1.11.0'
15 | }
16 |
17 | dokka {
18 | outputFormat = 'gfm'
19 | outputDirectory = "$rootDir/github-docs"
20 | }
21 |
22 | conclave {
23 | productID = 1
24 | revocationLevel = 0
25 |
26 | simulation {
27 | signingType = privateKey
28 | signingKey = file("sample_private_key.pem")
29 | }
30 |
31 | debug {
32 | signingType = privateKey
33 | signingKey = file("sample_private_key.pem")
34 | }
35 |
36 | release {
37 | signingType = privateKey
38 | signingKey = file("sample_private_key.pem")
39 | }
40 | }
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/sample_private_key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | 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
39 | -----END RSA PRIVATE KEY-----
40 |
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/src/main/resources/META-INF/native-image/filter.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": [
3 | {
4 | "excludeClasses": "java.net.**"
5 | },
6 | {
7 | "excludeClasses": "com.r3.conclave.host.**"
8 | }
9 | ]
10 | }
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/src/main/resources/META-INF/native-image/jni-config.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "sun.management.VMManagementImpl",
4 | "fields": [
5 | {
6 | "name": "bootClassPathSupport"
7 | },
8 | {
9 | "name": "compTimeMonitoringSupport"
10 | },
11 | {
12 | "name": "currentThreadCpuTimeSupport"
13 | },
14 | {
15 | "name": "gcNotificationSupport"
16 | },
17 | {
18 | "name": "objectMonitorUsageSupport"
19 | },
20 | {
21 | "name": "otherThreadCpuTimeSupport"
22 | },
23 | {
24 | "name": "remoteDiagnosticCommandsSupport"
25 | },
26 | {
27 | "name": "synchronizerUsageSupport"
28 | },
29 | {
30 | "name": "threadAllocatedMemorySupport"
31 | },
32 | {
33 | "name": "threadContentionMonitoringSupport"
34 | }
35 | ]
36 | }
37 | ]
38 |
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/src/main/resources/META-INF/native-image/native-image.properties:
--------------------------------------------------------------------------------
1 | Args = -H:IncludeResources=trustedroot.cer
2 |
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/src/main/resources/META-INF/native-image/proxy-config.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/src/main/resources/META-INF/native-image/resource-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "resources": {
3 | "includes": [
4 | {
5 | "pattern": "\\Qorg/slf4j/impl/StaticLoggerBinder.class\\E"
6 | }
7 | ]
8 | },
9 | "bundles": []
10 | }
11 |
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/src/main/resources/META-INF/native-image/serialization-config.json:
--------------------------------------------------------------------------------
1 | [
2 | ]
3 |
--------------------------------------------------------------------------------
/protocolAggregator/sampleEnclave/src/main/resources/trustedroot.cer:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICCTCCAbCgAwIBAgIIcFe0qctqSucwCgYIKoZIzj0EAwIwWDEbMBkGA1UEAwwS
3 | Q29yZGEgTm9kZSBSb290IENBMQswCQYDVQQKDAJSMzEOMAwGA1UECwwFY29yZGEx
4 | DzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUswHhcNMTcwNTIyMDAwMDAwWhcN
5 | MjcwNTIwMDAwMDAwWjBYMRswGQYDVQQDDBJDb3JkYSBOb2RlIFJvb3QgQ0ExCzAJ
6 | BgNVBAoMAlIzMQ4wDAYDVQQLDAVjb3JkYTEPMA0GA1UEBwwGTG9uZG9uMQswCQYD
7 | VQQGEwJVSzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGlm6LFHrVkzfuUHin36
8 | Jrm1aUMarX/NUZXw8n8gSiJmsZPlUEplJ+f/lzZMky5EZPTtCciG34pnOP0eiMd/
9 | JTCjZDBiMB0GA1UdDgQWBBR8rqnfuUgBKxOJC5rmRYUcORcHczALBgNVHQ8EBAMC
10 | AYYwIwYDVR0lBBwwGgYIKwYBBQUHAwEGCCsGAQUFBwMCBgRVHSUAMA8GA1UdEwEB
11 | /wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgDaL4SguKsNeTT7SeUkFdoCBACeG8
12 | GqO4M1KlfimphQwCICiq00hDanT5W8bTLqE7GIGuplf/O8AABlpWrUg6uiUB
13 | -----END CERTIFICATE-----
14 |
--------------------------------------------------------------------------------
/protocolAggregator/settings.gradle:
--------------------------------------------------------------------------------
1 | import java.nio.file.Files
2 | import java.nio.file.Paths
3 |
4 | pluginManagement {
5 | repositories {
6 | maven {
7 | def path = Paths.get(rootDir.absolutePath).resolve(conclaveRepo).toAbsolutePath().normalize()
8 | if (!Files.isDirectory(path.resolve("com"))) {
9 | if (Files.isDirectory(Paths.get("/repo/com"))) {
10 | path = Paths.get("/repo")
11 | } else {
12 | throw new Exception("Neither $path nor /repo seem to exist, or they aren't Maven repositories; it should be the SDK 'repo' subdirectory. " +
13 | "If on macOS, try using the container-gradle script to execute run the tests. See the Conclave CorDapp tutorial on https://docs.conclave.net/writing-cordapps.html")
14 | }
15 | }
16 | url = path.toFile()
17 | }
18 | // Add standard repositories back.
19 | gradlePluginPortal()
20 | jcenter()
21 | mavenCentral()
22 | }
23 |
24 | plugins {
25 | id 'com.r3.conclave.enclave' version conclaveVersion apply false
26 | }
27 | }
28 |
29 | include 'enclave'
30 | include 'workflows'
31 | include 'contracts'
32 | include 'sampleEnclave'
33 | include 'estuaryStorage'
34 | include "estuaryStorage:shadowJar"
35 |
--------------------------------------------------------------------------------
/protocolAggregator/workflows/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'net.corda.plugins.cordapp'
2 | apply plugin: 'net.corda.plugins.cordformation'
3 | apply plugin: 'net.corda.plugins.quasar-utils'
4 | apply plugin: 'org.jetbrains.dokka'
5 |
6 | cordapp {
7 | targetPlatformVersion corda_platform_version
8 | minimumPlatformVersion corda_platform_version
9 | workflow {
10 | name "180 Protocol Broker Flows"
11 | vendor "180Protocol Pte Ltd"
12 | licence "GNU AFFERO GENERAL PUBLIC LICENSE, Version 3.0"
13 | versionId 1
14 | }
15 | signing {
16 | enabled false
17 | }
18 | }
19 |
20 | sourceSets {
21 | main {
22 | resources {
23 | srcDirs rootProject.file("config/dev"), "src/main/resources"
24 | }
25 | }
26 | test {
27 | resources {
28 | srcDirs rootProject.file("config/test"), "src/test/resources"
29 | }
30 | }
31 | }
32 |
33 | dokka {
34 | outputFormat = 'gfm'
35 | outputDirectory = "$rootDir/github-docs"
36 | }
37 |
38 | // Override the default (simulation) with -PenclaveMode=
39 | def mode = findProperty("enclaveMode")?.toString()?.toLowerCase() ?: "mock"
40 |
41 | // Create a task that can be used for generating signing materials
42 | tasks.register("prepareForSigning") {
43 | it.dependsOn(":enclave:generateEnclaveSigningMaterial" + mode.capitalize())
44 | }
45 |
46 | dependencies {
47 | //only for facilitating testing locally when using protocolAggregator directly using docker compose
48 | //not included in maven artifact
49 | compile project(path: ":sampleEnclave", configuration: mode)
50 |
51 | //external
52 | compile group: 'org.apache.avro', name: 'avro', version: '1.11.0'
53 |
54 | //conclave
55 | compile "com.r3.conclave:conclave-host:$conclaveVersion"
56 | compile "com.r3.conclave:conclave-client:$conclaveVersion"
57 | compile "com.r3.conclave:conclave-common:$conclaveVersion"
58 | compile "com.r3.conclave:conclave-mail:$conclaveVersion"
59 |
60 | //test
61 | testCompile(platform('org.junit:junit-bom:5.7.0'))
62 | testCompile('org.junit.jupiter:junit-jupiter')
63 |
64 | // Corda dependencies.
65 | cordapp project(":contracts")
66 | cordaCompile "$corda_core_release_group:corda-core:$corda_core_release_version"
67 | cordaRuntime "$corda_release_group:corda:$corda_release_version"
68 | testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
69 | }
70 |
71 | test {
72 | maxHeapSize = "1024m"
73 | useJUnitPlatform {
74 | includeEngines = ['junit-jupiter', 'junit-vintage']
75 | systemProperty 'junit.jupiter.execution.parallel.enabled', 'true'
76 | systemProperty 'enclaveMode', mode
77 | }
78 | }
79 |
80 | testlogger {
81 | showFullStackTraces true
82 | }
83 |
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/main/kotlin/com/protocol180/aggregator/flow/CoalitionConfigurationStateService.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.flow
2 |
3 | import com.protocol180.aggregator.states.CoalitionConfigurationState
4 | import net.corda.core.contracts.StateAndRef
5 | import net.corda.core.contracts.UniqueIdentifier
6 | import net.corda.core.identity.AbstractParty
7 | import net.corda.core.node.AppServiceHub
8 | import net.corda.core.node.services.CordaService
9 | import net.corda.core.node.services.Vault
10 | import net.corda.core.node.services.queryBy
11 | import net.corda.core.node.services.vault.QueryCriteria
12 | import net.corda.core.serialization.SingletonSerializeAsToken
13 |
14 | /**
15 | * Service for Coalition Configuration State vault queries used in the flows.
16 | */
17 | @CordaService
18 | class CoalitionConfigurationStateService(private val hub: AppServiceHub) : SingletonSerializeAsToken() {
19 |
20 | /**
21 | * Returns the coalition configuration state for a specific linear id
22 | */
23 | fun findCoalitionConfigurationStateForId(id: UniqueIdentifier) : StateAndRef? =
24 | hub.vaultService.queryBy(
25 | QueryCriteria.LinearStateQueryCriteria(
26 | linearId = listOf(id),
27 | status = Vault.StateStatus.UNCONSUMED,
28 | relevancyStatus = Vault.RelevancyStatus.ALL)).states.singleOrNull()
29 |
30 | /**
31 | * Returns the coalition configuration state for a list of participants
32 | */
33 | fun findCoalitionConfigurationStateForParticipants(participants: List) : StateAndRef? =
34 | hub.vaultService.queryBy(
35 | QueryCriteria.VaultQueryCriteria(
36 | participants = participants,
37 | status = Vault.StateStatus.UNCONSUMED,
38 | relevancyStatus = Vault.RelevancyStatus.ALL)).states.singleOrNull()
39 | }
40 |
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/main/kotlin/com/protocol180/aggregator/flow/ConsumerDBStoreService.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.flow
2 |
3 | import com.protocol180.aggregator.schema.ConsumerAggregationDataOutputSchemaV1
4 | import net.corda.core.node.AppServiceHub
5 | import net.corda.core.node.services.CordaService
6 | import net.corda.core.serialization.SingletonSerializeAsToken
7 |
8 |
9 | /**
10 | * A database service subclass for handling a table used for persisting decrypted consumer aggregation data output bytes
11 | *
12 | * @param services The node's service hub.
13 | */
14 | @CordaService
15 | class ConsumerDBStoreService(val services: AppServiceHub) : SingletonSerializeAsToken() {
16 |
17 | /**
18 | * Adds a decrypted Consumer Data Output Bytes received from enclave into consumer db store.
19 | */
20 | fun addConsumerDataOutputWithFlowId(flowId: String, consumerAggregationDataOutputResponseBytes: ByteArray, dataType: String) {
21 | val decryptedConsumerDataOutput = ConsumerAggregationDataOutputSchemaV1.ConsumerDataOutput(flowId, consumerAggregationDataOutputResponseBytes, dataType)
22 | services.withEntityManager {
23 | persist(decryptedConsumerDataOutput)
24 | }
25 | }
26 |
27 | /**
28 | * Retrieves a decrypted aggregation data output from consumer db store.
29 | */
30 | fun retrieveConsumerDataOutputWithFlowId(flowId: String): ByteArray? {
31 | var result: MutableList? = null
32 | services.withEntityManager {
33 | val query = criteriaBuilder.createQuery(ConsumerAggregationDataOutputSchemaV1.ConsumerDataOutput::class.java)
34 | val type = query.from(ConsumerAggregationDataOutputSchemaV1.ConsumerDataOutput::class.java)
35 | query.select(type).where(criteriaBuilder.equal(type.get>("flowId"), flowId))
36 | result = createQuery(query).resultList
37 | }
38 | if (result?.size == 0)
39 | return null
40 |
41 | val dataOutputBytes = result?.get(0)
42 |
43 | return dataOutputBytes?.consumerDataOutputBytes
44 | }
45 | }
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/main/kotlin/com/protocol180/aggregator/flow/ConsumerDataOutputRetrievalFlow.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.flow
2 |
3 | import co.paralleluniverse.fibers.Suspendable
4 | import net.corda.core.flows.FlowLogic
5 | import net.corda.core.flows.StartableByRPC
6 | import net.corda.core.utilities.ProgressTracker
7 |
8 |
9 | /**
10 | * This is the flow which retrieves the data aggregation outputs stored on a Consumer's node. The consumer receives the
11 | * data output received from the enclave via the host in encrypted form during the [ConsumerAggregationFlow], decrypts it
12 | * and stores it in its local database using the flowId of the [ConsumerAggregationFlow] as the unique id.
13 | * Flow id generated during the consumer aggregation flow needs to be passed to retrieve the appropriate output from the Vault.
14 | * The data is then encoded from Avro format into JSON using Avro's JsonEncoder.
15 | */
16 | @StartableByRPC
17 | class ConsumerDataOutputRetrievalFlow(
18 | private val flowId: String
19 | ) : FlowLogic() {
20 | override val progressTracker = ProgressTracker()
21 |
22 |
23 | @Suspendable
24 | override fun call(): String {
25 | val consumerDbStoreService = serviceHub.cordaService(ConsumerDBStoreService::class.java)
26 | val enclaveClientService = serviceHub.cordaService(EnclaveClientService::class.java)
27 | val consumer = ourIdentity
28 | return enclaveClientService.readJsonFromOutputBytesAndSchema(
29 | consumerDbStoreService.retrieveConsumerDataOutputWithFlowId(
30 | flowId
31 | )!!, "aggregate"
32 | ).toString()
33 | }
34 | }
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/main/kotlin/com/protocol180/aggregator/flow/ProviderAggregationInputFlow.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.flow
2 |
3 | import co.paralleluniverse.fibers.Suspendable
4 | import net.corda.core.flows.*
5 | import net.corda.core.internal.readFully
6 | import net.corda.core.utilities.ProgressTracker
7 | import net.corda.core.utilities.loggerFor
8 | import java.io.File
9 | import java.io.InputStream
10 | import java.nio.file.Files
11 | import java.nio.file.Paths
12 |
13 | @InitiatingFlow
14 | @StartableByRPC
15 | open class ProviderAggregationInputFlow(
16 | private val file: ByteArray,
17 | private val dataType: String,
18 | private val storageType: String,
19 | private val encryptionKeyId: String
20 | ) : FlowLogic() {
21 | companion object {
22 | private val log = loggerFor()
23 | }
24 |
25 | override val progressTracker = ProgressTracker()
26 |
27 | open fun storeData(aggregationInputBytes: ByteArray, encryptionKeyId: String) {
28 | val providerDbStoreService = serviceHub.cordaService(ProviderDBStoreService::class.java)
29 |
30 | return providerDbStoreService.addProviderAggregationInput(
31 | dataType,
32 | aggregationInputBytes,
33 | storageType,
34 | "",
35 | ""
36 | )
37 | }
38 |
39 | @Suspendable
40 | override fun call() {
41 | return storeData(file, encryptionKeyId);
42 | }
43 | }
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/main/kotlin/com/protocol180/aggregator/flow/ProviderRewardOutputRetrievalFlow.kt:
--------------------------------------------------------------------------------
1 | package com.protocol180.aggregator.flow
2 |
3 | import co.paralleluniverse.fibers.Suspendable
4 | import net.corda.core.flows.FlowLogic
5 | import net.corda.core.flows.StartableByRPC
6 | import net.corda.core.utilities.ProgressTracker
7 |
8 | /**
9 | * This is the flow which retrieves the rewards stored on a Provider node. The provider receives the
10 | * rewards received from the enclave via the host in decrypted form during the [ConsumerAggregationFlow], and stores
11 | * it in its local database using the flowId of the [ProviderAggregationResponseFlow] as the unique id. Flow id generated
12 | * during the provider aggregation response flow needs to be passed to retrieve the appropriate output from the Vault.
13 | * The data is then encoded from Avro format into JSON using Avro's JsonEncoder.
14 | */
15 | @StartableByRPC
16 | class ProviderRewardOutputRetrievalFlow(private val flowId: String) : FlowLogic() {
17 |
18 | override val progressTracker = ProgressTracker()
19 |
20 |
21 | @Suspendable
22 | override fun call(): String {
23 |
24 | val providerDbStoreService = serviceHub.cordaService(ProviderDBStoreService::class.java)
25 | val enclaveClientService = serviceHub.cordaService(EnclaveClientService::class.java)
26 | val provider = ourIdentity
27 |
28 | return enclaveClientService.readJsonFromOutputBytesAndSchema(providerDbStoreService.retrieveRewardResponseWithFlowId(flowId)!!, "rewards").toString()
29 | }
30 | }
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/main/resources/envelope.avsc:
--------------------------------------------------------------------------------
1 | {
2 | "namespace": "com.180protocol",
3 | "type": "record",
4 | "name": "Envelope",
5 | "fields": [
6 | {
7 | "name": "aggregateInput",
8 | "type": {
9 | "type" : "record",
10 | "name" : "AggregateInput",
11 | "fields": [
12 | {"name": "creditRating", "type": "string"},
13 | {"name": "sector", "type": "string"},
14 | {"name": "assetType", "type": "string"},
15 | {"name": "duration", "type": "string"},
16 | {"name": "amount", "type": ["null", "int"]}
17 | ]
18 | }
19 | },
20 | {
21 | "name": "aggregateOutput",
22 | "type": {
23 | "type" : "record",
24 | "name" : "AggregateOutput",
25 | "fields": [
26 | {"name": "creditRating", "type": "string"},
27 | {"name": "sector", "type": "string"},
28 | {"name": "assetType", "type": "string"},
29 | {"name": "duration", "type": "string"},
30 | {"name": "amount", "type": ["null", "int"]}
31 | ]
32 | }
33 | },
34 | {
35 | "name": "rewardsOutput",
36 | "type": {
37 | "type" : "record",
38 | "name" : "Rewards",
39 | "fields": [
40 | {"name": "client", "type": "string"},
41 | {"name": "allocation", "type": "int"}
42 | ]
43 | }
44 | }
45 | ]
46 | }
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/test/resources/Provider1InputData.csv:
--------------------------------------------------------------------------------
1 | manufacturer,brand,model,type,ev,date,country,units,average_price,total_sales
2 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Argentina",7,63525.16894743328,444676.18263203296
3 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Australia",60,63307.449682902035,3798446.980974122
4 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Brazil",138,63115.02566106154,8709873.541226493
5 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Canada",101,61418.442626873446,6203262.705314218
6 | "Honda","Honda","XR-V","SUV","","2021-12-30","Chile",4,19365.207946454368,77460.83178581747
7 | "Honda","Honda","XR-V","SUV","","2021-12-30","China",537,21523.902082053053,11558335.41806249
8 | "Honda","Honda","XR-V","SUV","","2021-12-30","France",153,20724.411656743563,3170834.9834817653
9 | "Honda","Honda","XR-V","SUV","","2021-12-30","Germany",35,21762.989212617933,761704.6224416277
10 | "Volkswagen","Skoda","Superb","Sedan","","2022-02-01","Chile",9,33078.19396357815,297703.74567220337
11 | "Volkswagen","Skoda","Superb","Sedan","","2022-02-01","China",2404,34391.9902125565,82678344.47098583
12 | "Volkswagen","Skoda","Superb","Sedan","","2022-02-01","France",47,35744.06963084006,1679971.2726494828
13 | "Volkswagen","Skoda","Superb","Sedan","","2022-02-01","Germany",52,35895.12662313691,1866546.5844031193
14 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","Chile",8,64134.23393977269,513073.8715181815
15 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","China",738,65605.09303787399,48416558.661951005
16 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","France",44,60374.37882341187,2656472.6682301224
17 | "Ford","Lincoln","Navigator","SUV","","2021-12-30","Germany",251,62953.076865719835,15801222.293295678
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/test/resources/Provider1InputData.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/protocolAggregator/workflows/src/test/resources/Provider1InputData.zip
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/test/resources/Provider2InputData.csv:
--------------------------------------------------------------------------------
1 | manufacturer,brand,model,type,ev,date,country,units,average_price,total_sales
2 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Argentina",7,63525.16894743328,444676.18263203296
3 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Australia",60,63307.449682902035,3798446.980974122
4 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Brazil",138,63115.02566106154,8709873.541226493
5 | "Tesla","Tesla","Model 3","Sedan","EV","2022-04-01","Canada",101,61418.442626873446,6203262.705314218
6 | "Honda","Honda","XR-V","SUV","","2022-02-24","Chile",4,19365.207946454368,77460.83178581747
7 | "Honda","Honda","XR-V","SUV","","2022-02-24","China",537,21523.902082053053,11558335.41806249
8 | "Honda","Honda","XR-V","SUV","","2022-02-24","France",153,20724.411656743563,3170834.9834817653
9 | "Honda","Honda","XR-V","SUV","","2022-02-24","Germany",35,21762.989212617933,761704.6224416277
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/test/resources/Provider2InputData.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/180Protocol/180protocol/e187119f6f2c2fb9037ea12b8d3b5bec5a5ae6a2/protocolAggregator/workflows/src/test/resources/Provider2InputData.zip
--------------------------------------------------------------------------------
/protocolAggregator/workflows/src/test/resources/logging.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------