├── app
├── platform
│ ├── fabric
│ │ ├── artifacts
│ │ │ └── operations
│ │ │ │ ├── grafana_conf
│ │ │ │ └── provisioning
│ │ │ │ │ ├── notifiers
│ │ │ │ │ └── .gitkeep
│ │ │ │ │ ├── dashboards
│ │ │ │ │ └── dashboard.yaml
│ │ │ │ │ └── datasources
│ │ │ │ │ └── datasource.yaml
│ │ │ │ └── balance-transfer
│ │ │ │ └── prometheus.yml
│ │ ├── config.json
│ │ ├── e2e-test
│ │ │ └── specs
│ │ │ │ ├── stopexplorer.sh
│ │ │ │ ├── apitest-input-multiprofile-invoke-org1.yml
│ │ │ │ ├── apitest-input-multiprofile-invoke-org2.yml
│ │ │ │ ├── apitest-input-multiprofile-invoke-common.yml
│ │ │ │ ├── validate_hash.sh
│ │ │ │ ├── go.mod
│ │ │ │ ├── templates-v1
│ │ │ │ └── crypto-config.yaml
│ │ │ │ ├── templates-v2
│ │ │ │ └── crypto-config.yaml
│ │ │ │ ├── apitest_suite_test.go
│ │ │ │ └── genchannelartifacts.sh
│ │ ├── utils
│ │ │ └── FabricConst.ts
│ │ ├── service
│ │ │ └── NetworkService.ts
│ │ ├── models
│ │ │ └── User.ts
│ │ └── connection-profile
│ │ │ └── test-network.json
│ └── PlatformBuilder.ts
├── persistence
│ ├── fabric
│ │ └── postgreSQL
│ │ │ └── db
│ │ │ ├── updatepg.sql
│ │ │ ├── processenv.js
│ │ │ └── createdb.sh
│ ├── postgreSQL
│ │ └── CONFIGURE-TLS-CONNECTION-TO-POSTGRESQL.md
│ └── PersistenceFactory.ts
├── appconfig.json
├── test
│ └── expect.ts
├── explorerconfig.json
├── common
│ ├── ExplorerConst.ts
│ └── ExplorerError.ts
├── exportConfig.sh
├── sync
│ ├── sender
│ │ ├── ForkSenderHandler.ts
│ │ └── ExplorerSender.ts
│ ├── SyncBuilder.ts
│ └── listener
│ │ ├── ForkListenerHandler.ts
│ │ └── ExplorerListener.ts
├── middleware
│ └── auth-check.ts
├── model
│ └── User.ts
└── passport
│ └── local-login.ts
├── client
├── .env
├── public
│ ├── favicon.ico
│ └── manifest.json
├── src
│ ├── components
│ │ ├── App
│ │ │ └── index.js
│ │ ├── Theme
│ │ │ └── index.js
│ │ ├── Header
│ │ │ └── index.js
│ │ ├── Footer
│ │ │ ├── index.js
│ │ │ ├── FooterView.js
│ │ │ └── FooterView.spec.js
│ │ ├── Login
│ │ │ └── index.js
│ │ ├── Route
│ │ │ ├── index.js
│ │ │ └── Private.js
│ │ ├── Register
│ │ │ └── index.js
│ │ ├── UsersPanal
│ │ │ └── index.js
│ │ ├── Panels
│ │ │ └── AdminPanel.spec.js
│ │ ├── Styled
│ │ │ ├── DatePicker.spec.js
│ │ │ ├── Table.spec.js
│ │ │ ├── View.js
│ │ │ ├── View.spec.js
│ │ │ └── Select.spec.js
│ │ ├── View
│ │ │ ├── NetworkView.js
│ │ │ ├── ChannelsView.js
│ │ │ ├── NetworkView.spec.js
│ │ │ ├── ChaincodeView.js
│ │ │ ├── ChannelView.js
│ │ │ ├── ChaincodeView.spec.js
│ │ │ ├── ChannelsView.spec.js
│ │ │ ├── BlockView.spec.js
│ │ │ ├── PageNotFound.spec.js
│ │ │ ├── ChaincodeModal.spec.js
│ │ │ └── PageNotFound.js
│ │ ├── ErrorMessage.js
│ │ ├── ErrorMessage.spec.js
│ │ ├── Container.js
│ │ ├── Forms
│ │ │ ├── ChannelForm.spec.js
│ │ │ └── ChaincodeForm.spec.js
│ │ ├── Lists
│ │ │ ├── constants.js
│ │ │ └── PeersHealth.spec.js
│ │ └── Charts
│ │ │ └── OrgPieChart.spec.js
│ ├── static
│ │ ├── images
│ │ │ ├── blockOpen.png
│ │ │ ├── chaincode.jpg
│ │ │ └── Hyperledger_Explorer_Logo_Color.png
│ │ └── css
│ │ │ ├── media-queries.css
│ │ │ └── main-dark.css
│ ├── state
│ │ ├── redux
│ │ │ ├── theme
│ │ │ │ ├── selectors.js
│ │ │ │ ├── types.js
│ │ │ │ ├── actions.js
│ │ │ │ ├── index.js
│ │ │ │ ├── reducers.js
│ │ │ │ └── tests.spec.js
│ │ │ ├── index.js
│ │ │ ├── charts
│ │ │ │ ├── index.js
│ │ │ │ ├── selectors.js
│ │ │ │ └── types.js
│ │ │ ├── tables
│ │ │ │ ├── index.js
│ │ │ │ └── types.js
│ │ │ └── auth
│ │ │ │ ├── index.js
│ │ │ │ ├── selectors.js
│ │ │ │ ├── types.js
│ │ │ │ ├── actions.js
│ │ │ │ └── reducers.js
│ │ ├── store.js
│ │ └── Auth.js
│ ├── FabricVersion.js
│ ├── config.js
│ ├── services
│ │ ├── __mocks__
│ │ │ └── request.js
│ │ └── request.js
│ ├── setupTests.js
│ └── index.js
├── e2e-test
│ ├── .mocharc.json
│ ├── configs
│ │ ├── config_guitest.json
│ │ └── connection-profile
│ │ │ └── org1-network-for-guitest.json
│ ├── package.json
│ ├── docker-compose-explorer.yaml
│ ├── specs
│ │ ├── utils
│ │ │ └── helper.js
│ │ └── network
│ │ │ └── network.test.js
│ └── E2E-TEST-README.md
└── .gitignore
├── examples
└── net1
│ ├── .gitignore
│ ├── crypto
│ └── .gitignore
│ ├── config.json
│ ├── config-ca.json
│ └── connection-profile
│ ├── test-network.json
│ └── test-network-ca.json
├── docs
├── source
│ ├── images
│ │ ├── Jira.png
│ │ ├── Jira4.png
│ │ ├── AddSSH1.png
│ │ ├── logs_dir.png
│ │ ├── GitCloneCmd.png
│ │ ├── lf-sandbox-a.png
│ │ ├── UserRegisterGUI.png
│ │ ├── gerritSettings.png
│ │ └── Hyperledger_Explorer_Logo_Color.png
│ ├── _static
│ │ ├── images
│ │ │ ├── logs_db.png
│ │ │ ├── hl_login.png
│ │ │ ├── host_sync.png
│ │ │ ├── logs_app.png
│ │ │ ├── GitCloneCmd.png
│ │ │ ├── azure_jobs.png
│ │ │ ├── azure_runs.png
│ │ │ ├── hl_dashboard.png
│ │ │ ├── hl_network.png
│ │ │ ├── hle_tx_list.png
│ │ │ ├── local_sync.png
│ │ │ ├── logs_console.png
│ │ │ ├── logs_subdirs.png
│ │ │ ├── sync_process.png
│ │ │ ├── diagram_routes.png
│ │ │ ├── hl_block_list.png
│ │ │ ├── hl_chaincodes.png
│ │ │ ├── hl_dark_theme.png
│ │ │ ├── hl_tx_details.png
│ │ │ ├── hle_dashboard.png
│ │ │ ├── azure_hlexplorer.png
│ │ │ ├── db_model_diagram.png
│ │ │ ├── diagram_main_js.png
│ │ │ ├── diagram_sync_js.png
│ │ │ ├── hl_block_filter.png
│ │ │ ├── hl_channel_list.png
│ │ │ ├── hl_swagger_home.png
│ │ │ ├── hl_sync_diagram.png
│ │ │ ├── hl_ui_high_level.png
│ │ │ ├── azure_code_coverage.png
│ │ │ ├── db_service_diagram.png
│ │ │ ├── diagram_explorer_js.png
│ │ │ ├── hl_blocks_per_hour.png
│ │ │ ├── hl_new_user_window.png
│ │ │ ├── hl_transaction_list.png
│ │ │ ├── hl_tx_count_minute.png
│ │ │ ├── clone_download_button.png
│ │ │ ├── diagram_gateway_class.png
│ │ │ ├── diagram_sync_package.png
│ │ │ ├── hl_blocks_per_minute.png
│ │ │ ├── hl_latest_block_icon.png
│ │ │ ├── hl_tx_count_per_hour.png
│ │ │ ├── hl_user_registration.png
│ │ │ ├── diagram_synchronizer_js.png
│ │ │ ├── hl_block_details_window.png
│ │ │ ├── hl_explorer_architecture.png
│ │ │ ├── diagram_persistence_package.png
│ │ │ ├── diagram_client_app_components.png
│ │ │ ├── hl_link_icon_to_block_details.png
│ │ │ ├── azure_code_coverage_single_file.png
│ │ │ ├── hl_new_block_notification_panel.png
│ │ │ └── hl_block_details_notification_panel.png
│ │ └── css
│ │ │ └── styles.css
│ ├── architecture
│ │ ├── index.rst
│ │ ├── logs_app.html
│ │ ├── logs_db.html
│ │ ├── synchronizer.html
│ │ ├── index.html
│ │ ├── logs_console.html
│ │ ├── restapi.html
│ │ ├── routes.html
│ │ ├── webserver.html
│ │ ├── databaselayer.html
│ │ ├── hl_ui_high_level.html
│ │ ├── dbservices.html
│ │ ├── gateway.html
│ │ ├── websockets.html
│ │ ├── websockets.rst
│ │ ├── webserver.rst
│ │ ├── backend.rst
│ │ ├── databaselayer.rst
│ │ ├── hl_ui_high_level.rst
│ │ └── dbservices.rst
│ ├── presentation
│ │ ├── hl_login.html
│ │ ├── hl_tx_count_minute.html
│ │ ├── hl_dashboard.html
│ │ ├── hl_blocks_per_minute.html
│ │ ├── hl_network.html
│ │ ├── hl_tx_count_per_hour.html
│ │ ├── hl_block_list.html
│ │ ├── hl_chaincodes.html
│ │ ├── hl_dark_theme.html
│ │ ├── hl_transaction_list.html
│ │ ├── hl_tx_details.html
│ │ ├── hl_blocks_per_hour.html
│ │ ├── hl_channel_list.html
│ │ ├── hl_filter_window.html
│ │ ├── hl_block_details_window.html
│ │ └── hl_block_details_notification_panel.html
│ ├── dev-setup
│ │ ├── azure.rst
│ │ ├── github_setup.html
│ │ ├── clone_button.html
│ │ └── build.rst
│ ├── architecture.rst
│ ├── Style-guides
│ │ └── js-style.rst
│ ├── index.rst
│ └── repos.rst
├── project_lifecycle
│ ├── active.md
│ ├── end-of-life.md
│ ├── project-incubation-exit-criteria.md
│ ├── deprecated.md
│ ├── proposal.md
│ ├── README.md
│ └── first-major-release.md
├── custom_theme
│ └── searchbox.html
├── requirements.txt
└── Makefile
├── ssl-certs
└── read.txt
├── devenv
└── diagrams
│ └── app
│ ├── explorer.png
│ ├── platform.png
│ └── persistance.png
├── CODEOWNERS
├── syncstop.sh
├── .env
├── .mocharc.json
├── .dockerignore
├── test
└── api
│ ├── config.json
│ ├── config_single.json
│ ├── config_single-pem.json
│ ├── config_single-disable-auth.json
│ ├── config_multi.json
│ └── connection-profile
│ ├── test-network.json
│ ├── org1-network-disable-auth.json
│ └── test-network-ca.json
├── .github
├── ISSUE_TEMPLATE
│ ├── config.yaml
│ ├── enhancement.yaml
│ └── bug-report.yaml
├── settings.yml
├── workflows
│ ├── test.yaml
│ ├── sonar.yml
│ └── build.yaml
└── PULL_REQUEST_TEMPLATE.md
├── monitor.sh
├── release_notes
├── v0.3.5.1.md
├── v0.3.6.1.md
├── v0.3.9.3.md
├── v0.3.7.md
├── v1.0.0-rc1.md
├── v0.3.9.md
├── v1.1.5.md
├── v1.1.2.md
├── v0.3.9.4.md
├── v0.3.9.5.md
├── v1.1.8.md
├── v0.3.4.md
├── v1.1.7.md
├── v1.1.6.md
└── v1.1.0.md
├── run_e2e_test.sh
├── lgtm.yml
├── stop.sh
├── .sonarcloud.properties
├── .editorconfig
├── .nycrc.json
├── keygenerator.sh
├── scripts
├── changelog.sh
└── release.sh
├── CODE_OF_CONDUCT.md
├── .eslintignore
├── docker-compose-testdb.yaml
├── DCO.md
├── NOTICE
├── CONFIG-HTTPS-HLEXPLORER.md
├── ci
├── install_deps.yml
├── azure-pipelines-release.yml
└── azure-pipelines.yml
├── sonar-project.properties
├── .gitignore
├── postgres-Dockerfile
├── syncstart.sh
├── start.sh
├── SECURITY.md
└── main.sh
/app/platform/fabric/artifacts/operations/grafana_conf/provisioning/notifiers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/.env:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | EXTEND_ESLINT=true
--------------------------------------------------------------------------------
/examples/net1/.gitignore:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: Apache-2.0
2 | **/crypto
3 | **/crypto-config
4 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/client/public/favicon.ico
--------------------------------------------------------------------------------
/app/persistence/fabric/postgreSQL/db/updatepg.sql:
--------------------------------------------------------------------------------
1 | --
2 | -- SPDX-License-Identifier: Apache-2.0
3 | --
4 | \c :dbname;
5 |
--------------------------------------------------------------------------------
/docs/source/images/Jira.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/Jira.png
--------------------------------------------------------------------------------
/docs/source/images/Jira4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/Jira4.png
--------------------------------------------------------------------------------
/ssl-certs/read.txt:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | Directory for storing keys, and certificates.
--------------------------------------------------------------------------------
/docs/source/images/AddSSH1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/AddSSH1.png
--------------------------------------------------------------------------------
/devenv/diagrams/app/explorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/devenv/diagrams/app/explorer.png
--------------------------------------------------------------------------------
/devenv/diagrams/app/platform.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/devenv/diagrams/app/platform.png
--------------------------------------------------------------------------------
/docs/source/images/logs_dir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/logs_dir.png
--------------------------------------------------------------------------------
/client/src/components/App/index.js:
--------------------------------------------------------------------------------
1 | //SPDX-License-Identifier: Apache-2.0
2 |
3 | import App from './App';
4 |
5 | export default App;
6 |
--------------------------------------------------------------------------------
/client/src/components/Theme/index.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | import Theme from './Theme';
3 |
4 | export default Theme;
5 |
--------------------------------------------------------------------------------
/devenv/diagrams/app/persistance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/devenv/diagrams/app/persistance.png
--------------------------------------------------------------------------------
/docs/source/images/GitCloneCmd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/GitCloneCmd.png
--------------------------------------------------------------------------------
/docs/source/images/lf-sandbox-a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/lf-sandbox-a.png
--------------------------------------------------------------------------------
/examples/net1/crypto/.gitignore:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 | ordererOrganizations/
5 | peerOrganizations/
6 |
7 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: Apache-2.0
2 |
3 | # Blockchain Explorer Committers
4 | * @hyperledger-labs/blockchain-explorer
5 |
--------------------------------------------------------------------------------
/client/src/static/images/blockOpen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/client/src/static/images/blockOpen.png
--------------------------------------------------------------------------------
/client/src/static/images/chaincode.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/client/src/static/images/chaincode.jpg
--------------------------------------------------------------------------------
/docs/source/_static/images/logs_db.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/logs_db.png
--------------------------------------------------------------------------------
/docs/source/images/UserRegisterGUI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/UserRegisterGUI.png
--------------------------------------------------------------------------------
/docs/source/images/gerritSettings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/gerritSettings.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_login.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_login.png
--------------------------------------------------------------------------------
/docs/source/_static/images/host_sync.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/host_sync.png
--------------------------------------------------------------------------------
/docs/source/_static/images/logs_app.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/logs_app.png
--------------------------------------------------------------------------------
/docs/source/_static/images/GitCloneCmd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/GitCloneCmd.png
--------------------------------------------------------------------------------
/docs/source/_static/images/azure_jobs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/azure_jobs.png
--------------------------------------------------------------------------------
/docs/source/_static/images/azure_runs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/azure_runs.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_dashboard.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_network.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_network.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hle_tx_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hle_tx_list.png
--------------------------------------------------------------------------------
/docs/source/_static/images/local_sync.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/local_sync.png
--------------------------------------------------------------------------------
/docs/source/_static/images/logs_console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/logs_console.png
--------------------------------------------------------------------------------
/docs/source/_static/images/logs_subdirs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/logs_subdirs.png
--------------------------------------------------------------------------------
/docs/source/_static/images/sync_process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/sync_process.png
--------------------------------------------------------------------------------
/client/src/components/Header/index.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | import HeaderView from './HeaderView';
3 |
4 | export default HeaderView;
5 |
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_routes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_routes.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_block_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_block_list.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_chaincodes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_chaincodes.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_dark_theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_dark_theme.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_tx_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_tx_details.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hle_dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hle_dashboard.png
--------------------------------------------------------------------------------
/app/appconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "sslEnabled": false,
3 | "sslCertsPath": "ssl-certs",
4 | "host": "localhost",
5 | "port": "8080",
6 | "license": "Apache-2.0"
7 | }
8 |
--------------------------------------------------------------------------------
/client/src/components/Footer/index.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | import FooterView from './FooterView';
4 |
5 | export default FooterView;
6 |
--------------------------------------------------------------------------------
/client/src/components/Login/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import Login from './Login';
6 |
7 | export default Login;
8 |
--------------------------------------------------------------------------------
/client/src/state/redux/theme/selectors.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | export const modeSelector = state => state.theme.mode;
6 |
--------------------------------------------------------------------------------
/docs/source/_static/images/azure_hlexplorer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/azure_hlexplorer.png
--------------------------------------------------------------------------------
/docs/source/_static/images/db_model_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/db_model_diagram.png
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_main_js.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_main_js.png
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_sync_js.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_sync_js.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_block_filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_block_filter.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_channel_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_channel_list.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_swagger_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_swagger_home.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_sync_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_sync_diagram.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_ui_high_level.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_ui_high_level.png
--------------------------------------------------------------------------------
/syncstop.sh:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | kill -15 $(ps aux | grep 'sync.js' | grep -v grep | awk '{print $2}')
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/client/src/components/Route/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import Private from './Private';
6 |
7 | export default Private;
8 |
--------------------------------------------------------------------------------
/docs/source/_static/images/azure_code_coverage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/azure_code_coverage.png
--------------------------------------------------------------------------------
/docs/source/_static/images/db_service_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/db_service_diagram.png
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_explorer_js.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_explorer_js.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_blocks_per_hour.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_blocks_per_hour.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_new_user_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_new_user_window.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_transaction_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_transaction_list.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_tx_count_minute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_tx_count_minute.png
--------------------------------------------------------------------------------
/docs/source/_static/images/clone_download_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/clone_download_button.png
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_gateway_class.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_gateway_class.png
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_sync_package.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_sync_package.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_blocks_per_minute.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_blocks_per_minute.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_latest_block_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_latest_block_icon.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_tx_count_per_hour.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_tx_count_per_hour.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_user_registration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_user_registration.png
--------------------------------------------------------------------------------
/client/e2e-test/.mocharc.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch-extensions": "js",
3 | "recursive": true,
4 | "spec": ["./specs/**/*.test.js"],
5 | "timeout": 20000,
6 | "extension": ["js"]
7 | }
8 |
--------------------------------------------------------------------------------
/client/src/components/Register/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import Register from './Register';
6 |
7 | export default Register;
8 |
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_synchronizer_js.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_synchronizer_js.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_block_details_window.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_block_details_window.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_explorer_architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_explorer_architecture.png
--------------------------------------------------------------------------------
/docs/source/images/Hyperledger_Explorer_Logo_Color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/images/Hyperledger_Explorer_Logo_Color.png
--------------------------------------------------------------------------------
/client/src/components/UsersPanal/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import UsersPanal from './UsersPanal';
6 |
7 | export default UsersPanal;
8 |
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_persistence_package.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_persistence_package.png
--------------------------------------------------------------------------------
/client/src/static/images/Hyperledger_Explorer_Logo_Color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/client/src/static/images/Hyperledger_Explorer_Logo_Color.png
--------------------------------------------------------------------------------
/docs/source/_static/images/diagram_client_app_components.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/diagram_client_app_components.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_link_icon_to_block_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_link_icon_to_block_details.png
--------------------------------------------------------------------------------
/docs/source/_static/images/azure_code_coverage_single_file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/azure_code_coverage_single_file.png
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_new_block_notification_panel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_new_block_notification_panel.png
--------------------------------------------------------------------------------
/client/src/FabricVersion.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | // add new version of fabric here
4 | const FabricVersion = ['v2.5', 'v2.4', 'v2.2'];
5 |
6 | export default FabricVersion;
7 |
--------------------------------------------------------------------------------
/docs/source/_static/images/hl_block_details_notification_panel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger-labs/blockchain-explorer/HEAD/docs/source/_static/images/hl_block_details_notification_panel.png
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | PORT=8080
2 | EXPLORER_CONFIG_FILE_PATH=./examples/net1/config.json
3 | EXPLORER_PROFILE_DIR_PATH=./examples/net1/connection-profile
4 | FABRIC_CRYPTO_PATH=/fabric-path/fabric-samples/test-network/organizations
--------------------------------------------------------------------------------
/.mocharc.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": "./node_modules/ts-node/register",
3 | "watch-extensions": "ts",
4 | "recursive": true,
5 | "spec": ["./app/test/**/*.test.ts"],
6 | "timeout": 10000,
7 | "extension": ["ts"]
8 | }
9 |
--------------------------------------------------------------------------------
/client/src/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import config from 'react-global-configuration';
6 |
7 | config.set({ api: 'web3' });
8 |
9 | export default config;
10 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 |
2 | #SPDX-License-Identifier: Apache-2.0
3 | **/node_modules/
4 | client/build/
5 | wallet/
6 | logs/
7 | **/e2e-test/
8 | **/test/
9 | *.md
10 | docs/
11 | examples/
12 | .dockerignore
13 | .git
14 |
--------------------------------------------------------------------------------
/test/api/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "test-network": {
4 | "name": "Test Network",
5 | "profile": "./connection-profile/test-network.json"
6 | }
7 | },
8 | "license": "Apache-2.0"
9 | }
10 |
--------------------------------------------------------------------------------
/app/persistence/fabric/postgreSQL/db/processenv.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | const fs = require('fs');
4 |
5 | const data = JSON.stringify(process.env);
6 | fs.writeFileSync('/tmp/process.env.json', data);
7 |
--------------------------------------------------------------------------------
/docs/project_lifecycle/active.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Active
4 |
5 | - Hyperledger Explorer is in the Incubation phase
6 |
7 |
--------------------------------------------------------------------------------
/examples/net1/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "test-network": {
4 | "name": "Test Network",
5 | "profile": "./connection-profile/test-network.json"
6 | }
7 | },
8 | "license": "Apache-2.0"
9 | }
10 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yaml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Support Request
4 | url: https://discord.gg/hyperledger
5 | about: Support request or question relating to Hyperledger Explorer
6 |
--------------------------------------------------------------------------------
/examples/net1/config-ca.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "test-network": {
4 | "name": "Test Network",
5 | "profile": "./connection-profile/test-network-ca.json"
6 | }
7 | },
8 | "license": "Apache-2.0"
9 | }
10 |
--------------------------------------------------------------------------------
/test/api/config_single.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "org1-network": {
4 | "name": "org1-network",
5 | "profile": "./connection-profile/org1-network.json"
6 | }
7 | },
8 | "license": "Apache-2.0"
9 | }
10 |
--------------------------------------------------------------------------------
/test/api/config_single-pem.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "org1-network": {
4 | "name": "org1-network",
5 | "profile": "./connection-profile/org1-network-pem.json"
6 | }
7 | },
8 | "license": "Apache-2.0"
9 | }
10 |
--------------------------------------------------------------------------------
/docs/project_lifecycle/end-of-life.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## End of Life
4 |
5 | - A project that is no longer actively developed or maintained.
6 |
7 |
--------------------------------------------------------------------------------
/client/e2e-test/configs/config_guitest.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "org1-network": {
4 | "name": "org1-network",
5 | "profile": "./connection-profile/org1-network-for-guitest.json"
6 | }
7 | },
8 | "license": "Apache-2.0"
9 | }
10 |
--------------------------------------------------------------------------------
/client/src/state/redux/theme/types.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | const namespaces = 'theme';
6 |
7 | const CHANGE_THEME = `${namespaces}/CHANGE_THEME`;
8 |
9 | export default {
10 | CHANGE_THEME,
11 | };
12 |
--------------------------------------------------------------------------------
/test/api/config_single-disable-auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "org1-network": {
4 | "name": "org1-network",
5 | "profile": "./connection-profile/org1-network-disable-auth.json"
6 | }
7 | },
8 | "license": "Apache-2.0"
9 | }
10 |
--------------------------------------------------------------------------------
/client/src/services/__mocks__/request.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | // TODO add request mocks
6 | const countHeader = {
7 | chaincodeCount: 1,
8 | txCount: 10,
9 | latestBlock: 5,
10 | peerCount: 1,
11 | };
12 |
--------------------------------------------------------------------------------
/app/platform/fabric/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "test-network": {
4 | "name": "Test Network",
5 | "profile": "./connection-profile/test-network.json",
6 | "bootMode": "ALL",
7 | "noOfBlocks": 0
8 | }
9 | },
10 | "license": "Apache-2.0"
11 | }
12 |
--------------------------------------------------------------------------------
/monitor.sh:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | #!/bin/bash
6 |
7 | while [ 1 ];do
8 | sleep 10
9 | process_num=$(ps -elf | grep -v grep | grep main.js | wc -l)
10 | if [ ${process_num} -eq 0 ];then
11 | ./start.sh
12 | fi
13 | done
14 |
--------------------------------------------------------------------------------
/docs/source/architecture/index.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | Hyperledger Explorer Architecture
6 | ----------------------------------
7 |
8 | The high-level architecture of Hyperledger Explorer
9 |
10 | .. raw:: html
11 | :file: ./index.html
12 |
13 |
--------------------------------------------------------------------------------
/client/src/state/redux/theme/actions.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import types from './types';
6 |
7 | export const changeTheme = mode => ({
8 | type: types.CHANGE_THEME,
9 | payload: { mode }
10 | });
11 |
12 | export default {
13 | changeTheme
14 | };
15 |
--------------------------------------------------------------------------------
/app/test/expect.ts:
--------------------------------------------------------------------------------
1 | /*
2 | *SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import chai from 'chai';
6 | import chaiAsPromised from 'chai-as-promised';
7 | import sinonChai from 'sinon-chai';
8 |
9 | chai.use(chaiAsPromised);
10 | chai.use(sinonChai);
11 |
12 | export const expect = chai.expect;
13 |
--------------------------------------------------------------------------------
/.github/settings.yml:
--------------------------------------------------------------------------------
1 | repository:
2 | name: blockchain-explorer
3 | default_branch: main
4 | has_downloads: true
5 | has_issues: true
6 | has_projects: false
7 | has_wiki: false
8 | archived: false
9 | private: false
10 | allow_squash_merge: false
11 | allow_merge_commit: false
12 | allow_rebase_merge: true
13 |
--------------------------------------------------------------------------------
/docs/project_lifecycle/project-incubation-exit-criteria.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## Project Incubation Exit Criteria
5 |
6 | - [Project Incubation Exit Criteria](https://wiki.hyperledger.org/display/HYP/Project+Incubation+Exit+Criteria)
7 |
--------------------------------------------------------------------------------
/release_notes/v0.3.5.1.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## New Features
5 |
6 | ## Bug Fixes and Updates
7 |
8 | * BE-460 Dockerized app fixes
9 |
10 | * Applied tag v0.3.5.1
11 |
12 | ## Known Vulnerabilities
13 |
14 | ## Resolved Vulnerabilities
15 |
--------------------------------------------------------------------------------
/test/api/config_multi.json:
--------------------------------------------------------------------------------
1 | {
2 | "network-configs": {
3 | "org1-network": {
4 | "name": "org1 network",
5 | "profile": "./connection-profile/org1-network.json"
6 | },
7 | "org2-network": {
8 | "name": "org2 network",
9 | "profile": "./connection-profile/org2-network.json"
10 | }
11 | },
12 | "license": "Apache-2.0"
13 | }
14 |
--------------------------------------------------------------------------------
/docs/custom_theme/searchbox.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/platform/fabric/artifacts/operations/grafana_conf/provisioning/dashboards/dashboard.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: 1
2 |
3 | providers:
4 | - name: 'default'
5 | orgId: 1
6 | folder: ''
7 | type: file
8 | disableDeletion: false
9 | updateIntervalSeconds: 10 #how often Grafana will scan for changed dashboards
10 | options:
11 | path: /var/lib/grafana/dashboards
--------------------------------------------------------------------------------
/release_notes/v0.3.6.1.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## New Features
5 |
6 | ## Bug Fixes and Updates
7 |
8 | * BE-462 Modify deploy docker to use createdb.sh
9 | * Applied tag v0.3.6.1
10 |
11 | ## Known Vulnerabilities
12 |
13 | ## Resolved Vulnerabilities
14 |
--------------------------------------------------------------------------------
/run_e2e_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # SPDX-License-Identifier: Apache-2.0
4 |
5 |
6 | # Prerequisition:
7 | # - Install Hyperledger Fabric container images and tools (by running fabric-samples/scripts/bootstrap.sh)
8 | # You also need to add these tool location to PATH
9 | # - Install python, pip and virtualenv
10 |
11 | npm install
12 | npm run e2e-api-test
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | # dependencies
6 | /node_modules
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/client/e2e-test/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "e2e-test",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "wdio.conf.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "devDependencies": {
12 | "mocha": "^8.2.1",
13 | "playwright": "^1.7.1",
14 | "ts-node": "^9.1.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/client/src/state/redux/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { default as auth } from './auth';
6 | import { default as charts } from './charts';
7 | import { default as tables } from './tables';
8 | import { default as theme } from './theme';
9 |
10 | export { auth };
11 | export { charts };
12 | export { tables };
13 | export { theme };
14 |
--------------------------------------------------------------------------------
/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "hyperledgerexplorer",
3 | "name": "Hyperledger Explorer",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "128x128",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff",
15 | "license": "Apache-2.0"
16 | }
17 |
--------------------------------------------------------------------------------
/client/src/state/redux/theme/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import reducer from './reducers';
6 | import themeTypes from './types';
7 | import * as themeSelectors from './selectors';
8 | import * as themeActions from './actions';
9 |
10 | export { themeTypes };
11 | export { themeSelectors };
12 | export { themeActions };
13 |
14 | export default reducer;
15 |
--------------------------------------------------------------------------------
/client/src/state/redux/charts/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import reducer from './reducers';
6 | import chartOperations from './operations';
7 | import chartTypes from './types';
8 | import * as chartSelectors from './selectors';
9 |
10 | export { chartOperations };
11 | export { chartTypes };
12 | export { chartSelectors };
13 |
14 | export default reducer;
15 |
--------------------------------------------------------------------------------
/app/platform/fabric/artifacts/operations/grafana_conf/provisioning/datasources/datasource.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: 1
2 |
3 | deleteDatasources:
4 | - name: 'Prometheus'
5 | orgId: 1
6 |
7 | datasources:
8 | - name: 'Prometheus'
9 | type: 'prometheus'
10 | access: 'direct'
11 | orgId: 1
12 | url: 'http://localhost:9090'
13 | isDefault: true
14 | version: 1
15 | editable: false
16 |
17 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: Apache-2.0
2 |
3 | python-markdown-math==0.2
4 |
5 | alabaster==0.7.8
6 | Babel==2.3.4
7 | docutils==0.12
8 | imagesize==0.7.1
9 | Jinja2==2.11.3
10 | MarkupSafe==0.23
11 | Pygments==2.7.4
12 | pytz==2016.4
13 | six==1.10.0
14 | snowballstemmer==1.2.1
15 | Sphinx==1.7.2
16 | sphinx-rtd-theme==0.2.5b2
17 | recommonmark==0.4.0
18 | sphinxcontrib-contentui==0.2.2
19 |
--------------------------------------------------------------------------------
/client/src/state/redux/tables/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import reducer from './reducers';
6 | import { default as tableOperations } from './operations';
7 | import { default as tableTypes } from './types';
8 | import * as tableSelectors from './selectors';
9 |
10 | export { tableOperations };
11 | export { tableTypes };
12 | export { tableSelectors };
13 |
14 | export default reducer;
15 |
--------------------------------------------------------------------------------
/lgtm.yml:
--------------------------------------------------------------------------------
1 |
2 | # SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | path_classifiers:
6 | queries:
7 | - exclude: "js/unused-local-variable"
8 | - exclude: "js/stack-trace-exposure"
9 | - exclude: "js/useless-assignment-to-local"
10 | - exclude: "js/react/unused-or-undefined-state-property"
11 | - exclude: "js/superfluous-trailing-arguments"
12 | extraction:
13 | javascript:
14 | index:
15 | exclude: "app/platform/fabric/e2e-test"
16 |
--------------------------------------------------------------------------------
/release_notes/v0.3.9.3.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * none
6 |
7 | ## Bug Fixes and Updates
8 |
9 | * Fixed PgService.js renaming issue, and added missing connection-profile files
10 | * Applied tag v0.3.9.3
11 |
12 | ## Known Vulnerabilities
13 |
14 | * none
15 |
16 | ## Resolved Vulnerabilities
17 |
18 | * n/a
19 |
20 |
21 |
--------------------------------------------------------------------------------
/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 |
7 | EXPLORER_PROCESS_ID=$(ps aux | grep -v "awk" | awk '/name - hyperledger-explorer/ {print $2}')
8 |
9 | if [ $EXPLORER_PROCESS_ID > 0 ]
10 | then
11 | echo 'Stopping node process hyperledger-explorer, id ' $EXPLORER_PROCESS_ID
12 | kill -SIGTERM $EXPLORER_PROCESS_ID
13 | else
14 | echo 'No process name hyperledger-explorer found'
15 | fi
16 |
17 |
--------------------------------------------------------------------------------
/app/explorerconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "persistence": "postgreSQL",
3 | "platforms": ["fabric"],
4 | "postgreSQL": {
5 | "host": "127.0.0.1",
6 | "port": "5432",
7 | "database": "fabricexplorer",
8 | "username": "hppoc",
9 | "passwd": "password"
10 | },
11 | "sync": {
12 | "type": "local",
13 | "platform": "fabric",
14 | "blocksSyncTime": "1"
15 | },
16 | "jwt": {
17 | "secret": "a secret phrase!!",
18 | "expiresIn": "2h"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/common/ExplorerConst.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier= Apache-2.0
3 | */
4 |
5 | /**
6 | * Explorer constants
7 | */
8 | /* eslint-disable no-shadow */
9 | export enum explorerConst {
10 | PERSISTENCE = 'persistence',
11 | PLATFORMS = 'platforms',
12 | PLATFORM_FABRIC = 'fabric',
13 | PERSISTENCE_POSTGRESQL = 'postgreSQL',
14 | SYNC_TYPE_LOCAL = 'local',
15 | SYNC_TYPE_HOST = 'host',
16 | HEALTHZ = 'healthz',
17 | METRICS = 'metrics'
18 | }
19 |
--------------------------------------------------------------------------------
/.sonarcloud.properties:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | # Path to sources
6 | sonar.sources=.
7 | sonar.exclusions=**/e2e-test/**,**/test/**,docs/**/*,devenv/**/*,client/**/*.spec.js
8 | #sonar.inclusions=
9 |
10 | # Path to tests
11 | #sonar.tests=
12 | #sonar.test.exclusions=
13 | #sonar.test.inclusions=
14 |
15 | # Source encoding
16 | #sonar.sourceEncoding=UTF-8
17 |
18 | # Exclusions for copy-paste detection
19 | #sonar.cpd.exclusions=
--------------------------------------------------------------------------------
/client/src/components/Panels/AdminPanel.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | import AdminPanel from './AdminPanel';
5 |
6 | const setup = () => {
7 | const wrapper = shallow();
8 |
9 | return {
10 | wrapper
11 | };
12 | };
13 |
14 | describe('AdminPanel', () => {
15 | test('AdminPanel component should render', () => {
16 | const { wrapper } = setup();
17 | expect(wrapper.exists()).toBe(true);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/client/src/components/Styled/DatePicker.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | import DatePicker from './DatePicker';
5 |
6 | const setup = () => {
7 | const wrapper = shallow();
8 |
9 | return {
10 | wrapper
11 | };
12 | };
13 |
14 | describe('DatePicker', () => {
15 | test('DatePicker component should render', () => {
16 | const { wrapper } = setup();
17 | expect(wrapper.exists()).toBe(true);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/docs/project_lifecycle/deprecated.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Deprecated
4 |
5 | - A Deprecated project will be maintained for a six month period by its community, after which it will be removed from any subsequent formal releases. Notice will be given to the public of the project’s deprecation. After the six-month deprecation period, the project will be labeled End of Life.
6 |
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | root = true
6 |
7 | [*]
8 | # tabbed indentation:
9 | indent_style = tab
10 | indent_size = 1
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | insert_final_newline = true
14 | end_of_line = lf
15 | # editorconfig-tools is unable to ignore longs strings or urls
16 | max_line_length = null
17 | [*.{md,txt}]
18 | indent_style = space
19 | indent_size = 4
20 | trim_trailing_whitespace = true
21 |
--------------------------------------------------------------------------------
/client/src/state/redux/auth/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import reducer from './reducers';
6 | import authTypes from './types';
7 |
8 | import authOperations from './operations';
9 | import * as authSelectors from './selectors';
10 | import * as authActions from './actions';
11 |
12 | export { authTypes };
13 | export { authSelectors };
14 | export { authActions };
15 | export { authOperations };
16 |
17 | export default reducer;
18 |
--------------------------------------------------------------------------------
/client/src/state/redux/theme/reducers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import types from './types';
6 |
7 | /* Reducers for Dashboard Charts */
8 | const themeReducer = (state = { mode: 'light' }, action = {}) => {
9 | if (action.type === types.CHANGE_THEME) {
10 | return {
11 | ...state,
12 | mode: action.payload.mode,
13 | };
14 | } else {
15 | return state;
16 | }
17 | };
18 |
19 | export default themeReducer;
20 |
--------------------------------------------------------------------------------
/docs/source/_static/css/styles.css:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: Apache-2.0 */
2 |
3 | input[type='checkbox'] {
4 | display: none;
5 | }
6 |
7 | .container img {
8 | margin: 0px;
9 | transition: transform 0.25s ease;
10 | cursor: zoom-in;
11 | overflow-y: auto;
12 | overflow-x: auto;
13 | display: block;
14 | }
15 |
16 | input[type='checkbox']:checked ~ label > img {
17 | transform: scale(1.2);
18 | /*transform-origin: left; */
19 | transform-origin: 0 0;
20 | cursor: zoom-out;
21 | }
22 |
--------------------------------------------------------------------------------
/app/exportConfig.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | echo "should be sourced"
4 | jq . ./explorerconfig.json >/dev/null
5 |
6 | export DATABASE_HOST=$(jq -r '.postgreSQL.host' ./explorerconfig.json)
7 | export DATABASE_PORT=$(jq -r '.postgreSQL.port' ./explorerconfig.json)
8 | export DATABASE_USERNAME=$(jq -r '.postgreSQL.username' ./explorerconfig.json)
9 | export DATABASE_DATABASE=$(jq -r '.postgreSQL.database' ./explorerconfig.json)
10 | export DATABASE_PASSWD=$(jq -r '.postgreSQL.passwd' ./explorerconfig.json)
11 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/client/src/components/View/NetworkView.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import View from '../Styled/View';
7 | import Peers from '../Lists/Peers';
8 | import { peerListType } from '../types';
9 |
10 | export const NetworkView = ({ peerList }) => (
11 |
12 |
13 |
14 | );
15 |
16 | NetworkView.propTypes = {
17 | peerList: peerListType.isRequired,
18 | };
19 |
20 | export default NetworkView;
21 |
--------------------------------------------------------------------------------
/.nycrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@istanbuljs/nyc-config-typescript",
3 | "require": ["ts-node/register"],
4 | "extension": [".ts"],
5 | "reporter": ["lcov", "text-summary"],
6 | "sourceMap": true,
7 | "instrument": true,
8 | "temp-dir": "app/test/.nyc_output",
9 | "report-dir": "app/test/coverage",
10 | "all": true,
11 | "include": ["app"],
12 | "exclude": ["**/e2e-test", "app/test"],
13 | "check-coverage": false,
14 | "branches": 80,
15 | "lines": 80,
16 | "functions": 80,
17 | "statements": 80
18 | }
19 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/stopexplorer.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # SPDX-License-Identifier: Apache-2.0
4 |
5 | ROOTPATH="$( cd "$(dirname "$0")/../../../../.." >/dev/null 2>&1 ; pwd -P )"
6 | CLEANUP=1
7 |
8 | while getopts "k" opt; do
9 | case "$opt" in
10 | k)
11 | echo "keep DB data and wallet"
12 | CLEANUP=0
13 | ;;
14 | esac
15 | done
16 |
17 | pushd ${ROOTPATH}
18 |
19 | if [ $CLEANUP -eq 1 ]; then
20 | docker-compose down -v
21 | else
22 | docker-compose down
23 | fi
24 |
25 | popd
--------------------------------------------------------------------------------
/docs/project_lifecycle/proposal.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Proposal
4 |
5 |
6 | - Hyperledger Explorer project was proposed by Christopher Ferris (IBM), Dan Middleton (Intel) and Pardha Vishnumolakala (DTCC)
7 |
8 | - See more about proposal on [wiki](https://wiki.hyperledger.org/display/explorer/Hyperledger+Explorer), and [Google documents](https://docs.google.com/document/d/1Z8uR_w9E9XITEe88PzkLjzH9t5bPivUhQO8OiEP7s_U/edit)
9 |
--------------------------------------------------------------------------------
/client/src/state/redux/auth/selectors.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | export const authSelector = state => state.auth.token;
6 |
7 | export const errorSelector = state => state.auth.error;
8 |
9 | export const networkSelector = state => state.auth.networks;
10 |
11 | export const registeredSelector = state => state.auth.registered;
12 |
13 | export const userlistSelector = state => state.auth.userlists;
14 |
15 | export const unregisteredSelector = state => state.auth.unregistered;
16 |
--------------------------------------------------------------------------------
/docs/source/architecture/logs_app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/architecture/logs_db.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/client/src/components/View/ChannelsView.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import View from '../Styled/View';
7 | import Channels from '../Lists/Channels';
8 | import { channelsType } from '../types';
9 |
10 | export const ChannelsView = ({ channels }) => (
11 |
12 |
13 |
14 | );
15 |
16 | ChannelsView.propTypes = {
17 | channels: channelsType.isRequired,
18 | };
19 |
20 | export default ChannelsView;
21 |
--------------------------------------------------------------------------------
/app/common/ExplorerError.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import util from 'util';
6 |
7 | /**
8 | *
9 | * @param {*} args {
10 | * %s - String.
11 | * %d - Number (both integer and float).
12 | * %j - JSON.
13 | * %% - single percent sign ('%'). This does not consume an argument.
14 | * }
15 | */
16 | export function ExplorerError(...args: string[]) {
17 | Error.captureStackTrace(this, this.constructor);
18 | this.name = this.constructor.name;
19 | this.message = util.format(args);
20 | }
21 |
--------------------------------------------------------------------------------
/docs/source/architecture/synchronizer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/source/dev-setup/azure.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | Azure DevOps
6 | -------------
7 |
8 | Hyperledger Explorer uses `Azure DevOps `__ to automate the builds, run tests, and code coverage.
9 | After the pull request is created an automated job will be triggered defined by the `Azure pipeline script `__.
10 |
11 |
12 | .. raw:: html
13 | :file: ./azure.html
14 |
--------------------------------------------------------------------------------
/docs/source/architecture/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/architecture/logs_console.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/architecture/restapi.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/architecture/routes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/architecture/webserver.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/source/architecture.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | Architecture Reference
6 | ----------------------
7 |
8 |
9 |
10 | .. short overview of the HL Explorer architecture
11 |
12 |
13 | .. toctree::
14 | :maxdepth: 1
15 |
16 | architecture/index
17 | architecture/hl_ui_high_level
18 | architecture/backend
19 | architecture/databaselayer
20 |
21 |
22 |
23 | .. Licensed under Creative Commons Attribution 4.0 International License
24 | https://creativecommons.org/licenses/by/4.0/
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/source/architecture/databaselayer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/architecture/hl_ui_high_level.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/source/dev-setup/github_setup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Clone the project
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_tx_count_minute.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/client/src/state/redux/auth/types.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | const namespaces = 'auth';
6 |
7 | const LOGIN = `${namespaces}/LOGIN`;
8 |
9 | const NETWORK = `${namespaces}/NETWORK`;
10 |
11 | const ERROR = `${namespaces}/ERROR`;
12 |
13 | const REGISTER = `${namespaces}/REGISTER`;
14 |
15 | const UNREGISTER = `${namespaces}/UNREGISTER`;
16 |
17 | const USERLIST = `${namespaces}/USERLIST`;
18 |
19 | export default {
20 | LOGIN,
21 | ERROR,
22 | NETWORK,
23 | REGISTER,
24 | UNREGISTER,
25 | USERLIST
26 | };
27 |
--------------------------------------------------------------------------------
/docs/source/architecture/dbservices.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/docs/source/architecture/gateway.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_dashboard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_blocks_per_minute.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_network.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_tx_count_per_hour.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/client/e2e-test/docker-compose-explorer.yaml:
--------------------------------------------------------------------------------
1 |
2 | # SPDX-License-Identifier: Apache-2.0
3 | version: '2.1'
4 |
5 | volumes:
6 | pgdata:
7 |
8 | services:
9 | explorerdb.mynetwork.com:
10 | image: ghcr.io/hyperledger-labs/explorer-db:latest
11 | network_mode: "host"
12 | container_name: explorerdb.mynetwork.com
13 | hostname: explorerdb.mynetwork.com
14 | environment:
15 | - DATABASE_DATABASE=fabricexplorer
16 | - DATABASE_USERNAME=hppoc
17 | - DATABASE_PASSWORD=password
18 | volumes:
19 | - pgdata:/var/lib/postgresql/data
20 |
--------------------------------------------------------------------------------
/client/src/static/css/media-queries.css:
--------------------------------------------------------------------------------
1 | /* SPDX-License-Identifier: Apache-2.0 */
2 | /* Media Queries*/
3 | /*Resizing the dashboard buttons when browser resized*/
4 |
5 | @media (max-width: 1415px) and (min-width: 990px) {
6 | .navbar-brand {
7 | width: 50%;
8 | }
9 | .navbar-expand-md .navbar-nav {
10 | width: 60%;
11 | float: left;
12 | }
13 | .ml-auto,
14 | .mx-auto {
15 | margin-left: 5px !important;
16 | }
17 | }
18 | /*Toggle Navbar*/
19 | @media (max-width: 990px) {
20 | .navbar-nav {
21 | margin-top: 20px;
22 | padding-left: 30px;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/client/src/components/View/NetworkView.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { NetworkView } from './NetworkView';
6 |
7 | const setup = () => {
8 | const props = {
9 | peerList: [],
10 | };
11 |
12 | const wrapper = shallow();
13 |
14 | return {
15 | props,
16 | wrapper,
17 | };
18 | };
19 |
20 | describe('NetworkView', () => {
21 | test('NetworkView component should render', () => {
22 | const { wrapper } = setup();
23 | expect(wrapper.exists()).toBe(true);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_block_list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_chaincodes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_dark_theme.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_transaction_list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_tx_details.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/client/src/state/store.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { createStore, applyMiddleware, combineReducers } from 'redux';
6 | import thunkMiddleware from 'redux-thunk';
7 | import * as reducers from './redux';
8 | import Auth from './Auth';
9 |
10 | export default function configureStore(initialState) {
11 | const token = Auth.getToken();
12 | const rootReducer = combineReducers(reducers);
13 |
14 | return createStore(
15 | rootReducer,
16 | { ...initialState, auth: { token } },
17 | applyMiddleware(thunkMiddleware)
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/docs/source/architecture/websockets.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_blocks_per_hour.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Blocks per hour
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_channel_list.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/enhancement.yaml:
--------------------------------------------------------------------------------
1 | name: Enhancement Tracking Issue
2 | description: Provide supporting details for a feature in development
3 | labels: [feature]
4 | body:
5 | - type: textarea
6 | id: feature
7 | attributes:
8 | label: What would you like to be added?
9 | description: |
10 | A clear and concise description of what you want to happen.
11 | validations:
12 | required: true
13 |
14 | - type: textarea
15 | id: rationale
16 | attributes:
17 | label: Why is this needed?
18 | validations:
19 | required: true
20 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_filter_window.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/keygenerator.sh:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | #!/bin/bash
6 |
7 | # script to generate key, and certificate for HTTPS (SSL) Server
8 |
9 | SSL_CERTS_PATH=./ssl-certs
10 | echo "Generating key, and certificate for HTTPS (SSL) Server, path ${SSL_CERTS_PATH}"
11 | openssl genrsa -out ${SSL_CERTS_PATH}/privatekey.pem 1024
12 | openssl req -new -key ${SSL_CERTS_PATH}/privatekey.pem -out ${SSL_CERTS_PATH}/certrequest.csr
13 | openssl x509 -req -in ${SSL_CERTS_PATH}/certrequest.csr -signkey ${SSL_CERTS_PATH}/privatekey.pem -out ${SSL_CERTS_PATH}/certificate.pem -days 365
--------------------------------------------------------------------------------
/release_notes/v0.3.7.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## New Features
5 |
6 | * Support for Hyperledger Fabric 1.2
7 |
8 | * Added peer status, ledger height low, ledger height high, and ledger height unsigned
9 |
10 | * Support non TLS in Fabric 1.2
11 |
12 | * Applied tag v0.3.7
13 |
14 | ## Bug Fixes and Updates
15 |
16 | * Updated footer with supported fabric version
17 |
18 | * Dockerized app fixes
19 |
20 | ## Known Vulnerabilities
21 |
22 |
23 | ## Resolved Vulnerabilities
24 |
--------------------------------------------------------------------------------
/scripts/changelog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright IBM Corp. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 | #
7 |
8 | cat > CHANGELOG.new << EOF
9 | ## ${2}
10 |
11 | $(git log "$1..HEAD" --oneline | grep -v Merge | sed -e "s/\[\(BE-[0-9]*\)\]/\[\1\](https:\/\/jira.hyperledger.org\/browse\/\1\)/" -e "s/ \(BE-[0-9]*\)/ \[\1\](https:\/\/jira.hyperledger.org\/browse\/\1\)/" -e "s/\([0-9|a-z]*\)/* \[\1\](https:\/\/github.com\/hyperledger\/blockchain-explorer\/commit\/\1)/")
12 |
13 | EOF
14 | cat CHANGELOG.md >> CHANGELOG.new
15 | mv -f CHANGELOG.new CHANGELOG.md
16 |
--------------------------------------------------------------------------------
/docs/source/dev-setup/clone_button.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | Clone, or download button
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/client/src/components/ErrorMessage.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | import React from 'react';
3 | import { withStyles } from '@material-ui/core/styles';
4 | import { Alert } from 'reactstrap';
5 |
6 | const styles = {
7 | error: {
8 | marginTop: 50,
9 | marginBottom: -95,
10 | paddingTop: 30,
11 | textAlign: 'center',
12 | width: '100%'
13 | }
14 | };
15 |
16 | export const ErrorMessage = ({ message, classes }) => (
17 |
20 | );
21 |
22 | export default withStyles(styles)(ErrorMessage);
23 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_block_details_window.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | Code of Conduct Guidelines
2 | ==========================
3 |
4 | Please review the Hyperledger [Code of
5 | Conduct](https://wiki.hyperledger.org/community/hyperledger-project-code-of-conduct)
6 | before participating. It is important that we keep things civil.
7 |
8 | 
This work is licensed under a Creative Commons Attribution 4.0 International License.
9 |
--------------------------------------------------------------------------------
/client/src/components/Styled/Table.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import Enzyme, { shallow } from 'enzyme';
7 | import { unwrap } from '@material-ui/core/test-utils';
8 | import Adapter from 'enzyme-adapter-react-16';
9 | import Table from './Table';
10 |
11 | Enzyme.configure({ adapter: new Adapter() });
12 |
13 | const ComponentNaked = unwrap(Table);
14 |
15 | describe('', () => {
16 | it('with shallow', () => {
17 | const wrapper = shallow();
18 | expect(wrapper.exists()).toBe(true);
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/client/src/components/ErrorMessage.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import ErrorMessage from './ErrorMessage';
6 |
7 | const setup = () => {
8 | const props = {};
9 | const div = document.createElement('div');
10 | document.body.appendChild(div);
11 | const wrapper = mount(, { attachTo: div });
12 | return {
13 | props,
14 | wrapper
15 | };
16 | };
17 |
18 | describe('ErrorMessage', () => {
19 | test('ErrorMessage component should render correctly', () => {
20 | const { wrapper } = setup();
21 | expect(wrapper.exists()).toBe(true);
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/docs/source/presentation/hl_block_details_notification_panel.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | #SPDX-License-Identifier: Apache-2.0
2 | **/node_modules/**
3 | **/client/build/**
4 | **/client/coverage/**
5 | **/client/src/services/__mocks__/**
6 | **/app/test//node_modules/**
7 | **/app/persistence/fabric/postgreSQL/db/**
8 | **/app/test/**
9 | **/app/platform/fabric/e2e-test/**
10 | *.css
11 | **/client/src/components/View/*.spec.js
12 | **/client/src/components/Panels/*.spec.js
13 | **/client/src/components/*.spec.js
14 | **/client/src/components/Lists/*.spec.js
15 | **/client/src/components/Header/*.spec.js
16 | **/client/src/components/App/*.spec.js
17 | **/client/wdio.conf.js
18 | **/client/e2e-test/**/*.js
19 |
20 |
--------------------------------------------------------------------------------
/docker-compose-testdb.yaml:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: Apache-2.0
2 | version: '2.1'
3 |
4 | volumes:
5 | pgdata:
6 |
7 | services:
8 | explorerdb.mynetwork.com:
9 | image: ghcr.io/hyperledger-labs/explorer-db:latest
10 | container_name: explorerdb.mynetwork.com
11 | hostname: explorerdb.mynetwork.com
12 | # network_mode: "host"
13 | environment:
14 | - DATABASE_DATABASE=fabricexplorer
15 | - DATABASE_USERNAME=hppoc
16 | - DATABASE_PASSWORD=password
17 | # - POSTGRES_HOST_AUTH_METHOD=trust
18 | volumes:
19 | - pgdata:/var/lib/postgresql/data
20 | ports:
21 | - 5432:5432
22 |
--------------------------------------------------------------------------------
/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | name: test
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 | jobs:
11 | build:
12 | runs-on: ubuntu-20.04
13 | strategy:
14 | matrix:
15 | node-version: [12.x, 14.x, 16.x]
16 | steps:
17 | - uses: actions/checkout@v3
18 | - name: Use Node.js ${{ matrix.node-version }}
19 | uses: actions/setup-node@v3
20 | with:
21 | node-version: ${{ matrix.node-version }}
22 |
23 | - name: install dependencies
24 | run: npm install
25 |
26 | - name: run test
27 | run: npm test
28 |
29 |
30 |
--------------------------------------------------------------------------------
/DCO.md:
--------------------------------------------------------------------------------
1 | DCO
2 | ===
3 |
4 | As per section 13.a of the [Hyperledger Charter](https://www.hyperledger.org/about/charter) all code submitted to the Hyperledger Foundation needs to have a [Developer Certificate of Origin](http://developercertificate.org/) (DCO) sign-off.
5 |
6 | The sign off needs to be using your legal name, not a pseudonym. Git has a built-in mechanism to allow this with the `-s` or `--signoff` argument to `git commit` command, providing your `user.name` and `user.email` have been setup correctly.
7 |
8 | If you have any questions, you can reach us on [hyperledger-explorer channel](https://chat.hyperledger.org/channel/hyperledger-explorer).
9 |
--------------------------------------------------------------------------------
/.github/workflows/sonar.yml:
--------------------------------------------------------------------------------
1 | name: Sonar Cloud
2 | on:
3 | push:
4 | branches:
5 | - main
6 | workflow_dispatch:
7 |
8 | jobs:
9 | sonarcloud:
10 | name: SonarCloud
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v3
14 | with:
15 | fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
16 | - name: SonarCloud Scan
17 | uses: SonarSource/sonarcloud-github-action@master
18 | env:
19 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
20 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
21 |
--------------------------------------------------------------------------------
/docs/source/architecture/websockets.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | WebSockets
6 | ===========================================
7 |
8 |
9 | Websocket API is used to push information from the server to the clients. Information about new blocks, stats.
10 | are pushed via Websocket API. This is a convenient API that reduces load on clients and server.
11 |
12 | The image below illustrates how the notification is displayed when new blocks are received from the blockchain network, and a link to the
13 | new block details is provided in the notification panel.
14 |
15 |
16 | .. raw:: html
17 | :file: ./websockets.html
18 |
19 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright ONECHAIN 2017 All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
--------------------------------------------------------------------------------
/app/persistence/postgreSQL/CONFIGURE-TLS-CONNECTION-TO-POSTGRESQL.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # TLS connection to Postgresql
5 |
6 | In order to configure TLS connection to Postgresql take next steps:
7 |
8 | - [Optional] pass environment variable `DATABASE_CERTS_PATH`, default is `/opt/explorer/db-certs`
9 |
10 | - put certificates into folder specified by `DATABASE_CERTS_PATH`. There should be three files:
11 |
12 | - `client-cert.pem`
13 | - `client-key.pem`
14 | - `server-ca.pem`
15 |
16 | - pass environment variable `DATABASE_SSL_ENABLED=true`
17 |
--------------------------------------------------------------------------------
/app/platform/fabric/utils/FabricConst.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | export const fabric = {
6 | const: {
7 | NETWORK_CONFIGS: 'network-configs',
8 | PERSISTENCE: 'persistence',
9 | BLOCK_TYPE_CONFIG: 'CONFIG',
10 | BLOCK_TYPE_ENDORSER_TRANSACTION: 'ENDORSER_TRANSACTION',
11 | CHAINCODE_LSCC: 'lscc',
12 | CHAINCODE_LIFECYCLE: '_lifecycle',
13 | NOTITY_TYPE_NEWCHANNEL: '1',
14 | NOTITY_TYPE_UPDATECHANNEL: '2',
15 | NOTITY_TYPE_CHAINCODE: '3',
16 | NOTITY_TYPE_BLOCK: '4',
17 | NOTITY_TYPE_EXISTCHANNEL: '5',
18 | NOTITY_TYPE_CLIENTERROR: '6'
19 | }
20 | };
21 |
22 | export enum BootModes {
23 | 'ALL',
24 | 'CUSTOM'
25 | }
26 |
--------------------------------------------------------------------------------
/docs/project_lifecycle/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## Hyperledger Explorer Project Lifecycle
5 |
6 | - Hyperledger Explorer Project follows the Hyperledger Project lifecycle states process as follows:
7 |
8 | - [Proposal](proposal.md)
9 |
10 | - [Incubation](Incubation.md)
11 |
12 | - [Active](active.md)
13 |
14 | - [First Major Release](first-major-release.md)
15 |
16 | - [Deprecated](deprecated.md)
17 |
18 | - [End of Life](end-of-life.md)
19 |
20 | Projects may not necessarily move through those states in a linear way and may go through several iterations.
21 |
22 |
--------------------------------------------------------------------------------
/CONFIG-HTTPS-HLEXPLORER.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## Configure HTTPS to Hyperledger Explorer
5 |
6 |
7 | #### Configure appconfig.json
8 |
9 | - Edit file blockchain-explorer/appconfig.json
10 | - Update config options
11 | - sslEnabled : true | false, to enable, or disable HTTPS.
12 | - sslCertsPath: "ssl-certs", by default it is in root of the project.
13 | - if sslEnabled is set to true, run $./keygenerator.sh to generate key, and certificate for HTTPS.
14 |
15 | ** NOTE:
16 | - The self-signed root certificate generated by ./keygenerator.sh script, has not been verified by a third party.
17 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 |
5 | # You can set these variables from the command line.
6 | SPHINXOPTS =
7 | SPHINXBUILD = sphinx-build
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--------------------------------------------------------------------------------
/ci/install_deps.yml:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: Apache-2.0
2 |
3 | steps:
4 | - task: NodeTool@0
5 | inputs:
6 | versionSpec: $(NODE_VER)
7 | displayName: Install NodeJs
8 | - task: GoTool@0
9 | inputs:
10 | version: $(GO_VER)
11 | goPath: $(GOPATH)
12 | - task: Go@0
13 | inputs:
14 | command: 'get'
15 | arguments: '-u github.com/onsi/ginkgo/ginkgo'
16 | - task: Go@0
17 | inputs:
18 | command: 'get'
19 | arguments: '-u github.com/onsi/gomega/...'
20 | - task: Go@0
21 | inputs:
22 | command: 'get'
23 | arguments: '-u gopkg.in/yaml.v2'
24 | - task: Go@0
25 | inputs:
26 | command: 'get'
27 | arguments: '-u github.com/pkg/errors'
--------------------------------------------------------------------------------
/sonar-project.properties:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | sonar.projectKey=hyperledger-labs_blockchain-explorer
6 | sonar.organization=hyperledger-labs
7 |
8 | # Path to sources
9 | sonar.sources=.
10 | sonar.exclusions=**/e2e-test/**,**/test/**,docs/**/*,devenv/**/*,client/**/*.spec.js
11 | #sonar.inclusions=
12 |
13 | # Path to tests
14 | #sonar.tests=
15 | #sonar.test.exclusions=
16 | #sonar.test.inclusions=
17 |
18 | # Source encoding
19 | #sonar.sourceEncoding=UTF-8
20 |
21 | # Exclusions for copy-paste detection
22 | #sonar.cpd.exclusions=
23 |
24 | # This is the name and version displayed in the SonarCloud UI.
25 | #sonar.projectName=blockchain-explorer
26 | #sonar.projectVersion=1.0
27 |
--------------------------------------------------------------------------------
/release_notes/v1.0.0-rc1.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * Added column for block size on BLOCK view page
6 | * Added orderer to network view page
7 | * Create online documentation
8 | * Add default GitHub SECURITY policy
9 | * Switching to Azure Pipeline, and GitHub pull request
10 | * Gerrit EOL, no longer supported
11 |
12 | ## Bug Fixes and Updates
13 |
14 | * Update packages
15 | * Fixed broken links in README.md
16 |
17 |
18 | ## Known Vulnerabilities
19 |
20 | * "helmet": "^3.21.1"
21 |
22 | ## Resolved Vulnerabilities
23 |
24 | * Updated to "helmet": "^3.21.1" to fix security vulnerability
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/source/architecture/webserver.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 |
6 |
7 | Webserver
8 | ==========
9 |
10 | `Node.js `__ is the backend framework for implementing the server-side components, and `Express `__, a Web framework for Node.js.
11 | application. The main entry point of the Hyperledger Explorer is
12 | the `Broadcaster `__ class,
13 | that will initialize the application, WebSockets, create an Express server, and other processes to start the application.
14 |
15 | Broadcaster class diagram shown in the image below.
16 |
17 | .. raw:: html
18 | :file: ./webserver.html
19 |
20 |
21 |
--------------------------------------------------------------------------------
/release_notes/v0.3.9.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## New Features
5 |
6 | * Support for Hyperledger Fabric 1.4
7 |
8 | * Applied tag v0.3.9
9 |
10 | ## Bug Fixes and Updates
11 |
12 | * Support for working with fabric-ca
13 | * Updated footer with supported fabric version
14 |
15 | ## Known Vulnerabilities
16 |
17 | * High Missing Origin Validation
18 | Package webpack-dev-server
19 | Dependency of react-scripts
20 | Path react-scripts > webpack-dev-server
21 | More info https://nodesecurity.io/advisories/725
22 |
23 | ## Resolved Vulnerabilities
24 |
25 | * All known vulnerabilities fixed
26 |
--------------------------------------------------------------------------------
/docs/project_lifecycle/first-major-release.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## First Major Release
4 |
5 | - Hyperledger Explorer seeks graduation from the incubation phase
6 |
7 | - A project’s maintainers seeking to publish a project’s first major release (see semver) must seek approval of the TSC whether in Active or Incubation status as defined above. While it is expected that most projects will have reached an Active status by the time their maintainers seek to announce a first major release, the TSC may approve such requests also in cases where the project is still in Incubation status, should the TSC believe that the project's code is sufficiently mature.
8 |
--------------------------------------------------------------------------------
/release_notes/v1.1.5.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * [BE-694](https://jira.hyperledger.org/browse/BE-694) Add UI link to trans (#227)
6 | * [BE-858](https://jira.hyperledger.org/browse/BE-858) Upgrade base image of Explorer container image (#220)
7 | * [BE-801](https://jira.hyperledger.org/browse/BE-801) Add the steps to configure a subdomain (#219)
8 | * Upgrade fabric version supported by Explorer (#227)
9 |
10 | ## Bug Fixes and Updates
11 |
12 | * [BE-862](https://jira.hyperledger.org/browse/BE-862) Fix sync error (#228)
13 | * Fix layout of icons on navigation bar (#218)
14 |
15 | ## Known Vulnerabilities
16 |
17 | None
18 |
19 |
--------------------------------------------------------------------------------
/client/src/components/Container.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | import React, { Component } from 'react';
3 |
4 | import { withStyles } from '@material-ui/core/styles';
5 |
6 | const styles = theme => ({
7 | root: {
8 | width: 'auto',
9 | display: 'block', // Fix IE 11 issue.
10 | marginLeft: 'auto',
11 | marginRight: 'auto',
12 | [theme.breakpoints.up(400 + theme.spacing.unit * 3 * 2)]: {
13 | width: 400,
14 | marginLeft: 'auto',
15 | marginRight: 'auto'
16 | }
17 | }
18 | });
19 |
20 | export class Container extends Component {
21 | render() {
22 | const { classes, children } = this.props;
23 | return {children}
;
24 | }
25 | }
26 |
27 | export default withStyles(styles)(Container);
28 |
--------------------------------------------------------------------------------
/client/src/components/View/ChaincodeView.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import View from '../Styled/View';
7 | import Chaincodes from '../Lists/Chaincodes';
8 | import { chaincodeListType, chaincodeMetaDataType } from '../types';
9 |
10 | export const ChaincodeView = ({ chaincodeList,chaincodeMetaData, getChaincodeMetaData, currentChannel }) => (
11 |
12 |
13 |
14 | );
15 |
16 | ChaincodeView.propTypes = {
17 | chaincodeList: chaincodeListType.isRequired,
18 | chaincodeMetaData: chaincodeMetaDataType.isRequired
19 | };
20 |
21 | export default ChaincodeView;
22 |
--------------------------------------------------------------------------------
/client/src/components/View/ChannelView.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import View from '../Styled/View';
7 | import Channels from '../Lists/Channels';
8 | import { channelPeerDataType, channelsType } from '../types';
9 |
10 | export const ChannelView = ({
11 | currentChannel,
12 | getChannelPeerData,
13 | channels,
14 | channelPeerData
15 | }) => (
16 |
17 |
23 |
24 | );
25 |
26 | ChannelView.propTypes = {
27 | channels: channelsType.isRequired,
28 | channelPeerData: channelPeerDataType.isRequired
29 | };
30 |
31 | export default ChannelView;
32 |
--------------------------------------------------------------------------------
/docs/source/Style-guides/js-style.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | Coding guidelines
6 | -----------------
7 |
8 | Coding javascript
9 | ~~~~~~~~~~~~~~~~~
10 |
11 | We code in javascript™ and follow the `Airbnb JavaScript Style Guide `__, and
12 | `Google JavaScript Style Guide `__.
13 |
14 |
15 | PostgreSQL Coding Conventions
16 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17 |
18 | Keep PostgreSQL coding guidelines and follow the `PostgreSQL The SQL Language Coding Conventions `__.
19 |
20 |
21 | .. Licensed under Creative Commons Attribution 4.0 International License
22 | https://creativecommons.org/licenses/by/4.0/
23 |
--------------------------------------------------------------------------------
/client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | /* eslint-disable */
7 | import { shallow, render, mount, configure } from 'enzyme';
8 | /* eslint-enable */
9 | import sinon from 'sinon';
10 | // import { configure } from 'enzyme';
11 | import Adapter from 'enzyme-adapter-react-16';
12 | import localstorage from 'mock-local-storage';
13 |
14 | configure({ adapter: new Adapter() });
15 |
16 | global.matchMedia =
17 | global.matchMedia ||
18 | function() {
19 | return {
20 | matches: false,
21 | addListener() {},
22 | removeListener() {}
23 | };
24 | };
25 |
26 | global.React = React;
27 | global.shallow = shallow;
28 | global.render = render;
29 | global.mount = mount;
30 | global.sinon = sinon;
31 | global.localstorage = localstorage;
32 |
--------------------------------------------------------------------------------
/release_notes/v1.1.2.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * Add user management feature/API
6 | * Please refer [README-CONFIG.md](../README-CONFIG.md#user-management)
7 | * Reduce container image size (#148)
8 | * Add fabric 1.4.8 / 2.2.0 support (#150)
9 | * Change default encode of value in TX details (#157)
10 | * Please refer [README-CONFIG.md](../README-CONFIG.md#value-encoding-in-transaction-details)
11 | * Update example of connection profile for docker setup (#165)
12 |
13 | ## Bug Fixes and Updates
14 |
15 | * Fixed typos in "SyncService" (#149)
16 | * Fix typo in "Transaction Details" view (#147)
17 | * Correct index to get validation code from metadata (#164)
18 |
19 | ## Known Vulnerabilities
20 |
21 | * none
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 |
6 | explorer_1/scripts/bower_components/
7 | explorer_1/webcontent
8 |
9 | node_modules
10 | app/test/coverage/
11 |
12 | .idea/*
13 | venv
14 | .vscode
15 |
16 | test/fabric-samples
17 | tmp/*
18 |
19 | logs
20 | .log
21 | log.log
22 |
23 | fabric-docker-compose-svt/channel-artifacts
24 | fabric-docker-compose-svt/crypto-config
25 | first-network/channel-artifacts/*
26 | # examples/*
27 | tmp/wallet/*
28 | wallet/*
29 | *.swp
30 | # package-lock.json
31 | ssl-certs/*.pem
32 | ssl-certs/*.csr
33 | 0
34 | app/test/.nyc_output/
35 | docs/build/
36 | _build
37 | # _static
38 | _templates
39 | *.DS_Store
40 | crypto-config
41 | **/specs/channel-artifacts
42 | **/specs/configFiles/
43 | **/specs/templates/
44 | **/specs/ytt/
45 | PTE
46 | dist/*
47 | app/persistence/fabric/postgreSQL/db/logfile
48 |
--------------------------------------------------------------------------------
/client/src/components/View/ChaincodeView.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { ChaincodeView } from './ChaincodeView';
6 |
7 | const setup = () => {
8 | const props = {
9 | chaincodeList: [
10 | {
11 | chaincodename: 'mycc',
12 | channelName: 'mychannel',
13 | path: 'github.com/chaincode/chaincode_example02/go/',
14 | source: 'Location not found',
15 | txCount: 32,
16 | version: '1.0',
17 | },
18 | ],
19 | };
20 |
21 | const wrapper = shallow();
22 |
23 | return {
24 | props,
25 | wrapper,
26 | };
27 | };
28 |
29 | describe('ChaincodeView', () => {
30 | test('ChaincodeView component should render', () => {
31 | const { wrapper } = setup();
32 | expect(wrapper.exists()).toBe(true);
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/client/src/state/redux/auth/actions.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import types from './types';
6 |
7 | export const login = user => ({
8 | type: types.LOGIN,
9 | payload: user
10 | });
11 |
12 | export const network = networks => ({
13 | type: types.NETWORK,
14 | payload: networks
15 | });
16 |
17 | export const error = errors => ({
18 | type: types.ERROR,
19 | payload: errors
20 | });
21 |
22 | export const register = registered => ({
23 | type: types.REGISTER,
24 | payload: registered
25 | });
26 |
27 | export const unregister = unregistered => ({
28 | type: types.UNREGISTER,
29 | payload: unregistered
30 | });
31 |
32 | export const userlist = userlists => ({
33 | type: types.USERLIST,
34 | payload: userlists
35 | });
36 |
37 | export default {
38 | login,
39 | network,
40 | error,
41 | register,
42 | unregister,
43 | userlist
44 | };
45 |
--------------------------------------------------------------------------------
/.github/workflows/build.yaml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 | jobs:
11 | build:
12 | runs-on: ubuntu-20.04
13 | strategy:
14 | matrix:
15 | node-version: [12.x, 14.x, 16.x]
16 | steps:
17 | - uses: actions/checkout@v3
18 | - name: Use Node.js ${{ matrix.node-version }}
19 | uses: actions/setup-node@v3
20 | with:
21 | node-version: ${{ matrix.node-version }}
22 |
23 | - name: install server dependencies
24 | run: npm install
25 |
26 | - name: build server
27 | run: npm run build
28 |
29 | - name: install client dependencies
30 | run: npm install --prefix client
31 |
32 |
33 | - name: build client
34 | run: CI=false npm run build --prefix client #warnning are considered as failed build, skipping warnings
35 |
36 |
--------------------------------------------------------------------------------
/client/src/state/Auth.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | export default class Auth {
3 | /**
4 | * Authenticate a user. Save a token string in Local Storage
5 | *
6 | * @param {string} token
7 | */
8 | static authenticateUser(token) {
9 | localStorage.setItem('token', token);
10 | }
11 |
12 | /**
13 | * Check if a user is authenticated - check if a token is saved in Local Storage
14 | *
15 | * @returns {boolean}
16 | */
17 | static isUserAuthenticated() {
18 | return localStorage.getItem('token') !== null;
19 | }
20 |
21 | /**
22 | * Deauthenticate a user. Remove a token from Local Storage.
23 | *
24 | */
25 | static deauthenticateUser() {
26 | localStorage.removeItem('token');
27 | }
28 |
29 | /**
30 | * Get a token value.
31 | *
32 | * @returns {string}
33 | */
34 |
35 | static getToken() {
36 | return localStorage.getItem('token');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/platform/PlatformBuilder.ts:
--------------------------------------------------------------------------------
1 | /*
2 | *SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { explorerConst } from '../common/ExplorerConst';
6 | import { explorerError } from '../common/ExplorerMessage';
7 | import { ExplorerError } from '../common/ExplorerError';
8 | import { Platform } from './fabric/Platform';
9 |
10 | /**
11 | *
12 | *
13 | * @class PlatformBuilder
14 | */
15 | export class PlatformBuilder {
16 | /**
17 | *
18 | *
19 | * @static
20 | * @param {*} pltfrm
21 | * @param {*} persistence
22 | * @param {*} broadcaster
23 | * @returns
24 | * @memberof PlatformBuilder
25 | */
26 | static async build(pltfrm: string, persistence: any, broadcaster: any) {
27 | if (pltfrm === explorerConst.PLATFORM_FABRIC) {
28 | const platform = new Platform(persistence, broadcaster);
29 | return platform;
30 | }
31 | throw new ExplorerError(explorerError.ERROR_1004, pltfrm);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/client/src/components/View/ChannelsView.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { ChannelsView } from './ChannelsView';
6 |
7 | const setup = () => {
8 | const props = {
9 | channels: [
10 | {
11 | blocks: 5,
12 | channel_hash:
13 | '0bc9fb4bca66ff0583e39e888eebdf9e01f976d292af3e9deff7d3199ecf3977',
14 | channelname: 'mychannel',
15 | createdat: '2018-05-30T20:56:47.795Z',
16 | id: 3,
17 | transactions: 5,
18 | },
19 | ],
20 | getChannels: jest.fn(),
21 | };
22 |
23 | const wrapper = shallow();
24 |
25 | return {
26 | props,
27 | wrapper,
28 | };
29 | };
30 |
31 | describe('ChannelsView', () => {
32 | test('ChannelsView component should render', () => {
33 | const { wrapper } = setup();
34 | expect(wrapper.exists()).toBe(true);
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/release_notes/v0.3.9.4.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * none
6 |
7 | ## Bug Fixes and Updates
8 |
9 | * Added e2e test suite for GUI
10 | * Added script to setup fabric for GUI e2e test
11 | * Bug fixes
12 | - Fix e2e sanity check error
13 | - Selected Channel not stable in UI
14 | * Code coverage increase
15 | * Added script for generating change log
16 | * SWAGGER updated to use OPENAPI
17 | * Updated Content-Security-Policy
18 | * Applied tag v0.3.9.4
19 |
20 | ## Known Vulnerabilities
21 |
22 | * 'diff' vulnerability found in app/test/package-lock.json
23 | - Dependency diff
24 | - Version < 3.5.0 Upgrade to ~> 3.5.0
25 | - Vulnerabilities WS-2018-0590 High severity
26 | - Defined in package-lock.json
27 |
28 | ## Resolved Vulnerabilities
29 |
30 | * All known vulnerabilities fixed
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-org1.yml:
--------------------------------------------------------------------------------
1 | organizations:
2 | - name: org1
3 | #! For smoke test suite, connection-profile are read from smoke directory
4 | connProfilePath: ./connection-profile/connection_profile_org1.yaml
5 | - name: org2
6 | connProfilePath: ./connection-profile/connection_profile_org2.yaml
7 |
8 | invokes:
9 | - channelName: org1channel
10 | name: samplecc
11 | targetPeers: OrgAnchor
12 | nProcPerOrg: 1
13 | nRequest: 1
14 | runDur: 0
15 | organizations: org1
16 | txnOpt:
17 | - mode: constant
18 | options:
19 | constFreq: 0
20 | devFreq: 0
21 | queryCheck: 1
22 | eventOpt:
23 | type: FilteredBlock
24 | listener: Block
25 | timeout: 240000
26 | ccOpt:
27 | ccType: ccchecker
28 | keyStart: 0
29 | payLoadMin: 1024
30 | payLoadMax: 2048
31 | args: "put,a1,1"
32 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-org2.yml:
--------------------------------------------------------------------------------
1 | organizations:
2 | - name: org1
3 | #! For smoke test suite, connection-profile are read from smoke directory
4 | connProfilePath: ./connection-profile/connection_profile_org1.yaml
5 | - name: org2
6 | connProfilePath: ./connection-profile/connection_profile_org2.yaml
7 |
8 | invokes:
9 | - channelName: org2channel
10 | name: samplecc
11 | targetPeers: OrgAnchor
12 | nProcPerOrg: 1
13 | nRequest: 1
14 | runDur: 0
15 | organizations: org2
16 | txnOpt:
17 | - mode: constant
18 | options:
19 | constFreq: 0
20 | devFreq: 0
21 | queryCheck: 1
22 | eventOpt:
23 | type: FilteredBlock
24 | listener: Block
25 | timeout: 240000
26 | ccOpt:
27 | ccType: ccchecker
28 | keyStart: 0
29 | payLoadMin: 1024
30 | payLoadMax: 2048
31 | args: "put,a1,1"
32 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/apitest-input-multiprofile-invoke-common.yml:
--------------------------------------------------------------------------------
1 | organizations:
2 | - name: org1
3 | #! For smoke test suite, connection-profile are read from smoke directory
4 | connProfilePath: ./connection-profile/connection_profile_org1.yaml
5 | - name: org2
6 | connProfilePath: ./connection-profile/connection_profile_org2.yaml
7 |
8 | invokes:
9 | - channelName: commonchannel
10 | name: samplecc
11 | targetPeers: OrgAnchor
12 | nProcPerOrg: 1
13 | nRequest: 1
14 | runDur: 0
15 | organizations: org1
16 | txnOpt:
17 | - mode: constant
18 | options:
19 | constFreq: 0
20 | devFreq: 0
21 | queryCheck: 1
22 | eventOpt:
23 | type: FilteredBlock
24 | listener: Block
25 | timeout: 240000
26 | ccOpt:
27 | ccType: ccchecker
28 | keyStart: 0
29 | payLoadMin: 1024
30 | payLoadMax: 2048
31 | args: "put,a1,1"
32 |
--------------------------------------------------------------------------------
/client/src/components/Route/Private.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | /* eslint-disable implicit-arrow-linebreak */
6 | /* eslint-disable no-confusing-arrow */
7 |
8 | import React from 'react';
9 |
10 | import { Route, Redirect } from 'react-router-dom';
11 |
12 | import { connect } from 'react-redux';
13 |
14 | import { authSelectors } from '../../state/redux/auth';
15 |
16 | export function Private({ render, auth, ...rest }) {
17 | const redirect = !auth;
18 | return (
19 |
22 | !redirect ? (
23 | render(props)
24 | ) : (
25 |
31 | )
32 | }
33 | />
34 | );
35 | }
36 |
37 | const { authSelector } = authSelectors;
38 |
39 | export default connect(state => ({
40 | auth: authSelector(state)
41 | }))(Private);
42 |
--------------------------------------------------------------------------------
/app/sync/sender/ForkSenderHandler.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { helper } from '../../common/helper';
6 |
7 | const logger = helper.getLogger('ForkSenderHandler');
8 |
9 | /**
10 | *
11 | *
12 | * @class ForkSenderHandler
13 | */
14 | export class ForkSenderHandler {
15 | /**
16 | * Creates an instance of ForkSenderHandler.
17 | * @memberof ForkSenderHandler
18 | */
19 | /*eslint-disable */
20 | constructor() {}
21 | /* eslint-enable */
22 |
23 | async initialize() {
24 | process.on('message', msg => {
25 | logger.debug('Message from parent: %j', msg);
26 | });
27 | }
28 |
29 | /**
30 | *
31 | *
32 | * @param {*} message
33 | * @memberof ForkSenderHandler
34 | */
35 | send(message) {
36 | if (process.send) {
37 | process.send(message);
38 | }
39 | }
40 |
41 | /**
42 | *
43 | *
44 | * @memberof ForkSenderHandler
45 | */
46 | close() {
47 | // TODO
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/release_notes/v0.3.9.5.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * Add options for TLS connection to Postgresql
6 | * Verify with fabric v1.4.2
7 | * Create online documentation (WIP)
8 |
9 | ## Bug Fixes and Updates
10 |
11 | * Update packages
12 | * Add CODEOWNERS
13 | * Switch orderer when losing connection
14 | * Add e2e test for raft ordering model
15 | * Remove AnsiColor wrap in bc Explorer
16 | * Fix a bug on chaincode view
17 | * Fix log for SSL settings in PgService
18 | * Fix node access error in non-docker env
19 | * Ignoring style code for coverage purposes
20 | * Increase UI code coverage
21 | * Update Hyperledger Explorer documentation
22 | * Add steps how to run e2e test for GUI to README
23 | * Update gprcio pkg for e2e test
24 |
25 | ## Known Vulnerabilities
26 |
27 | * none
28 |
29 | ## Resolved Vulnerabilities
30 |
31 | * n/a
32 |
33 |
34 |
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | .. Hyperledger Explorer documentation master file, created by
6 | sphinx-quickstart on Tue Jul 2 15:36:38 2019.
7 | You can adapt this file completely to your liking, but it should at least
8 | contain the root `toctree` directive.
9 |
10 |
11 | Hyperledger Explorer documentation
12 | **********************************
13 |
14 | .. image:: images/Hyperledger_Explorer_Logo_Color.png
15 | :width: 650px
16 |
17 |
18 |
19 |
20 |
21 | Overview of Hyperledger Explorer
22 | ================================
23 |
24 | Table of contents
25 | =================
26 |
27 |
28 | .. toctree::
29 | :maxdepth: 1
30 |
31 |
32 | introduction
33 | presentation/index
34 | architecture
35 | getting_started
36 | repos
37 | CONTRIBUTING
38 |
39 | .. Licensed under Creative Commons Attribution 4.0 International License
40 | https://creativecommons.org/licenses/by/4.0/
41 |
--------------------------------------------------------------------------------
/app/persistence/PersistenceFactory.ts:
--------------------------------------------------------------------------------
1 | /*
2 | *SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { explorerConst } from '../common/ExplorerConst';
6 | import { explorerError } from '../common/ExplorerMessage';
7 | import { ExplorerError } from '../common/ExplorerError';
8 | import { Persist } from './postgreSQL/Persist';
9 |
10 | /**
11 | *
12 | *
13 | * @class PersistenceFactory
14 | */
15 | export class PersistenceFactory {
16 | /**
17 | *
18 | *
19 | * @static
20 | * @param {*} db
21 | * @param {*} dbconfig
22 | * @returns
23 | * @memberof PersistenceFactory
24 | */
25 | static async create(db: string, dbconfig: any) {
26 | if (db === explorerConst.PERSISTENCE_POSTGRESQL) {
27 | // Avoid to load all db Persist module
28 | const persistence = new Persist(dbconfig);
29 | await persistence.getPGService().handleDisconnect();
30 | return persistence;
31 | }
32 | throw new ExplorerError(explorerError.ERROR_1003, db);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/client/src/state/redux/auth/reducers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import types from './types';
6 |
7 | const initialState = {
8 | user: '',
9 | token: null,
10 | error: '',
11 | networks: [],
12 | registered: '',
13 | userlists: []
14 | };
15 |
16 | /* Reducers for Dashboard Charts */
17 | const authReducer = (state = initialState, action) => {
18 | switch (action.type) {
19 | case types.LOGIN:
20 | case types.ERROR:
21 | case types.NETWORK:
22 | case types.REGISTER:
23 | {
24 | return {
25 | ...state,
26 | ...action.payload
27 | };
28 | }
29 | case types.USERLIST: {
30 | return {
31 | ...state,
32 | userlists: action.payload.message
33 | };
34 | }
35 | case types.UNREGISTER: {
36 | return {
37 | ...state,
38 | unregistered: action.payload.message
39 | };
40 | }
41 | default: {
42 | return state;
43 | }
44 | }
45 | };
46 |
47 | export default authReducer;
48 |
--------------------------------------------------------------------------------
/app/sync/SyncBuilder.ts:
--------------------------------------------------------------------------------
1 | /*
2 | *SPDX-License-Identifier: Apache-2.0
3 | */
4 | import { explorerConst } from '../common/ExplorerConst';
5 | import { explorerError } from '../common/ExplorerMessage';
6 | import { ExplorerError } from '../common/ExplorerError';
7 | import { ExplorerSender } from './sender/ExplorerSender';
8 | import { SyncPlatform } from '../platform/fabric/sync/SyncPlatform';
9 |
10 | /**
11 | *
12 | *
13 | * @class SyncBuilder
14 | */
15 | export class SyncBuilder {
16 | /**
17 | *
18 | *
19 | * @static
20 | * @param {*} pltfrm
21 | * @param {*} persistence
22 | * @param {*} sender
23 | * @returns
24 | * @memberof SyncBuilder
25 | */
26 | static async build(pltfrm: string, persistence: any, sender: ExplorerSender) {
27 | if (pltfrm === explorerConst.PLATFORM_FABRIC) {
28 | const platform = new SyncPlatform(persistence, sender);
29 | return platform;
30 | }
31 | throw new ExplorerError(explorerError.ERROR_1005, pltfrm);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/client/src/state/redux/charts/selectors.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | export const blockPerHourSelector = state => state.charts.blockPerHour.rows;
6 | export const blockPerMinSelector = state => state.charts.blockPerMin.rows;
7 | export const channelListSelector = state => state.charts.channelList.list;
8 | export const currentChannelSelector = state => state.charts.channel.currentChannel;
9 | export const dashStatsSelector = state => state.charts.dashStats;
10 | export const notificationSelector = state => state.charts.notification;
11 | export const transactionByOrgSelector = state => state.charts.transactionByOrg.rows;
12 | export const transactionPerHourSelector = state => state.charts.transactionPerHour.rows;
13 | export const transactionPerMinSelector = state => state.charts.transactionPerMin.rows;
14 | export const errorMessageSelector = state => state.charts.errorMessage.error;
15 | export const blockActivitySelector = state => state.charts.blockActivity.rows;
16 |
--------------------------------------------------------------------------------
/release_notes/v1.1.8.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * None
6 |
7 | ## Bug Fixes and Updates
8 |
9 | * BE-880 Fix incorrect multi-process logging (#260)
10 | * docs: add code snippet for admin cert modification (#257) (#258)
11 |
12 | ## Known Vulnerabilities
13 |
14 | package-lock.json
15 | ```
16 |
17 | jsrsasign <10.2.0
18 | Severity: critical
19 | RSA signature validation vulnerability - https://npmjs.com/advisories/1672
20 | fix available via `npm audit fix --force`
21 | Will install fabric-network@1.4.1, which is a breaking change
22 | node_modules/jsrsasign
23 | fabric-ca-client *
24 | Depends on vulnerable versions of fabric-common
25 | Depends on vulnerable versions of jsrsasign
26 | node_modules/fabric-ca-client
27 | fabric-common >=2.1.1-snapshot.390
28 | Depends on vulnerable versions of jsrsasign
29 | ```
30 |
31 | client/package-lock.json
32 | ```
33 |
34 | ```
35 |
--------------------------------------------------------------------------------
/app/middleware/auth-check.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import * as jwt from 'jsonwebtoken';
6 | import config from '../explorerconfig.json';
7 |
8 | /**
9 | * The Auth Checker middleware function.
10 | */
11 | export const authCheckMiddleware = (req, res, next) => {
12 | if (!req.headers.authorization) {
13 | return res.status(401).end();
14 | }
15 |
16 | // Get the last part from a authorization header string like "bearer token-value"
17 | const token = req.headers.authorization.split(' ')[1];
18 |
19 | // Decode the token using a secret key-phrase
20 | return jwt.verify(token, config.jwt.secret, (err, decoded) => {
21 | // The 401 code is for unauthorized status
22 | if (err) {
23 | return res.status(401).end();
24 | }
25 |
26 | const requestUserId = decoded.user;
27 |
28 | req.requestUserId = requestUserId;
29 | req.network = decoded.network;
30 |
31 | // TODO: check if a user exists, otherwise error
32 |
33 | return next();
34 | });
35 | };
36 |
--------------------------------------------------------------------------------
/postgres-Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright Tecnalia Research & Innovation (https://www.tecnalia.com)
2 | # Copyright Tecnalia Blockchain LAB
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 |
6 | FROM postgres:10.4-alpine
7 |
8 | # default database name for HLF Explorer db connection
9 | ENV DATABASE_DATABASE fabricexplorer
10 |
11 | # default username for HLF Explorer db connection
12 | ENV DATABASE_USERNAME hppoc
13 |
14 | # default password for HLF Explorer db connection
15 | ENV DATABASE_PASSWORD password
16 |
17 | RUN apk update \
18 | && apk add jq \
19 | && apk add nodejs \
20 | && apk add sudo \
21 | && rm -rf /var/cache/apk/*
22 |
23 | WORKDIR /opt
24 |
25 | # Copy files
26 | COPY app/persistence/fabric/postgreSQL/db/explorerpg.sql /opt/explorerpg.sql
27 | COPY app/persistence/fabric/postgreSQL/db/updatepg.sql /opt/updatepg.sql
28 | COPY app/persistence/fabric/postgreSQL/db/createdb.sh /docker-entrypoint-initdb.d/createdb.sh
29 | COPY app/persistence/fabric/postgreSQL/db/processenv.js /opt/processenv.js
--------------------------------------------------------------------------------
/client/src/state/redux/theme/tests.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | /* eslint-disable */
5 |
6 | import reducers from './reducers';
7 | import actions from './actions';
8 | import * as selectors from './selectors';
9 |
10 | describe('Theme Reducer', () => {
11 | it('should return the initial state', () => {
12 | expect(reducers(undefined, {})).toEqual({
13 | mode: 'light'
14 | });
15 | });
16 |
17 | it('should display the theme based on the action passed', () => {
18 | const initialState = {};
19 | const payload = { mode: 'light' };
20 | const action = actions.changeTheme(payload);
21 |
22 | const newState = reducers(initialState, action);
23 | expect(newState.mode).toEqual({ mode: 'light' });
24 | });
25 | });
26 |
27 | describe('Theme Selector', () => {
28 | test('chaincodeListSelector', () => {
29 | const state = { theme: { mode: 'test' } };
30 | const selectTheme = selectors.modeSelector(state);
31 | expect(selectTheme).toBe('test');
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/docs/source/dev-setup/build.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | Building Hyperledger Explorer
6 | ------------------------------
7 |
8 | The following instructions assume that you have already set up your
9 | :doc:`development environment `.
10 |
11 | To build Hyperledger Explorer:
12 |
13 | ::
14 |
15 | cd blockchain-explorer
16 | git checkout
17 | ./main.sh clean
18 | ./main.sh install
19 |
20 | .. note::
21 |
22 |
23 | `Ask in chat `__ what is the branch name of the latest being in development
24 |
25 |
26 | Running the unit tests
27 | ~~~~~~~~~~~~~~~~~~~~~~
28 |
29 | Use the following sequence to run all unit tests
30 |
31 | ::
32 |
33 | cd blockchain-explorer
34 | ./main.sh clean
35 | ./main.sh install
36 | ./main.sh test
37 |
38 |
39 |
40 | .. Licensed under Creative Commons Attribution 4.0 International License
41 | https://creativecommons.org/licenses/by/4.0/
42 |
--------------------------------------------------------------------------------
/release_notes/v0.3.4.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## New Features
5 |
6 | * Support for multiple channels
7 |
8 | * Ability to switch between channels
9 |
10 | * Support Hyperledger Composer network
11 |
12 |
13 | ## Bug Fixes and Updates
14 |
15 | * Improved transition for loading another channel
16 |
17 | * React/redux refactor to improve performance
18 |
19 | * Display issues in transaction and block detail window
20 |
21 | * Display issues in transaction and block list views
22 |
23 | * Support long values in transaction model
24 |
25 | * Activity charts display
26 |
27 | * Metrics in organization Pie chart
28 |
29 | * Dark theme in activity and details views
30 |
31 | * Database optimization
32 |
33 | * Compress HTTP Response
34 |
35 | * Fixed transaction modal cache issue
36 |
37 |
38 | ## Known Vulnerabilities
39 |
40 | * None
41 |
42 |
43 | ## Resolved Vulnerabilities
44 |
45 | * None
46 |
--------------------------------------------------------------------------------
/client/src/components/Forms/ChannelForm.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import Enzyme, { shallow, mount } from 'enzyme';
7 | import { unwrap } from '@material-ui/core/test-utils';
8 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
9 | import Adapter from 'enzyme-adapter-react-16';
10 | import { createMuiTheme } from '@material-ui/core/styles';
11 | import ChannelForm from './ChannelForm';
12 |
13 | Enzyme.configure({ adapter: new Adapter() });
14 |
15 | const ComponentNaked = unwrap(ChannelForm);
16 |
17 | describe('', () => {
18 | it('with shallow', () => {
19 | const wrapper = shallow();
20 | expect(wrapper.exists()).toBe(true);
21 | });
22 |
23 | it('with mount', () => {
24 | const wrapper = mount(
25 |
26 |
27 |
28 | );
29 | expect(wrapper.exists()).toBe(true);
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/client/src/components/View/BlockView.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import Enzyme, { shallow, mount } from 'enzyme';
7 | import { unwrap } from '@material-ui/core/test-utils';
8 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
9 | import Adapter from 'enzyme-adapter-react-16';
10 | import { createMuiTheme } from '@material-ui/core/styles';
11 | import BlockView from './BlockView';
12 |
13 | Enzyme.configure({ adapter: new Adapter() });
14 |
15 | const ComponentNaked = unwrap(BlockView);
16 |
17 | describe('', () => {
18 | it('with shallow', () => {
19 | const wrapper = shallow();
20 | expect(wrapper.exists()).toBe(true);
21 | });
22 |
23 | it('with mount', () => {
24 | const wrapper = mount(
25 |
26 |
27 |
28 | );
29 | expect(wrapper.exists()).toBe(true);
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/syncstart.sh:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | #!/bin/bash
6 |
7 | # Please visit ./logs/sync/app to view the application logs and visit the ./logs/sync/db to view the Database logs and visit the ./logs/sync/console for the console.log
8 | # Log rotating for every 7 days.
9 |
10 | export SYNC_LOG_PATH=./logs/sync
11 |
12 | echo "************************************************************************************"
13 | echo "**************************** Hyperledger Explorer Sync**********************************"
14 | echo "************************************************************************************"
15 |
16 | export LOG_LEVEL_APP=${LOG_LEVEL_APP:-debug}
17 | export LOG_LEVEL_DB=${LOG_LEVEL_DB:-debug}
18 | export LOG_LEVEL_CONSOLE=${LOG_LEVEL_CONSOLE:-info}
19 | export LOG_CONSOLE_STDOUT=${LOG_CONSOLE_STDOUT:-false}
20 |
21 | export DISCOVERY_AS_LOCALHOST=${DISCOVERY_AS_LOCALHOST:-true}
22 | export EXPLORER_APP_ROOT=${EXPLORER_APP_ROOT:-dist}
23 |
24 | node ${EXPLORER_APP_ROOT}/sync.js $1 $2 &
25 |
--------------------------------------------------------------------------------
/client/src/components/Lists/constants.js:
--------------------------------------------------------------------------------
1 | export const rowsPerPageOptions = [5, 10, 25, 50, 100];
2 | export const reg = new RegExp("^[0-9]{0,9}$");
3 | export const rangeLimitOptions = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
4 | export const defaultRangeLimit = 10;
5 | export const E001 = "Please enter From and To fields";
6 | export const E002 = '"To" Block should be less than or equal to "From" Block';
7 | export const E003 = `Maximum allowed No of Block(s) is ${
8 | rangeLimitOptions[rangeLimitOptions.length - 1]
9 | }`;
10 | export const E004 = limit =>
11 | `No of Block(s) is set to ${limit}. Increase it to search for higher range.`;
12 | export const E005 = `Maximum allowed No of Block(s) is ${
13 | rangeLimitOptions[rangeLimitOptions.length - 1]
14 | }. Set lower range for better performance.`;
15 | export const E006 = "Total block count in ledger";
16 | export const E007 = "Blocks available after purge/boot-time";
17 | export const E008 = "Transactions available after purge/boot-time";
18 | export const E009 = "Transactions available after purge/boot-time";
19 |
--------------------------------------------------------------------------------
/docs/source/repos.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 |
6 | Repositories/Links
7 | ===================
8 |
9 | Hyperledger Explorer Repositories
10 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 |
12 |
13 |
14 | - GitHub:
15 |
16 | * `Hyperledger Explorer github repository `__.
17 |
18 | - Docker:
19 | -For v2.0.0 and above:
20 |
21 | * `Hyperledger Explorer ghcr repository `__.
22 | * `Hyperledger Explorer PostgreSQL ghcr repository `__.
23 |
24 | -For v1.1.8 and below:
25 |
26 | * `Hyperledger Explorer docker repository `__.
27 | * `Hyperledger Explorer PostgreSQL docker repository `__.
28 |
29 |
30 |
31 |
32 | .. Licensed under Creative Commons Attribution 4.0 International License
33 | https://creativecommons.org/licenses/by/4.0/
34 |
--------------------------------------------------------------------------------
/client/src/components/Footer/FooterView.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import { withStyles } from '@material-ui/core/styles';
7 | import clientJson from '../../../package.json';
8 | import FabricVersion from '../../FabricVersion';
9 |
10 | const styles = theme => {
11 | const { type } = theme.palette;
12 | const dark = type === 'dark';
13 | return {
14 | root: {
15 | margin: '2%'
16 | },
17 | footer: {
18 | backgroundColor: dark ? '#5e558e' : '#e8e8e8',
19 | color: dark ? '#ffffff' : undefined,
20 | textAlign: 'center',
21 | position: 'fixed',
22 | left: 0,
23 | right: 0,
24 | bottom: 0
25 | }
26 | };
27 | };
28 |
29 | const FooterView = ({ classes }) => (
30 |
31 |
32 |
33 | {'Hyperledger Explorer Client Version: '}
34 | {clientJson.version}
35 |
36 | {'Fabric Compatibility: '} {FabricVersion.map(v => v)}
37 |
38 |
39 |
40 | );
41 |
42 | export default withStyles(styles)(FooterView);
43 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/validate_hash.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | channel=commonchannel
4 | while getopts "c:" opt; do
5 | case "$opt" in
6 | c)
7 | channel=$OPTARG
8 | ;;
9 | esac
10 | done
11 |
12 | docker exec explorerdb.mynetwork.com \
13 | psql -t -U postgres fabricexplorer -c \
14 | "select array_to_json(array_agg(row_to_json(t)))
15 | from (
16 | select blocks.blocknum, blocks.prehash, blocks.blockhash from blocks
17 | join channel on blocks.channel_genesis_hash = channel.channel_genesis_hash
18 | where channel.name='${channel}'
19 | order by blocknum
20 | ) t" > result.json
21 |
22 | length=$(jq 'length' result.json)
23 | i=0
24 | while [ $i -lt $(expr $length - 1) ]; do
25 | current=$i
26 | i=$(expr $i + 1)
27 | next=$i
28 | bh=$(jq '.['$current'].blockhash' result.json)
29 | ph=$(jq '.['$next'].prehash' result.json)
30 | echo $bh
31 | echo $ph
32 | if [ $bh != $ph ]; then
33 | echo "FAIL... Invalid blockhash chain : $(jq '.['$current'].blocknum' result.json)"
34 | exit 1
35 | fi
36 | done
37 |
38 | echo 'PASS!!! Valid blockhash chain'
39 | exit 0
40 |
41 |
--------------------------------------------------------------------------------
/client/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import ReactDOM from 'react-dom';
7 | import { Provider } from 'react-redux';
8 | import createStore from './state/store';
9 | import authOperations from './state/redux/auth/operations';
10 | import Theme from './components/Theme';
11 | import App from './components/App';
12 | import { unregister } from './registerServiceWorker';
13 |
14 | const mode = localStorage.getItem('theme-mode') || 'light';
15 | const store = createStore({ theme: { mode } });
16 |
17 | store.subscribe(themeSideEffect(store));
18 |
19 | function themeSideEffect(storeObj) {
20 | let theme;
21 | return () => {
22 | const state = storeObj.getState();
23 | if (theme !== state.theme) {
24 | theme = state.theme;
25 | localStorage.setItem('theme-mode', theme.mode);
26 | }
27 | };
28 | }
29 |
30 | store.dispatch(authOperations.network());
31 |
32 | unregister();
33 |
34 | ReactDOM.render(
35 |
36 |
37 |
38 |
39 | ,
40 | document.getElementById('root')
41 | );
42 |
--------------------------------------------------------------------------------
/docs/source/architecture/backend.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | Back End Layer
6 | ===========================================
7 |
8 | .. JavaScript has a bold proof to be an undisputed leader among the most popular programming languages.
9 | In turn, Node.js has carved its name in the industry.
10 | Why Node.js is a right choice for Hyperledger Explorer?
11 | - Best efficiency and developer productivity
12 | - Sharing and code reuse
13 | - Performance and speed
14 | - Easy knowledge sharing within a team
15 | - Largely maintained libraries
16 | - Growing number of free tools
17 | - Unlimited discussion groups and forums
18 |
19 |
20 |
21 | Main components of the HLExplorer back end can be listed as:
22 |
23 | .. .. image:: ../images/backend.png
24 | .. :width: 850px
25 |
26 | .. toctree::
27 | :maxdepth: 1
28 |
29 |
30 | webserver
31 | restapi
32 | gateway
33 | dbservices
34 | synchronizer
35 | websockets
36 | logs
37 |
38 |
39 |
40 | .. Licensed under Creative Commons Attribution 4.0 International License
41 | https://creativecommons.org/licenses/by/4.0/
42 |
--------------------------------------------------------------------------------
/client/src/components/Styled/View.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import { withStyles } from '@material-ui/core/styles';
7 | import Card from '@material-ui/core/Card';
8 |
9 | const styles = (theme) => {
10 | const { type } = theme.palette;
11 | const dark = type === 'dark';
12 | return {
13 | fullwidth: {
14 | width: '100%',
15 | marginTop: 105,
16 | backgroundColor: dark ? 'rgb(36, 32, 54)' : '#f0f5f9',
17 | },
18 | display: {
19 | display: 'block',
20 | marginLeft: 'auto',
21 | marginRight: 'auto',
22 | width: '80%',
23 | backgroundColor: dark ? 'transparent' : undefined,
24 | },
25 | card: {
26 | color: dark ? '#ffffff' : undefined,
27 | backgroundColor: dark ? '#453e68' : undefined,
28 | },
29 | };
30 | };
31 |
32 | export const View = ({ children, classes }) => (
33 |
34 |
35 |
36 | {children}
37 |
38 |
39 |
40 | );
41 |
42 | export default withStyles(styles)(View);
43 |
--------------------------------------------------------------------------------
/start.sh:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 |
5 | #!/bin/bash
6 | #
7 | #Redirecting console.log to log file.
8 | #Please visit ./logs/app to view the application logs and visit the ./logs/db to view the Database logs and visit the ./log/console for the console.log
9 | # Log rotating for every 7 days.
10 |
11 | echo "************************************************************************************"
12 | echo "**************************** Hyperledger Explorer **********************************"
13 | echo "************************************************************************************"
14 |
15 | export LOG_LEVEL_APP=${LOG_LEVEL_APP:-debug}
16 | export LOG_LEVEL_DB=${LOG_LEVEL_DB:-debug}
17 | export LOG_LEVEL_CONSOLE=${LOG_LEVEL_CONSOLE:-info}
18 | export LOG_CONSOLE_STDOUT=${LOG_CONSOLE_STDOUT:-false}
19 |
20 | export DISCOVERY_AS_LOCALHOST=${DISCOVERY_AS_LOCALHOST:-true}
21 | export EXPLORER_APP_ROOT=${EXPLORER_APP_ROOT:-dist}
22 | export PORT=${PORT:-8080}
23 |
24 | log_exit() {
25 | echo "Server stopped"
26 | exit
27 | }
28 | trap log_exit INT EXIT
29 | echo "Server running..."
30 |
31 | node ${EXPLORER_APP_ROOT}/main.js name - hyperledger-explorer
32 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # Hyperledger Security Policy
5 |
6 | ## Reporting a Security Bug
7 |
8 | If you think you have discovered a security issue in any of the Hyperledger projects, we'd love to hear from you. We will take all security bugs seriously and if confirmed upon investigation we will patch it within a reasonable amount of time and release a public security bulletin discussing the impact and credit the discoverer.
9 |
10 | There are two ways to report a security bug. The easiest is to email a description of the flaw and any related information (e.g. reproduction steps, version) to [security at hyperledger dot org](mailto:security@hyperledger.org).
11 |
12 | The other way is to file a confidential security bug in our [JIRA bug tracking system](https://jira.hyperledger.org). Be sure to set the “Security Level” to “Security issue”.
13 |
14 | The process by which the Hyperledger Security Team handles security bugs is documented further in our [Defect Response page](https://wiki.hyperledger.org/display/HYP/Defect+Response) on our [wiki](https://wiki.hyperledger.org).
15 |
16 |
--------------------------------------------------------------------------------
/app/sync/sender/ExplorerSender.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { explorerConst } from '../../common/ExplorerConst';
6 | import { ForkSenderHandler } from './ForkSenderHandler';
7 |
8 | /**
9 | *
10 | *
11 | * @class ExplorerSender
12 | */
13 | export class ExplorerSender {
14 | public syncType: any;
15 | public syncSenderHandler: any;
16 |
17 | /**
18 | * Creates an instance of ExplorerSender.
19 | * @param {*} syncconfig
20 | * @memberof ExplorerSender
21 | */
22 | constructor(syncconfig) {
23 | this.syncType = syncconfig.type;
24 | this.syncSenderHandler = null;
25 | }
26 |
27 | /**
28 | *
29 | *
30 | * @memberof ExplorerSender
31 | */
32 | async initialize() {
33 | if (this.syncType && this.syncType === explorerConst.SYNC_TYPE_LOCAL) {
34 | this.syncSenderHandler = new ForkSenderHandler();
35 | }
36 | if (this.syncSenderHandler) {
37 | this.syncSenderHandler.initialize();
38 | }
39 | }
40 |
41 | /**
42 | *
43 | *
44 | * @param {*} message
45 | * @memberof ExplorerSender
46 | */
47 | send(message) {
48 | if (this.syncSenderHandler) {
49 | this.syncSenderHandler.send(message);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/client/src/components/Lists/PeersHealth.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import ReactTable from '../Styled/Table';
6 | import PeersHealth from './PeersHealth';
7 |
8 | const setup = () => {
9 | const props = {
10 | classes: {
11 | table: 'table',
12 | center: 'center',
13 | },
14 | peerStatus: [
15 | {
16 | status: 'UP',
17 | server_hostname: 'peer0.org1.example.com',
18 | },
19 | {
20 | status: 'UP',
21 | server_hostname: 'peer1.org1.example.com',
22 | },
23 | {
24 | status: 'UP',
25 | server_hostname: 'peer0.org2.example.com',
26 | },
27 | {
28 | status: 'DOWN',
29 | server_hostname: 'peer1.org2.example.com',
30 | },
31 | ],
32 | };
33 |
34 | const wrapper = mount();
35 |
36 | return {
37 | props,
38 | wrapper,
39 | };
40 | };
41 |
42 | describe('PeersHealth', () => {
43 | test('PeersHealth and ReactTable components should render', () => {
44 | const { wrapper } = setup();
45 | expect(wrapper.exists()).toBe(true);
46 | expect(wrapper.find(ReactTable).exists()).toBe(true);
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/app/model/User.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import * as Sequelize from 'sequelize';
6 |
7 | export const attributes = {
8 | username: {
9 | type: Sequelize.DataTypes.STRING,
10 | allowNull: false,
11 | unique: true,
12 | validate: {
13 | is: {
14 | args: /^[a-z0-9_-]+$/i,
15 | msg:
16 | 'Username allows only lowercase alphanumeric characters with hyphen and underscore Ex:(a-z0-9_-)'
17 | }
18 | }
19 | },
20 | email: {
21 | type: Sequelize.DataTypes.STRING,
22 | validate: {
23 | isEmail: {
24 | args: true,
25 | msg: 'Invalid email format'
26 | }
27 | }
28 | },
29 | networkName: {
30 | type: Sequelize.DataTypes.STRING,
31 | allowNull: false
32 | },
33 | firstName: {
34 | type: Sequelize.DataTypes.STRING
35 | },
36 | lastName: {
37 | type: Sequelize.DataTypes.STRING
38 | },
39 | password: {
40 | type: Sequelize.DataTypes.STRING
41 | },
42 | roles: {
43 | type: Sequelize.DataTypes.STRING
44 | },
45 | salt: {
46 | type: Sequelize.DataTypes.STRING
47 | }
48 | };
49 |
50 | export const options = {
51 | freezeTableName: true,
52 | indexes: [
53 | {
54 | unique: true,
55 | fields: ['username', 'networkName']
56 | }
57 | ]
58 | };
59 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/go.mod:
--------------------------------------------------------------------------------
1 | module apitest
2 |
3 | // SPDX-License-Identifier: Apache-2.0
4 |
5 | go 1.13
6 |
7 | require (
8 | github.com/cosiner/argv v0.0.1 // indirect
9 | github.com/fsouza/go-dockerclient v1.6.3 // indirect
10 | github.com/go-delve/delve v1.4.0 // indirect
11 | github.com/go-resty/resty/v2 v2.1.0
12 | github.com/hyperledger/fabric-test v1.4.5-0.20200212013951-45799a2ee4ee
13 | github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
14 | github.com/mattn/go-colorable v0.1.4 // indirect
15 | github.com/mattn/go-isatty v0.0.12 // indirect
16 | github.com/mattn/go-runewidth v0.0.8 // indirect
17 | github.com/onsi/ginkgo v1.12.0
18 | github.com/onsi/gomega v1.9.0
19 | github.com/peterh/liner v1.2.0 // indirect
20 | github.com/pkg/errors v0.9.1 // indirect
21 | github.com/sirupsen/logrus v1.4.2 // indirect
22 | github.com/spf13/cobra v0.0.5 // indirect
23 | github.com/spf13/pflag v1.0.5 // indirect
24 | go.starlark.net v0.0.0-20200203144150-6677ee5c7211 // indirect
25 | golang.org/x/arch v0.0.0-20191126211547-368ea8f32fff // indirect
26 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect
27 | gopkg.in/yaml.v2 v2.2.8 // indirect
28 | k8s.io/client-go v0.16.8 // indirect
29 | )
30 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/templates-v1/crypto-config.yaml:
--------------------------------------------------------------------------------
1 | #! Copyright IBM Corp. All Rights Reserved.
2 | #!
3 | #! SPDX-License-Identifier: Apache-2.0
4 |
5 | #@ load("@ytt:data", "data")
6 | #@ config = data.values
7 | OrdererOrgs:
8 | #@ num_organizations = len(config.ordererOrganizations)
9 | #@ for i in range(0, num_organizations):
10 | #@ ordererOrg = config.ordererOrganizations[i]
11 | - Domain: #@ ordererOrg.name
12 | Name: #@ ordererOrg.name
13 | EnableNodeOUs: #@ config.enableNodeOUs
14 | Specs:
15 | #@ numOderers = ordererOrg.numOderers
16 | #@ for i in range(0, numOderers):
17 | - Hostname: #@ "orderer{}-{}".format(i, ordererOrg.name)
18 | #@ if config.nodeportIP != "":
19 | SANS:
20 | - #@ config.nodeportIP
21 | #@ end
22 | #@ end
23 | #@ end
24 | PeerOrgs:
25 | #@ for i in range(0, len(config.peerOrganizations)):
26 | #@ peerOrg = config.peerOrganizations[i]
27 | - Domain: #@ peerOrg.name
28 | Name: #@ peerOrg.name
29 | EnableNodeOUs: #@ config.enableNodeOUs
30 | Specs:
31 | #@ for i in range(0, peerOrg.numPeers):
32 | - Hostname: #@ "peer{}-{}".format(i, peerOrg.name)
33 | #@ if config.nodeportIP != "":
34 | SANS:
35 | - #@ config.nodeportIP
36 | #@ end
37 | #@ end
38 | #@ end
--------------------------------------------------------------------------------
/client/src/components/Styled/View.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import Enzyme, { shallow, mount } from 'enzyme';
6 | import { unwrap } from '@material-ui/core/test-utils';
7 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
8 | import Adapter from 'enzyme-adapter-react-16';
9 | import { createMuiTheme } from '@material-ui/core/styles';
10 | import View from './View';
11 |
12 | Enzyme.configure({ adapter: new Adapter() });
13 |
14 | const ComponentNaked = unwrap(View);
15 |
16 | describe('', () => {
17 | it('with shallow', () => {
18 | const wrapper = shallow();
19 | expect(wrapper.exists()).toBe(true);
20 | });
21 |
22 | it('with mount', () => {
23 | const wrapper = mount(
24 |
25 |
26 |
27 | );
28 | expect(wrapper.exists()).toBe(true);
29 | });
30 |
31 | it('Check if dark theme is applied correctly', () => {
32 | const wrapperone = mount(
33 |
34 |
35 |
36 | );
37 | expect(wrapperone.exists()).toBe(true);
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/app/platform/fabric/service/NetworkService.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { helper } from '../../../common/helper';
6 |
7 | const logger = helper.getLogger('NetworkService');
8 |
9 | /**
10 | *
11 | *
12 | * @class NetworkService
13 | */
14 | export class NetworkService {
15 | platform: any;
16 | /**
17 | * Creates an instance of NetworkService.
18 | * @param {*} platform
19 | * @memberof NetworkService
20 | */
21 | constructor(platform) {
22 | this.platform = platform;
23 | }
24 |
25 | /**
26 | *
27 | *
28 | * @returns
29 | * @memberof NetworkService
30 | */
31 | async networkList() {
32 | // Get the list of the networks from the configuration that was loaded from the config.json
33 | const networklist = [];
34 | const networks = this.platform.getNetworks();
35 | logger.debug('Network list ', networks);
36 | for (const [network_id, clientObj] of networks.entries()) {
37 | logger.debug('Network list ', clientObj.name);
38 | networklist.push({
39 | id: network_id,
40 | name: clientObj.name,
41 | authEnabled: clientObj.instance.fabricGateway.getEnableAuthentication()
42 | });
43 | }
44 |
45 | logger.debug('Network list ', networklist);
46 | return networklist;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/test/api/connection-profile/test-network.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-network",
3 | "version": "1.0.0",
4 | "client": {
5 | "tlsEnable": true,
6 | "adminCredential": {
7 | "id": "exploreradmin",
8 | "password": "exploreradminpw"
9 | },
10 | "enableAuthentication": true,
11 | "organization": "Org1MSP",
12 | "connection": {
13 | "timeout": {
14 | "peer": {
15 | "endorser": "300"
16 | },
17 | "orderer": "300"
18 | }
19 | }
20 | },
21 | "channels": {
22 | "mychannel": {
23 | "peers": {
24 | "peer0.org1.example.com": {}
25 | }
26 | }
27 | },
28 | "organizations": {
29 | "Org1MSP": {
30 | "mspid": "Org1MSP",
31 | "adminPrivateKey": {
32 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/priv_sk"
33 | },
34 | "peers": ["peer0.org1.example.com"],
35 | "signedCert": {
36 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem"
37 | }
38 | }
39 | },
40 | "peers": {
41 | "peer0.org1.example.com": {
42 | "tlsCACerts": {
43 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
44 | },
45 | "url": "grpcs://peer0.org1.example.com:7051"
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/client/src/components/Styled/Select.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import Enzyme, { shallow, mount } from 'enzyme';
7 | import { unwrap } from '@material-ui/core/test-utils';
8 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
9 | import Adapter from 'enzyme-adapter-react-16';
10 | import { createMuiTheme } from '@material-ui/core/styles';
11 | import Select from './Select';
12 |
13 | Enzyme.configure({ adapter: new Adapter() });
14 |
15 | const ComponentNaked = unwrap(Select);
16 |
17 | describe('', () => {
18 | it('with shallow', () => {
19 | const wrapper = shallow();
20 | expect(wrapper.exists()).toBe(true);
21 | });
22 |
23 | it('with mount', () => {
24 | const wrapper = mount(
25 |
26 |
27 |
28 | );
29 | expect(wrapper.exists()).toBe(true);
30 | });
31 |
32 | it('Check if dark theme is applied correctly', () => {
33 | const wrapperone = mount(
34 |
35 |
36 |
37 | );
38 | expect(wrapperone.exists()).toBe(true);
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/client/src/static/css/main-dark.css:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | /* Dark-Theme is switched by the class name */
5 |
6 | .dark-theme svg.custom .node circle {
7 | fill: #f3f3ff;
8 | stroke: #2593b8;
9 | }
10 |
11 | .dark-theme svg.custom .node text {
12 | background-color: #444;
13 | fill: #000000;
14 | }
15 |
16 | /*Tables Styling*/
17 | .dark-theme .table-hover tbody tr:hover td,
18 | .dark-theme .table-hover tbody tr:hover th {
19 | transition: background-color 1s ease;
20 | background-color: #5e558e !important;
21 | opacity: 0.8;
22 | }
23 |
24 | .dark-theme .-pageJump input {
25 | background: #7165ad !important;
26 | color: #ffffff !important;
27 | }
28 | .dark-theme .select-wrap select {
29 | background: #7165ad !important;
30 | color: #ffffff !important;
31 | }
32 |
33 | .dark-theme li .active {
34 | color: #ffffff !important;
35 | background-color: #5e558e !important;
36 | }
37 | .dark-theme li .active:hover {
38 | color: #ffffff !important;
39 | }
40 |
41 | .dark-theme .active .nav-link {
42 | color: #ffffff;
43 | fill: #ffffff;
44 | }
45 |
46 | /*Time Chart and Chart stats */
47 | .dark-theme .nav-link:hover {
48 | color: #007bff !important;
49 | }
50 | .dark-theme .rt-noData {
51 | color: #ffffff !important;
52 | background: transparent !important;
53 | }
54 |
--------------------------------------------------------------------------------
/examples/net1/connection-profile/test-network.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-network",
3 | "version": "1.0.0",
4 | "client": {
5 | "tlsEnable": true,
6 | "adminCredential": {
7 | "id": "exploreradmin",
8 | "password": "exploreradminpw"
9 | },
10 | "enableAuthentication": true,
11 | "organization": "Org1MSP",
12 | "connection": {
13 | "timeout": {
14 | "peer": {
15 | "endorser": "300"
16 | },
17 | "orderer": "300"
18 | }
19 | }
20 | },
21 | "channels": {
22 | "mychannel": {
23 | "peers": {
24 | "peer0.org1.example.com": {}
25 | }
26 | }
27 | },
28 | "organizations": {
29 | "Org1MSP": {
30 | "mspid": "Org1MSP",
31 | "adminPrivateKey": {
32 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/priv_sk"
33 | },
34 | "peers": ["peer0.org1.example.com"],
35 | "signedCert": {
36 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem"
37 | }
38 | }
39 | },
40 | "peers": {
41 | "peer0.org1.example.com": {
42 | "tlsCACerts": {
43 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
44 | },
45 | "url": "grpcs://peer0.org1.example.com:7051"
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/app/platform/fabric/models/User.ts:
--------------------------------------------------------------------------------
1 | /*
2 | *SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import {helper} from '../../../common/helper';
6 |
7 | const logger = helper.getLogger('User');
8 |
9 | /**
10 | *
11 | *
12 | * @class User
13 | */
14 | export class User {
15 | userJson : any;
16 | user: any;
17 |
18 | /**
19 | * Creates an instance of User.
20 | * @param {*} user
21 | * @memberof User
22 | */
23 | constructor(user) {
24 | // Put the user request in user object
25 | this.userJson = {};
26 | logger.debug(`User : ${user.user}`);
27 | Object.keys(user).forEach(key => {
28 | const value = user[key];
29 | this.userJson[key] = value;
30 | });
31 | }
32 |
33 | /**
34 | *
35 | * Create and return the User object by specifying minimum parameters
36 | * @param {string} user
37 | * @param {string} password
38 | * @param {string} network
39 | * @param {string} roles
40 | * @returns {User} Newly defined User object
41 | * @memberof User
42 | */
43 | static createInstanceWithParam(user, password, network, roles) : any {
44 | return new User({
45 | user,
46 | password,
47 | network,
48 | roles
49 | });
50 | }
51 |
52 | /**
53 | *
54 | *
55 | * @returns
56 | * @memberof User
57 | */
58 | async asJson() {
59 | return this.userJson;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/client/src/components/Footer/FooterView.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import Enzyme, { shallow, mount } from 'enzyme';
7 | import { unwrap } from '@material-ui/core/test-utils';
8 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
9 | import Adapter from 'enzyme-adapter-react-16';
10 | import { createMuiTheme } from '@material-ui/core/styles';
11 | import FooterView from './FooterView';
12 |
13 | Enzyme.configure({ adapter: new Adapter() });
14 |
15 | const ComponentNaked = unwrap(FooterView);
16 |
17 | describe('', () => {
18 | it('with shallow', () => {
19 | const wrapper = shallow();
20 | expect(wrapper.exists()).toBe(true);
21 | });
22 |
23 | it('with mount', () => {
24 | const wrapper = mount(
25 |
26 |
27 |
28 | );
29 | expect(wrapper.exists()).toBe(true);
30 | });
31 |
32 | it('Check if dark theme is applied correctly', () => {
33 | const wrapperone = mount(
34 |
35 |
36 |
37 | );
38 | expect(wrapperone.exists()).toBe(true);
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/client/src/state/redux/charts/types.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | const namespaces = 'charts';
6 | /* Analytics Charts */
7 | const BLOCK_CHART_MIN = `${namespaces}/BLOCK_CHART_MIN`;
8 | const BLOCK_CHART_HOUR = `${namespaces}/BLOCK_CHART_HOUR`;
9 | const TRANSACTION_CHART_MIN = `${namespaces}/TRANSACTION_CHART_MIN`;
10 | const TRANSACTION_CHART_HOUR = `${namespaces}/TRANSACTION_CHART_HOUR`;
11 |
12 | /* Pie Graph */
13 | const TRANSACTION_CHART_ORG = `${namespaces}/TRANSACTION_CHART_ORG`;
14 |
15 | /* Notification */
16 | const NOTIFICATION_LOAD = `${namespaces}/NOTIFICATION_LOAD`;
17 |
18 | /* Dash Stats */
19 | const DASHBOARD_STATS = `${namespaces}/DASHBOARD_STATS`;
20 |
21 | /* Channel */
22 | const CHANNEL = `${namespaces}/CHANNEL`;
23 | const CHANGE_CHANNEL = `${namespaces}/CHANGE_CHANNEL`;
24 | const CHANNEL_LIST = `${namespaces}/CHANNEL_LIST`;
25 |
26 |
27 | const ERROR_MESSAGE = 'ERROR_MESSAGE';
28 |
29 | const BLOCK_ACTIVITY = `${namespaces}/BLOCK_ACTIVITY`;
30 |
31 | export default {
32 | BLOCK_CHART_HOUR,
33 | BLOCK_CHART_MIN,
34 | CHANGE_CHANNEL,
35 | CHANNEL,
36 | CHANNEL_LIST,
37 | DASHBOARD_STATS,
38 | NOTIFICATION_LOAD,
39 | TRANSACTION_CHART_HOUR,
40 | TRANSACTION_CHART_MIN,
41 | TRANSACTION_CHART_ORG,
42 | ERROR_MESSAGE,
43 | BLOCK_ACTIVITY,
44 | };
45 |
--------------------------------------------------------------------------------
/client/src/components/View/PageNotFound.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.
3 | *
4 | **/
5 |
6 | import React from 'react';
7 | import Enzyme, { shallow, mount } from 'enzyme';
8 | import { unwrap } from '@material-ui/core/test-utils';
9 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
10 | import Adapter from 'enzyme-adapter-react-16';
11 | import { createMuiTheme } from '@material-ui/core/styles';
12 | import PageNotFound from './PageNotFound';
13 |
14 | Enzyme.configure({ adapter: new Adapter() });
15 | const ComponentNaked = unwrap(PageNotFound);
16 |
17 | describe('', () => {
18 | it('with shallow', () => {
19 | const wrapper = shallow();
20 | expect(wrapper.exists()).toBe(true);
21 | });
22 |
23 | it('with mount', () => {
24 | const wrapper = mount(
25 |
26 |
27 |
28 | );
29 | expect(wrapper.exists()).toBe(true);
30 | });
31 |
32 | it('Check if dark theme is applied correctly', () => {
33 | const wrapper = mount(
34 |
35 |
36 |
37 | );
38 | expect(wrapper.exists()).toBe(true);
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/client/e2e-test/specs/utils/helper.js:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | const scDirName = '.';
6 | const headless = true;
7 |
8 | let scIndex = 1;
9 | let scPrefix = '';
10 |
11 | setupPage = async context => {
12 | const page = await context.newPage();
13 | if (process.env.E2E_TEST_URL) {
14 | await page.goto(process.env.E2E_TEST_URL);
15 | } else {
16 | await page.goto('http://localhost:8080');
17 | }
18 | await page.fill('#user', 'admin');
19 | await page.fill('#password', 'adminpw');
20 | await page.click('button[type=submit]');
21 | await sleep(2000);
22 | return new Promise(resolve => resolve(page));
23 | };
24 |
25 | takeScreenShot = async (page, name) => {
26 | await sleep(2000);
27 | let prefix = String(scIndex++).padStart(3, '0');
28 | prefix = `${prefix}_${scPrefix}`;
29 | prefix = `${scDirName}/${prefix}`;
30 | return page.screenshot({ path: `${prefix}_${name}.png`, fullPage: true });
31 | };
32 |
33 | sleep = ms => {
34 | return new Promise(resolve => setTimeout(resolve, ms));
35 | };
36 |
37 | switchView = async (page, viewname) => {
38 | await sleep(1000);
39 | await page.click(`a >> text=${viewname}`);
40 | return sleep(1000);
41 | };
42 |
43 | isHeadless = () => headless;
44 |
45 | module.exports = {
46 | setupPage,
47 | takeScreenShot,
48 | sleep,
49 | switchView,
50 | isHeadless
51 | };
52 |
--------------------------------------------------------------------------------
/client/src/components/Forms/ChaincodeForm.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import Enzyme, { shallow, mount } from 'enzyme';
7 | import { unwrap } from '@material-ui/core/test-utils';
8 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
9 | import Adapter from 'enzyme-adapter-react-16';
10 | import { createMuiTheme } from '@material-ui/core/styles';
11 | import ChaincodeForm from './ChaincodeForm';
12 |
13 | Enzyme.configure({ adapter: new Adapter() });
14 |
15 | const ComponentNaked = unwrap(ChaincodeForm);
16 |
17 | describe('', () => {
18 | it('with shallow', () => {
19 | const wrapper = shallow();
20 | expect(wrapper.exists()).toBe(true);
21 | });
22 |
23 | it('with mount', () => {
24 | const wrapper = mount(
25 |
26 |
27 |
28 | );
29 | expect(wrapper.exists()).toBe(true);
30 | });
31 |
32 | it('Check if dark theme is applied correctly', () => {
33 | const wrapperone = mount(
34 |
35 |
36 |
37 | );
38 | expect(wrapperone.exists()).toBe(true);
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/client/src/components/View/ChaincodeModal.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import React from 'react';
6 | import Enzyme, { shallow, mount } from 'enzyme';
7 | import { unwrap } from '@material-ui/core/test-utils';
8 | import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider';
9 | import Adapter from 'enzyme-adapter-react-16';
10 | import { createMuiTheme } from '@material-ui/core/styles';
11 | import ChaincodeModal from './ChaincodeModal';
12 |
13 | Enzyme.configure({ adapter: new Adapter() });
14 | const ComponentNaked = unwrap(ChaincodeModal);
15 |
16 | describe('', () => {
17 | it('with shallow', () => {
18 | const wrapper = shallow();
19 | expect(wrapper.exists()).toBe(true);
20 | });
21 | it('with mount', () => {
22 | const wrapper = mount(
23 |
24 |
25 |
26 | );
27 | expect(wrapper.exists()).toBe(true);
28 | });
29 |
30 | it('mount with dark', () => {
31 | const wrapper = mount(
32 |
33 |
34 |
35 | );
36 | expect(wrapper.exists()).toBe(true);
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/templates-v2/crypto-config.yaml:
--------------------------------------------------------------------------------
1 | #! Copyright IBM Corp. All Rights Reserved.
2 | #!
3 | #! SPDX-License-Identifier: Apache-2.0
4 |
5 | #@ load("@ytt:data", "data")
6 | #@ config = data.values
7 | #@ localIP = "127.0.0.1"
8 | OrdererOrgs:
9 | #@ num_organizations = len(config.ordererOrganizations)
10 | #@ for i in range(0, num_organizations):
11 | #@ ordererOrg = config.ordererOrganizations[i]
12 | - Domain: #@ ordererOrg.name
13 | Name: #@ ordererOrg.name
14 | EnableNodeOUs: #@ config.enableNodeOUs
15 | Specs:
16 | #@ numOderers = ordererOrg.numOderers
17 | #@ for i in range(0, numOderers):
18 | - Hostname: #@ "orderer{}-{}".format(i, ordererOrg.name)
19 | SANS:
20 | - #@ "{}".format(localIP)
21 | #@ if config.nodeportIP != "":
22 | - #@ config.nodeportIP
23 | #@ end
24 | #@ end
25 | #@ end
26 | PeerOrgs:
27 | #@ for i in range(0, len(config.peerOrganizations)):
28 | #@ peerOrg = config.peerOrganizations[i]
29 | - Domain: #@ peerOrg.name
30 | Name: #@ peerOrg.name
31 | EnableNodeOUs: #@ config.enableNodeOUs
32 | Specs:
33 | #@ for i in range(0, peerOrg.numPeers):
34 | - Hostname: #@ "peer{}-{}".format(i, peerOrg.name)
35 | SANS:
36 | - #@ "{}".format(localIP)
37 | #@ if config.nodeportIP != "":
38 | - #@ config.nodeportIP
39 | #@ end
40 | #@ end
41 | #@ end
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/apitest_suite_test.go:
--------------------------------------------------------------------------------
1 | package apitest
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "os/exec"
7 | "testing"
8 |
9 | . "github.com/onsi/ginkgo"
10 | "github.com/onsi/ginkgo/reporters"
11 | . "github.com/onsi/gomega"
12 | "github.com/onsi/gomega/gexec"
13 | )
14 |
15 | var failed = false
16 |
17 | func TestRestApi(t *testing.T) {
18 | RegisterFailHandler(Fail)
19 | junitReporter := reporters.NewJUnitReporter("results_rest-api-test-suite.xml")
20 | RunSpecsWithDefaultAndCustomReporters(t, "Rest Api Test Suite", []Reporter{junitReporter})
21 | }
22 |
23 | // Bringing up network using BeforeSuite
24 | var _ = BeforeSuite(func() {
25 | })
26 |
27 | // Cleaning up network launched from BeforeSuite and removing all chaincode containers
28 | // and chaincode container images using AfterSuite
29 | var _ = AfterSuite(func() {
30 | if failed {
31 | dumpLog()
32 | }
33 | })
34 |
35 | var _ = AfterEach(func() {
36 | failed = failed || CurrentGinkgoTestDescription().Failed
37 | })
38 |
39 | func dumpLog() {
40 | cwd, _ := os.Getwd()
41 | fmt.Println("=== Dump Explorer app log ===")
42 | fmt.Println(cwd)
43 | os.Chdir(relativePahtToRoot)
44 | cmd := exec.Command("docker", "logs", "explorer.mynetwork.com")
45 | session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
46 | Expect(err).ShouldNot(HaveOccurred())
47 | session.Wait()
48 | }
49 |
--------------------------------------------------------------------------------
/client/src/state/redux/tables/types.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | const namespaces = 'tables';
6 |
7 | const BLOCK_LIST = `${namespaces}/BLOCK_LIST`;
8 | const CHAINCODE_LIST = `${namespaces}/CHAINCODE_LIST`;
9 | const CHANNELS = `${namespaces}/CHANNELS`;
10 | const PEER_LIST = `${namespaces}/PEER_LIST`;
11 | const TXN_LIST = 'TXN_LIST';
12 | const BLOCK_HASH = 'BLOCK_HASH';
13 | const BLOCK_TXN = 'BLOCK_TXN';
14 | const BLOCK_SEARCH = 'BLOCK_SEARCH';
15 | const CHAINCODE_META_DATA = 'CHAINCODE_META_DATA';
16 | const CHANNEL_PEER_DATA = 'CHANNEL_PEER_DATA';
17 | const TRANSACTION = `${namespaces}/TRANSACTION`;
18 | const TRANSACTION_LIST = `${namespaces}/TRANSACTION_LIST`;
19 | const BLOCK_LIST_SEARCH = `${namespaces}/BLOCK_LIST_SEARCH`;
20 | const BLOCK_RANGE_SEARCH = 'BLOCK_RANGE_SEARCH';
21 | const BLOCK_RANGE_LOADED = `${namespaces}/BLOCK_RANGE_LOADED`;
22 | const TRANSACTION_LIST_SEARCH = `${namespaces}/TRANSACTION_LIST_SEARCH`;
23 | const ORGS = `${namespaces}/ORGS`;
24 |
25 | export default {
26 | BLOCK_LIST,
27 | CHAINCODE_LIST,
28 | CHANNELS,
29 | PEER_LIST,
30 | TXN_LIST,
31 | BLOCK_HASH,
32 | BLOCK_TXN,
33 | BLOCK_SEARCH,
34 | CHAINCODE_META_DATA,
35 | CHANNEL_PEER_DATA,
36 | TRANSACTION,
37 | TRANSACTION_LIST,
38 | BLOCK_LIST_SEARCH,
39 | BLOCK_RANGE_SEARCH,
40 | BLOCK_RANGE_LOADED,
41 | TRANSACTION_LIST_SEARCH,
42 | ORGS
43 | };
44 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | #### What this PR does / why we need it:
6 |
7 | #### Which issue(s) this PR fixes:
8 |
13 | Fixes #
14 |
15 | #### Special notes for your reviewer:
16 |
17 | #### Does this PR introduce a user-facing change?
18 |
24 | ```release-note
25 |
26 | ```
27 |
28 | #### Additional documentation, usage docs, etc.:
29 |
30 |
40 | ```docs
41 |
42 | ```
43 |
--------------------------------------------------------------------------------
/app/sync/listener/ForkListenerHandler.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import path from 'path';
6 | import { fork } from 'child_process';
7 |
8 | /**
9 | *
10 | *
11 | * @class ForkListenerHandler
12 | */
13 | export class ForkListenerHandler {
14 | public platform: any;
15 | public syncProcessor: any;
16 |
17 | /**
18 | * Creates an instance of ForkListenerHandler.
19 | * @param {*} platform
20 | * @memberof ForkListenerHandler
21 | */
22 | constructor(platform) {
23 | this.platform = platform;
24 | this.syncProcessor = null;
25 | }
26 |
27 | /**
28 | *
29 | *
30 | * @param {*} args
31 | * @memberof ForkListenerHandler
32 | */
33 | async initialize(args) {
34 | this.syncProcessor = fork(path.resolve(__dirname, '../../sync.js'), args, {
35 | env: {
36 | ...process.env,
37 | // Mark forked process explicitly for logging using TCP server
38 | FORK: '1'
39 | }
40 | });
41 |
42 | this.syncProcessor.on('message', msg => {
43 | this.platform.getProxy().processSyncMessage(msg);
44 | });
45 | }
46 |
47 | /**
48 | *
49 | * @param {*} message
50 | */
51 | send(message) {
52 | this.syncProcessor.send({
53 | message
54 | });
55 | }
56 |
57 | /**
58 | *
59 | *
60 | * @memberof ForkListenerHandler
61 | */
62 | close() {
63 | if (this.syncProcessor) {
64 | this.syncProcessor.kill('SIGINT');
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/client/src/components/View/PageNotFound.js:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 | import React from 'react';
3 | import { withStyles } from '@material-ui/core/styles';
4 | import FontAwesome from 'react-fontawesome';
5 |
6 | const styles = theme => {
7 | const { type } = theme.palette;
8 | const dark = type === 'dark';
9 | return {
10 | container: {
11 | marginTop: '10%'
12 | },
13 | content: {
14 | color: dark ? '#ffffff' : undefined,
15 | textAlign: 'center'
16 | },
17 | header: {
18 | color: '#58c5c2 !important',
19 | fontSize: '12em',
20 | textAlign: 'center',
21 | height: 220
22 | },
23 | subHeader: {
24 | color: dark ? '#ffffff' : undefined,
25 | fontSize: '4em !important',
26 | textAlign: 'center'
27 | },
28 | errorIcon: {
29 | size: '30px 30px',
30 | textAlign: 'center',
31 | color: '#f9be53',
32 | fontSize: '80%'
33 | }
34 | };
35 | };
36 |
37 | export const PageNotFound = ({ classes }) => (
38 |
39 |
40 |
41 | 404
42 |
43 |
Page not found
44 |
45 | {' '}
46 | The page you are trying to access does not exist. Please check the URL
47 |
48 |
49 | );
50 |
51 | export default withStyles(styles)(PageNotFound);
52 |
--------------------------------------------------------------------------------
/ci/azure-pipelines-release.yml:
--------------------------------------------------------------------------------
1 | # Copyright the Hyperledger Fabric contributors. All rights reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 |
5 | name: RELEASE-$(Date:yyyyMMdd)$(Rev:.rrr)
6 | trigger:
7 | tags:
8 | include:
9 | - v*
10 | pr: none
11 |
12 | variables:
13 | - group: secrets
14 |
15 | jobs:
16 | - job: Release
17 | pool:
18 | vmImage: ubuntu-20.04
19 | steps:
20 | - script: docker login --username=$(DockerHub-Username) --password=$(DockerHub-Password)
21 | displayName: Login to Docker
22 | - script: ./build_docker_image.sh
23 | displayName: Build Docker Images
24 | - script: docker tag hyperledger/explorer hyperledger/explorer:$(git describe --abbrev=0 --tags | cut -d 'v' -f 2)
25 | displayName: Tag Explorer Image
26 | - script: docker tag hyperledger/explorer-db hyperledger/explorer-db:$(git describe --abbrev=0 --tags | cut -d 'v' -f 2)
27 | displayName: Tag Explorer DB Image
28 | - script: docker push hyperledger/explorer
29 | displayName: Push Explorer Latest Image
30 | - script: docker push hyperledger/explorer-db
31 | displayName: Push Explorer DB Latest Image
32 | - script: docker push hyperledger/explorer:$(git describe --abbrev=0 --tags | cut -d 'v' -f 2)
33 | displayName: Push Explorer Versioned Image
34 | - script: docker push hyperledger/explorer-db:$(git describe --abbrev=0 --tags | cut -d 'v' -f 2)
35 | displayName: Push Explorer DB Versioned Image
36 |
--------------------------------------------------------------------------------
/app/platform/fabric/e2e-test/specs/genchannelartifacts.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
3 | CHPROFILE=testorgschannel
4 | function genChTx()
5 | {
6 | ch=$1
7 | pushd ${SCRIPTPATH}/configFiles
8 | mkdir -p ../channel-artifacts/$ch
9 | configtxgen -configPath . -profile ${CHPROFILE} -outputCreateChannelTx ../channel-artifacts/${ch}/${ch}.tx -channelID ${ch}
10 | popd
11 | }
12 |
13 | function genAnchorTx()
14 | {
15 | ch=$1
16 | org=$2
17 | pushd ${SCRIPTPATH}/configFiles
18 | mkdir -p ../channel-artifacts/$ch
19 | configtxgen -configPath . -profile ${CHPROFILE} -outputAnchorPeersUpdate ../channel-artifacts/${ch}/${ch}org${org}anchor.tx -channelID ${ch} -asOrg org${org}
20 | popd
21 | }
22 |
23 | genChTx commonchannel
24 | genChTx org1channel
25 | genChTx channel2422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422
26 | genChTx org2channel
27 |
28 | genAnchorTx commonchannel 1
29 | genAnchorTx commonchannel 2
30 | genAnchorTx org1channel 1
31 | genAnchorTx channel2422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422422 1
32 | genAnchorTx org2channel 2
33 |
--------------------------------------------------------------------------------
/release_notes/v1.1.7.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * None
6 |
7 | ## Bug Fixes and Updates
8 |
9 | * [BE-876](https://jira.hyperledger.org/browse/BE-876) Stop unnecessary discovery request (#255)
10 | * Bugfix: tailing ampersand sign prevents container from restarting (#254)
11 | * [BE-857](https://jira.hyperledger.org/browse/BE-857) Change invoking function of lifecycle scc to allow non-admin client access (#252)
12 | * Bugfix: timeout error crashing explorer (#253)
13 | * Bugfix: disable enableAuthentication auth auto login using wrong network key issue (#250)
14 |
15 | ## Known Vulnerabilities
16 |
17 | ```
18 | jsrsasign <10.2.0
19 | Severity: critical
20 | RSA signature validation vulnerability - https://npmjs.com/advisories/1672
21 | fix available via `npm audit fix --force`
22 | Will install fabric-network@1.4.1, which is a breaking change
23 | node_modules/jsrsasign
24 | fabric-ca-client *
25 | Depends on vulnerable versions of fabric-common
26 | Depends on vulnerable versions of jsrsasign
27 | node_modules/fabric-ca-client
28 | fabric-common >=2.1.1-snapshot.390
29 | Depends on vulnerable versions of jsrsasign
30 | node_modules/fabric-common
31 | fabric-network >=1.4.19-snapshot.1
32 | Depends on vulnerable versions of fabric-common
33 | node_modules/fabric-network
34 |
35 | 4 critical severity vulnerabilities
36 | ```
37 |
--------------------------------------------------------------------------------
/docs/source/architecture/databaselayer.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | Database Layer
6 | ==============
7 |
8 | Hyperledger Explorer uses `PostgreSQL `__ database. The information about blocks,
9 | transactions, channels etc will be stored in this database. This is a mature database
10 | for real-time web applications as the updates will be retrieved from database instead of
11 | the application polling data from the Hyperledger Fabric network.
12 |
13 |
14 | The following diagram shows a high level view of the Hyperledger Explorer data model.
15 |
16 | .. raw:: html
17 | :file: ./databaselayer.html
18 |
19 |
20 | .. note::
21 |
22 | Please note, the connecting lines are just for info purposes to illustrate the relation, there are no constraints defined in the current database.
23 |
24 | Physical schema
25 | ~~~~~~~~~~~~~~~~~~
26 |
27 | The script `explorerpg.sql `__ describes
28 | Hyperledger Explorer database. Creation of the database is a mandatory step and it is done by running the script `createdb.sh `__,
29 | detailed steps and instructions are provided in the `README.md `__ file.
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/scripts/release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | function usage {
4 | echo "$0 [current version] [release version]"
5 | echo -e "\te.g. $0 1.1.7 1.1.8"
6 | }
7 |
8 | if [ $# -ne 2 ]; then
9 | usage
10 | exit
11 | fi
12 |
13 | CURVER=$1
14 | NEWVER=$2
15 |
16 | echo $CURVER | grep -q -E "^v"
17 | if [ $? -eq 0 ]; then
18 | usage
19 | exit
20 | fi
21 |
22 | echo $NEWVER | grep -q -E "^v"
23 | if [ $? -eq 0 ]; then
24 | usage
25 | exit
26 | fi
27 |
28 | ./scripts/changelog.sh v$CURVER v$NEWVER
29 | sed -e "s/^\(.*$CURVER.*\)$/\1\n\1/" README.md | sed -e "0,/$CURVER/s//$NEWVER/g" | sed -e "s/\($NEWVER.md)<\/b> \)([^)]*)/\1($(date +"%b %d, %Y"))/" > README.md
30 | sed -i -e "$(grep -n -E "v[0-9]+\.[0-9]+\.[0-9]+\.md" README.md | tail -n 1 | cut -d ':' -f 1)d" README.md
31 | sed -i -e "0,/^\s*\"version/{s/^\(\s*\"version\": \).*$/\1\"$NEWVER\",/}" package.json client/package.json
32 | cat << EOF > release_notes/v$NEWVER.md
33 |
34 |
35 | ## New Features
36 |
37 | $(git log "v$CURVER..HEAD" --oneline | grep -v Merge | cut -d ' ' -f 2- | sed -e 's/^/* /')
38 |
39 | ## Bug Fixes and Updates
40 |
41 | *
42 |
43 | ## Known Vulnerabilities
44 |
45 | package-lock.json
46 | \`\`\`
47 | $(npm audit | grep -E "Severity: critical" -B2 -A10)
48 | \`\`\`
49 |
50 | client/package-lock.json
51 | \`\`\`
52 | $(cd client; npm audit | grep -E "Severity: critical" -B2 -A10)
53 | \`\`\`
54 | EOF
--------------------------------------------------------------------------------
/app/passport/local-login.ts:
--------------------------------------------------------------------------------
1 | // @ts-check
2 |
3 | /*
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 | import { promisify } from 'util';
7 | import jwt from 'jsonwebtoken';
8 | import { Strategy } from 'passport-local';
9 | import { User } from '../platform/fabric/models/User';
10 | import config from '../explorerconfig.json';
11 |
12 | const jwtSignAsync = promisify<
13 | Record,
14 | jwt.Secret,
15 | jwt.SignOptions
16 | >(jwt.sign);
17 |
18 | export const localLoginStrategy = function(platform) {
19 | const proxy = platform.getProxy();
20 | return new Strategy(
21 | {
22 | usernameField: 'user',
23 | passwordField: 'password',
24 | session: false,
25 | passReqToCallback: true
26 | },
27 | async (req, user, password, done) => {
28 | const userData = {
29 | user: user.trim(),
30 | password: password.trim()
31 | };
32 |
33 | const reqUser = await new User(req.body).asJson();
34 | const authResult = await proxy.authenticate(reqUser);
35 | if (!authResult) {
36 | return done(null, false, { message: 'Incorrect credentials' });
37 | }
38 |
39 | const payload = {
40 | user: reqUser.user,
41 | network: reqUser.network
42 | };
43 |
44 | const token: any = await jwtSignAsync(payload, config.jwt.secret, {
45 | expiresIn: config.jwt.expiresIn
46 | });
47 | const data = {
48 | message: 'logged in',
49 | name: userData.user
50 | };
51 | return done(null, token, data);
52 | }
53 | );
54 | };
55 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.yaml:
--------------------------------------------------------------------------------
1 | name: 🐞 Bug
2 | description: File a bug/issue
3 | labels: [Bug, Needs Triage]
4 | body:
5 | - type: textarea
6 | id: problem
7 | attributes:
8 | label: What happened?
9 | description: |
10 | Please provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner.
11 | If this matter is security related, please disclose it privately via https://discord.gg/hyperledger
12 | validations:
13 | required: true
14 |
15 | - type: textarea
16 | id: expected
17 | attributes:
18 | label: What did you expect to happen?
19 | validations:
20 | required: true
21 |
22 | - type: textarea
23 | id: repro
24 | attributes:
25 | label: How can we reproduce it (as minimally and precisely as possible)?
26 | validations:
27 | required: true
28 |
29 | - type: textarea
30 | id: additional
31 | attributes:
32 | label: Anything else we need to know?
33 |
34 | - type: textarea
35 | id: osVersion
36 | attributes:
37 | label: OS version
38 | value: |
39 |
40 |
41 | ```console
42 | # On Linux:
43 | $ cat /etc/os-release
44 | # paste output here
45 | $ uname -a
46 | # paste output here
47 |
48 | # On Windows:
49 | C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
50 | # paste output here
51 | ```
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/sync/listener/ExplorerListener.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 | import { explorerConst } from '../../common/ExplorerConst';
5 | import { ForkListenerHandler } from './ForkListenerHandler';
6 |
7 | /**
8 | *
9 | *
10 | * @class ExplorerListener
11 | */
12 | export class ExplorerListener {
13 | public platform: any;
14 | public syncType: any;
15 | public syncListenerHandler: any;
16 |
17 | /**
18 | * Creates an instance of ExplorerListener.
19 | * @param {*} platform
20 | * @param {*} syncconfig
21 | * @memberof ExplorerListener
22 | */
23 | constructor(platform, syncconfig) {
24 | this.platform = platform;
25 | this.syncType = syncconfig.type;
26 | this.syncListenerHandler = null;
27 | }
28 |
29 | /**
30 | *
31 | *
32 | * @param {*} args
33 | * @memberof ExplorerListener
34 | */
35 | async initialize(args) {
36 | if (this.syncType && this.syncType === explorerConst.SYNC_TYPE_LOCAL) {
37 | this.syncListenerHandler = new ForkListenerHandler(this.platform);
38 | }
39 | if (this.syncListenerHandler) {
40 | this.syncListenerHandler.initialize(args);
41 | }
42 | }
43 |
44 | /**
45 | *
46 | *
47 | * @param {*} message
48 | * @memberof ExplorerListener
49 | */
50 | send(message) {
51 | if (this.syncListenerHandler) {
52 | this.syncListenerHandler.send({
53 | message
54 | });
55 | }
56 | }
57 |
58 | /**
59 | *
60 | */
61 | close() {
62 | if (this.syncListenerHandler) {
63 | this.syncListenerHandler.close();
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/release_notes/v1.1.6.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 | * [BE-871](https://jira.hyperledger.org/browse/BE-871) Introduce dropdown to put together icons (#247)
5 | * [BE-870](https://jira.hyperledger.org/browse/BE-870) display direct trans link (#237)
6 | * Add typescript compilation on main.sh install (#234)
7 | * [BE-865](https://jira.hyperledger.org/browse/BE-865) repolinter codeofconduct (#231)
8 |
9 | ## Bug Fixes and Updates
10 |
11 | * [BE-855](https://jira.hyperledger.org/browse/BE-855) Stop unnecessary sync process triggered by FabricEvent (#240)
12 | * [BE-855](https://jira.hyperledger.org/browse/BE-855) Add try catch block to handle block in-process exception (#239)
13 |
14 | ## Known Vulnerabilities
15 |
16 | ```
17 | jsrsasign <10.2.0
18 | Severity: critical
19 | RSA signature validation vulnerability - https://npmjs.com/advisories/1672
20 | fix available via `npm audit fix --force`
21 | Will install fabric-network@1.4.1, which is a breaking change
22 | node_modules/jsrsasign
23 | fabric-ca-client *
24 | Depends on vulnerable versions of fabric-common
25 | Depends on vulnerable versions of jsrsasign
26 | node_modules/fabric-ca-client
27 | fabric-common >=2.1.1-snapshot.390
28 | Depends on vulnerable versions of jsrsasign
29 | node_modules/fabric-common
30 | fabric-network >=1.4.19-snapshot.1
31 | Depends on vulnerable versions of fabric-common
32 | node_modules/fabric-network
33 |
34 | 4 critical severity vulnerabilities
35 | ```
36 |
--------------------------------------------------------------------------------
/test/api/connection-profile/org1-network-disable-auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "org1-network",
3 | "version": "1.0.0",
4 | "license": "Apache-2.0",
5 | "client": {
6 | "tlsEnable": true,
7 | "adminCredential": {
8 | "id": "exploreradmin3"
9 | },
10 | "enableAuthentication": false,
11 | "organization": "org1",
12 | "connection": {
13 | "timeout": {
14 | "peer": {
15 | "endorser": "300"
16 | },
17 | "orderer": "300"
18 | }
19 | }
20 | },
21 | "channels": {
22 | "org1channel": {
23 | "peers": {
24 | "peer0.org1.example.com": {}
25 | },
26 | "connection": {
27 | "timeout": {
28 | "peer": {
29 | "endorser": "6000",
30 | "eventHub": "6000",
31 | "eventReg": "6000"
32 | }
33 | }
34 | }
35 | }
36 | },
37 | "organizations": {
38 | "org1": {
39 | "mspid": "Org1MSP",
40 | "adminPrivateKey": {
41 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/priv_sk"
42 | },
43 | "peers": ["peer0.org1.example.com"],
44 | "signedCert": {
45 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/cert.pem"
46 | }
47 | }
48 | },
49 | "peers": {
50 | "peer0.org1.example.com": {
51 | "tlsCACerts": {
52 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
53 | },
54 | "url": "grpcs://peer0.org1.example.com:7051",
55 | "grpcOptions": {
56 | "ssl-target-name-override": "peer0.org1.example.com"
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/docs/source/architecture/hl_ui_high_level.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 |
6 | Presentation Layer / Front End
7 | ========================================
8 |
9 | When choosing a framework, or a library in most of the cases we look at the performance, maturity, and support this is where ReactJs
10 | was a benefit to us and used in our HLExplorer front end.
11 |
12 | Why ReactJs?
13 | ~~~~~~~~~~~~~
14 |
15 | - Plainness
16 | - Component-based approach
17 | - Use of well-defined lifecycle
18 | - JavaScript makes React very simple to learn, build professional web.
19 | - Use of a special syntax called JSX that allows to mix HTML with JavaScript.
20 | - Data Binding
21 | - One-way data binding, control of the flow of data to components through the dispatcher, a one control point.
22 | - Performance
23 | - React uses several clever techniques to minimize the number of costly DOM operations required to update the UI.
24 | - Testing
25 | - Easy to test, rich set of libraries, like Jest, and React Testing Library
26 | - Straightforward to learn
27 | - Easily understand React knowing JavaScript, and the good part: for react you just need basic knowledge of HTML and CSS.
28 |
29 | The high-level architecture of presentation layer
30 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31 | .. raw:: html
32 | :file: ./hl_ui_high_level.html
33 |
34 | .. toctree::
35 | :maxdepth: 1
36 |
37 |
38 |
39 | .. Licensed under Creative Commons Attribution 4.0 International License
40 | https://creativecommons.org/licenses/by/4.0/
41 |
--------------------------------------------------------------------------------
/client/e2e-test/E2E-TEST-README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | # How to run e2e test
5 |
6 | ## Pull fabric images and tools
7 |
8 | ```
9 | $ cd /some/where/blockchain-explorer
10 | $ npm run e2e-test-setup-tool:ci
11 | ```
12 |
13 | ## Build Explorer / Explorer-DB image
14 |
15 | ```
16 | $ cd /some/where/blockchain-explorer
17 | $ npm run e2e-test-setup-img
18 | ```
19 |
20 | ## Setup environment
21 |
22 | Bring up the fabric network and start Explorer service on it
23 |
24 | ```
25 | $ cd /some/where/blockchain-explorer
26 | $ npm run e2e-gui-test-setup
27 | ```
28 |
29 | ## Run test scenarios
30 |
31 | ```
32 | # cd /some/where/blockchain-explorer
33 | $ npm run e2e-gui-test-setup-env
34 | $ npm run e2e-gui-test-run
35 | ```
36 |
37 | # Tips
38 |
39 | # Project Structure
40 |
41 | Scenario files are intended to locate in `/client/test/specs` folder.
42 | Overall project structure is as follows:
43 |
44 | ```
45 | client/test/
46 |
47 | +-- docker-compose.yaml // Definition for Selenium Hub/Browser container service
48 |
49 | +-- e2e-setup.sh // Bring up fabric network and explorer
50 |
51 | +-- wdio.conf.js // webdriverIO configuration
52 |
53 | +-- specs/ // Test scenarios
54 |
55 | +-- dashboard.js // dashboard rendering scenarios
56 |
57 | +-- ...
58 | ```
59 |
60 | Mainly we'll update `client/test/specs/*.js` to cover more scenarios.
61 |
62 | # Link
63 |
64 | * https://webdriver.io/docs/api.html
65 | * https://github.com/SeleniumHQ/docker-selenium
66 |
--------------------------------------------------------------------------------
/ci/azure-pipelines.yml:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: Apache-2.0
2 |
3 | name: $(SourceBranchName)-$(Date:yyyyMMdd)$(Rev:.rrr)
4 | trigger:
5 | - main
6 | pr:
7 | - main
8 |
9 | variables:
10 | GOPATH: $(Agent.BuildDirectory)/go
11 | PATH: $(Agent.BuildDirectory)/go/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin
12 | GO_VER: 1.16.4
13 | NODE_VER: 12.13
14 |
15 | jobs:
16 | - job: TestsWithCoverage
17 | pool:
18 | vmImage: ubuntu-20.04
19 | steps:
20 |
21 | - template: install_deps.yml
22 | - checkout: self
23 | - script: |
24 | npm config set prefix ~/npm
25 | npm install
26 | npm run test
27 | cd ./client && npm install
28 | echo "--------> npm tests with code coverage"
29 | npm run test:ci -- -u --coverage && npm run build
30 | displayName: Run Tests With Coverage Report
31 | - script: |
32 | cd client
33 | wget https://raw.github.com/eriwen/lcov-to-cobertura-xml/master/lcov_cobertura/lcov_cobertura.py
34 | python lcov_cobertura.py ./coverage/lcov.info
35 | displayName: Create Cobertura Report
36 | - task: PublishCodeCoverageResults@1
37 | inputs:
38 | codeCoverageTool: 'Cobertura'
39 | summaryFileLocation: $(System.DefaultWorkingDirectory)/client/coverage.xml
40 | pathToSources: $(System.DefaultWorkingDirectory)/client
41 |
42 | - job: SanityChecks
43 | pool:
44 | vmImage: ubuntu-20.04
45 | steps:
46 | - template: install_deps.yml
47 | - checkout: self
48 | - script: |
49 | npm install
50 | npm run e2e-api-test
51 | displayName: Run Sanity Checks for v1.4
52 |
--------------------------------------------------------------------------------
/app/platform/fabric/artifacts/operations/balance-transfer/prometheus.yml:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 | # my global config
7 | global:
8 | scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
9 | evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
10 | # scrape_timeout is set to the global default (10s).
11 |
12 | # Alertmanager configuration
13 | alerting:
14 | alertmanagers:
15 | - static_configs:
16 | - targets:
17 | # - alertmanager:9093
18 |
19 | # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
20 | rule_files:
21 | # - "first_rules.yml"
22 | # - "second_rules.yml"
23 |
24 | # A scrape configuration containing exactly one endpoint to scrape:
25 | # Balance transfer sample
26 | scrape_configs:
27 | # The job name is added as a label `job=` to any timeseries scraped from this config.
28 | - job_name: 'balance-transfer'
29 |
30 | # metrics_path defaults to '/metrics'
31 | # scheme defaults to 'http'.
32 |
33 | static_configs:
34 | - targets: ['localhost:8443','localhost:9443','localhost:9444','localhost:9445','localhost:9446']
35 | - targets: ['orderer.example.com:9443', 'peer0.org1.example.com:9443', 'peer1.org1.example.com:9443', 'peer0.org2.example.com:9443', 'peer1.org2.example.com:9443']
36 | #- targets: [‘peer0.org1.example.com:9443’, ‘peer1.org1.example.com:9444’, ‘peer0.org2.example.com:9445’, ‘peer1.org2.example.com:9446’, ‘orderer.example.com:8443’]
37 |
--------------------------------------------------------------------------------
/client/src/components/Charts/OrgPieChart.spec.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import { OrgPieChart } from './OrgPieChart';
6 |
7 | const setup = () => {
8 | const props = {
9 | classes: {
10 | chart: 'chart',
11 | container: 'container',
12 | },
13 | transactionByOrg: [
14 | {
15 | count: '3',
16 | creator_msp_id: 'OrdererMSP',
17 | },
18 | {
19 | count: '1',
20 | creator_msp_id: 'Org2MSP',
21 | },
22 | {
23 | count: '100',
24 | creator_msp_id: 'Org1MSP',
25 | },
26 | ],
27 | };
28 | const wrapper = shallow();
29 |
30 | return {
31 | props,
32 | wrapper,
33 | };
34 | };
35 |
36 | describe('OrgPieChart', () => {
37 | test('OrgPieChart component should render', () => {
38 | const { wrapper } = setup();
39 | expect(wrapper.exists()).toBe(true);
40 | });
41 |
42 | test('orgDataSetup gets called in componentWillReceiveProps when a new prop is set', () => {
43 | const { wrapper } = setup();
44 | const instance = wrapper.instance();
45 | const spy = jest.spyOn(instance, 'orgDataSetup');
46 | const transactionByOrg = [
47 | {
48 | count: '3',
49 | creator_msp_id: 'OrdererMSP',
50 | },
51 | {
52 | count: '1',
53 | creator_msp_id: 'Org2MSP',
54 | },
55 | {
56 | count: '110',
57 | creator_msp_id: 'Org1MSP',
58 | },
59 | ];
60 |
61 | wrapper.setProps({ transactionByOrg });
62 | expect(spy).toHaveBeenCalledTimes(1);
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/client/e2e-test/specs/network/network.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | /* eslint-disable no-unused-expressions */
6 |
7 | const { chromium } = require('playwright');
8 | require('chai').should();
9 | const expect = require('chai').expect;
10 |
11 | const helper = require('../utils/helper');
12 |
13 | describe('Explorer network view', () => {
14 | let page;
15 | let contextCH;
16 | let browserCH;
17 |
18 | before(async () => {
19 | browserCH = await chromium.launch({ headless: helper.isHeadless() });
20 | contextCH = await browserCH.newContext({
21 | viewport: {
22 | width: 1920,
23 | height: 1080
24 | },
25 | ignoreHTTPSErrors: true
26 | });
27 | page = await helper.setupPage(contextCH);
28 | await helper.switchView(page, 'NETWORK');
29 | await takeScreenShot(page, 'test2');
30 | });
31 |
32 | it('should have 3 peers and 2 orderer: BE-695', async () => {
33 | const nodes = await page.$$('text=/^PEER|ORDERER$/');
34 | const peerNameList = nodes.map(async (elm, idx, array) => {
35 | // Pick 2nd column of each row
36 | const firstCell = await elm.$('xpath=preceding-sibling::div');
37 | return firstCell.innerText();
38 | });
39 |
40 | await Promise.all(peerNameList).then(list => {
41 | expect(list).to.include.members([
42 | 'peer0-org1:31000',
43 | 'peer1-org1:31001',
44 | 'peer0-org2:31002',
45 | 'orderer0-ordererorg1:30000',
46 | 'orderer1-ordererorg1:30001'
47 | ]);
48 | });
49 | });
50 |
51 | after(async () => {
52 | await page.close();
53 | await contextCH.close();
54 | await browserCH.close();
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/docs/source/architecture/dbservices.rst:
--------------------------------------------------------------------------------
1 |
2 | .. SPDX-License-Identifier: Apache-2.0
3 |
4 |
5 | Database Services
6 | ===========================================
7 |
8 | This module is a set of API's that handle the interactions with the database. The layer is isolated from the HTTP request and response.
9 | Hyperledger Explorer at this time persisting data from the Hyperledger Fabric only, no delete operations involved.
10 |
11 | The following API's are part of the database services:
12 | 1. `PersistenceFactory `__, responsible for platform based blockchain.
13 | 2. `Persist `__, has a set of getters, and setters to get services such as CRUDService, MetricServices, and PgService.
14 | 3. `PgService `__ is responsible to connect, and perform any data manipulation.
15 | 4. `CRUDService `__, has a set of platform specific, and interacts with models that are storing data related to Hyperledger Fabric network blockchain.
16 | 5. `MetricService `__, is in charge of computing statistics of the blockchain activity, per hours, minutes, and organizations.
17 |
18 | Below diagram shows above mentioned API's.
19 |
20 | .. raw:: html
21 | :file: ./dbservices.html
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/api/connection-profile/test-network-ca.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-network",
3 | "version": "1.0.0",
4 | "client": {
5 | "tlsEnable": true,
6 | "adminCredential": {
7 | "id": "exploreradmin",
8 | "password": "exploreradminpw",
9 | "affiliation": "org1.department1"
10 | },
11 | "caCredential": {
12 | "id": "admin",
13 | "password": "adminpw"
14 | },
15 | "enableAuthentication": true,
16 | "organization": "Org1MSP",
17 | "connection": {
18 | "timeout": {
19 | "peer": {
20 | "endorser": "300"
21 | },
22 | "orderer": "300"
23 | }
24 | }
25 | },
26 | "channels": {
27 | "mychannel": {
28 | "peers": {
29 | "peer0.org1.example.com": {}
30 | },
31 | "connection": {
32 | "timeout": {
33 | "peer": {
34 | "endorser": "6000",
35 | "eventHub": "6000",
36 | "eventReg": "6000"
37 | }
38 | }
39 | }
40 | }
41 | },
42 | "organizations": {
43 | "Org1MSP": {
44 | "mspid": "Org1MSP",
45 | "peers": ["peer0.org1.example.com"],
46 | "certificateAuthorities": ["ca0"]
47 | }
48 | },
49 | "peers": {
50 | "peer0.org1.example.com": {
51 | "tlsCACerts": {
52 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
53 | },
54 | "url": "grpcs://peer0.org1.example.com:7051"
55 | }
56 | },
57 | "certificateAuthorities": {
58 | "ca0": {
59 | "url": "https://ca_org1:7054",
60 | "httpOptions": {
61 | "verify": false
62 | },
63 | "tlsCACerts": {
64 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem"
65 | },
66 | "caName": "ca0-org1"
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/examples/net1/connection-profile/test-network-ca.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-network",
3 | "version": "1.0.0",
4 | "client": {
5 | "tlsEnable": true,
6 | "adminCredential": {
7 | "id": "exploreradmin",
8 | "password": "exploreradminpw",
9 | "affiliation": "org1.department1"
10 | },
11 | "caCredential": {
12 | "id": "admin",
13 | "password": "adminpw"
14 | },
15 | "enableAuthentication": true,
16 | "organization": "Org1MSP",
17 | "connection": {
18 | "timeout": {
19 | "peer": {
20 | "endorser": "300"
21 | },
22 | "orderer": "300"
23 | }
24 | }
25 | },
26 | "channels": {
27 | "mychannel": {
28 | "peers": {
29 | "peer0.org1.example.com": {}
30 | },
31 | "connection": {
32 | "timeout": {
33 | "peer": {
34 | "endorser": "6000",
35 | "eventHub": "6000",
36 | "eventReg": "6000"
37 | }
38 | }
39 | }
40 | }
41 | },
42 | "organizations": {
43 | "Org1MSP": {
44 | "mspid": "Org1MSP",
45 | "peers": ["peer0.org1.example.com"],
46 | "certificateAuthorities": ["ca0"]
47 | }
48 | },
49 | "peers": {
50 | "peer0.org1.example.com": {
51 | "tlsCACerts": {
52 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
53 | },
54 | "url": "grpcs://peer0.org1.example.com:7051"
55 | }
56 | },
57 | "certificateAuthorities": {
58 | "ca0": {
59 | "url": "https://ca_org1:7054",
60 | "httpOptions": {
61 | "verify": false
62 | },
63 | "tlsCACerts": {
64 | "path": "/tmp/crypto/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem"
65 | },
66 | "caName": "ca0-org1"
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/client/src/services/request.js:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | import agent from 'superagent';
6 |
7 | import Auth from '../state/Auth';
8 |
9 | export const post = (uri, payload) =>
10 | new Promise((resolve, reject) => {
11 | agent
12 | .post(uri)
13 | .send(payload)
14 | .set('Accept', 'application/json')
15 | .set('Authorization', `bearer ${Auth.getToken()}`)
16 | .end(withPromiseCallback(resolve, reject));
17 | });
18 | export const get = uri =>
19 | new Promise((resolve, reject) => {
20 | agent
21 | .get(uri)
22 | .set('Accept', 'application/json')
23 | .set('Authorization', `bearer ${Auth.getToken()}`)
24 | .set('Cache-Control', 'no-cache')
25 | .end(withPromiseCallback(resolve, reject));
26 | });
27 | export const put = (uri, payload) =>
28 | new Promise((resolve, reject) => {
29 | agent
30 | .put(uri)
31 | .send(payload)
32 | .set('Accept', 'application/json')
33 | .set('Authorization', `bearer ${Auth.getToken()}`)
34 | .end(withPromiseCallback(resolve, reject));
35 | });
36 | export const deleteRequest = (uri, payload) =>
37 | new Promise((resolve, reject) => {
38 | agent
39 | .delete(uri)
40 | .send(payload)
41 | .set('Accept', 'application/json')
42 | .set('Authorization', `bearer ${Auth.getToken()}`)
43 | .end(withPromiseCallback(resolve, reject));
44 | });
45 | export const withPromiseCallback = (resolve, reject) => (error, response) => {
46 | if (error) {
47 | console.error(error);
48 | if (response && response.status === 401) {
49 | Auth.deauthenticateUser();
50 | }
51 | reject({ error });
52 | } else {
53 | resolve(response.body);
54 | }
55 | };
56 |
--------------------------------------------------------------------------------
/app/persistence/fabric/postgreSQL/db/createdb.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # SPDX-License-Identifier: Apache-2.0
4 |
5 | echo "Copying ENV variables into temp file..."
6 | node processenv.js
7 | if [ $( jq .DATABASE_USERNAME /tmp/process.env.json) == null ]; then
8 | export USER=$( jq .postgreSQL.username ../../../../explorerconfig.json )
9 | else
10 | export USER=$( jq .DATABASE_USERNAME /tmp/process.env.json)
11 | fi
12 | if [ $(jq .DATABASE_DATABASE /tmp/process.env.json) == null ]; then
13 | export DATABASE=$(jq .postgreSQL.database ../../../../explorerconfig.json )
14 | else
15 | export DATABASE=$(jq .DATABASE_DATABASE /tmp/process.env.json)
16 | fi
17 | if [ $(jq .DATABASE_PASSWORD /tmp/process.env.json) == null ]; then
18 | export PASSWD=$(jq .postgreSQL.passwd ../../../../explorerconfig.json | sed "y/\"/'/")
19 | else
20 | export PASSWD=$(jq .DATABASE_PASSWORD /tmp/process.env.json | sed "y/\"/'/")
21 | fi
22 | echo "USER=${USER}"
23 | echo "DATABASE=${DATABASE}"
24 | echo "PASSWD=${PASSWD}"
25 | if [ -f /tmp/process.env.json ] ; then
26 | rm /tmp/process.env.json
27 | fi
28 | echo "Executing SQL scripts, OS="$OSTYPE
29 |
30 | #support for OS
31 | case $OSTYPE in
32 | darwin*) psql postgres -v dbname=$DATABASE -v user=$USER -v passwd=$PASSWD -f ./explorerpg.sql ;
33 | psql postgres -v dbname=$DATABASE -v user=$USER -v passwd=$PASSWD -f ./updatepg.sql ;;
34 | linux*)
35 | if [ $(id -un) = 'postgres' ]; then
36 | PSQL="psql"
37 | else
38 | PSQL="sudo -u postgres psql"
39 | fi;
40 | ${PSQL} -v dbname=$DATABASE -v user=$USER -v passwd=$PASSWD -f ./explorerpg.sql ;
41 | ${PSQL} -v dbname=$DATABASE -v user=$USER -v passwd=$PASSWD -f ./updatepg.sql ;;
42 | esac
43 |
44 |
45 |
--------------------------------------------------------------------------------
/main.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # SPDX-License-Identifier: Apache-2.0
4 |
5 | set -e
6 |
7 | # Print usage
8 | function print_help() {
9 | echo "Usage: "
10 | echo " main.sh [-v]"
11 | echo " - one of 'install', 'test' or 'clean'"
12 | echo " - 'install' - install all dependencies of the project"
13 | echo " - 'test' - run unit tests of the application and client code"
14 | echo " - 'clean' - clean the project directory of installed dependencies"
15 | echo " -v - enable verbose output"
16 | echo " -h - print this message"
17 | }
18 |
19 | function do_install() {
20 | VERBOSE=${VERBOSE:+-ddd}
21 | (npm install $VERBOSE && npm run build)
22 | (cd client && npm install $VERBOSE && npm run build)
23 | }
24 |
25 | function do_test() {
26 | (npm run test)
27 | (cd client && npm run test:ci -- -u --coverage)
28 | }
29 |
30 | function do_clean() {
31 | rm -rf node_modules
32 | rm -rf client/node_modules client/build client/coverage
33 | }
34 |
35 | # Get subcommand
36 | SUBCOMMAND=$1
37 | shift
38 |
39 | case $SUBCOMMAND in
40 | install | test | clean)
41 | ;;
42 | *)
43 | print_help
44 | exit 1
45 | ;;
46 | esac
47 |
48 | OPTIONS="hv"
49 | VERBOSE=
50 | while getopts "$OPTIONS" opt; do
51 | case "$opt" in
52 | v) VERBOSE=true ;;
53 | h)
54 | print_help
55 | exit 1
56 | ;;
57 | *)
58 | echo "Unrecognized option: $opt"
59 | exit 2
60 | ;;
61 | esac
62 | done
63 |
64 | case $SUBCOMMAND in
65 | install)
66 | do_install
67 | ;;
68 | test)
69 | do_test
70 | ;;
71 | clean)
72 | do_clean
73 | ;;
74 | *)
75 | echo "Logic Error"
76 | exit 3
77 | ;;
78 | esac
79 |
--------------------------------------------------------------------------------
/client/e2e-test/configs/connection-profile/org1-network-for-guitest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "org1-network",
3 | "version": "1.0.0",
4 | "license": "Apache-2.0",
5 | "client": {
6 | "tlsEnable": true,
7 | "adminCredential": {
8 | "id": "admin",
9 | "password": "adminpw",
10 | "affiliation": "org1.department1"
11 | },
12 | "enableAuthentication": true,
13 | "organization": "org1",
14 | "connection": {
15 | "timeout": {
16 | "peer": {
17 | "endorser": "300"
18 | },
19 | "orderer": "300"
20 | }
21 | }
22 | },
23 | "channels": {
24 | "testorgschannel0": {
25 | "peers": {
26 | "peer0-org1": {}
27 | },
28 | "connection": {
29 | "timeout": {
30 | "peer": {
31 | "endorser": "6000",
32 | "eventHub": "6000",
33 | "eventReg": "6000"
34 | }
35 | }
36 | }
37 | }
38 | },
39 | "organizations": {
40 | "org1": {
41 | "mspid": "Org1ExampleCom",
42 | "adminPrivateKey": {
43 | "path": "GOPATH/src/github.com/hyperledger/fabric-test/tools/operator/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/keystore/priv_sk"
44 | },
45 | "peers": ["peer0-org1"],
46 | "signedCert": {
47 | "path": "GOPATH/src/github.com/hyperledger/fabric-test/tools/operator/crypto-config/peerOrganizations/org1/users/Admin@org1/msp/signcerts/Admin@org1-cert.pem"
48 | }
49 | }
50 | },
51 | "peers": {
52 | "peer0-org1": {
53 | "tlsCACerts": {
54 | "path": "GOPATH/src/github.com/hyperledger/fabric-test/tools/operator/crypto-config/peerOrganizations/org1/peers/peer0-org1.org1/tls/ca.crt"
55 | },
56 | "url": "grpcs://localhost:31000",
57 | "grpcOptions": {
58 | "ssl-target-name-override": "peer0-org1"
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/platform/fabric/connection-profile/test-network.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-network",
3 | "version": "1.0.0",
4 | "license": "Apache-2.0",
5 | "client": {
6 | "tlsEnable": true,
7 | "adminCredential": {
8 | "id": "exploreradmin",
9 | "password": "exploreradminpw"
10 | },
11 | "enableAuthentication": true,
12 | "organization": "Org1MSP",
13 | "connection": {
14 | "timeout": {
15 | "peer": {
16 | "endorser": "300"
17 | },
18 | "orderer": "300"
19 | }
20 | }
21 | },
22 | "channels": {
23 | "mychannel": {
24 | "peers": {
25 | "peer0.org1.example.com": {}
26 | },
27 | "connection": {
28 | "timeout": {
29 | "peer": {
30 | "endorser": "6000",
31 | "eventHub": "6000",
32 | "eventReg": "6000"
33 | }
34 | }
35 | }
36 | }
37 | },
38 | "organizations": {
39 | "Org1MSP": {
40 | "mspid": "Org1MSP",
41 | "adminPrivateKey": {
42 | "path": "/fabric-path/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/keystore/priv_sk"
43 | },
44 | "peers": ["peer0.org1.example.com"],
45 | "signedCert": {
46 | "path": "/fabric-path/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/User1@org1.example.com/msp/signcerts/User1@org1.example.com-cert.pem"
47 | }
48 | }
49 | },
50 | "peers": {
51 | "peer0.org1.example.com": {
52 | "tlsCACerts": {
53 | "path": "/fabric-path/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
54 | },
55 | "url": "grpcs://localhost:7051",
56 | "grpcOptions": {
57 | "ssl-target-name-override": "peer0.org1.example.com"
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/release_notes/v1.1.0.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## New Features
4 |
5 | * Support for Hyperledger Fabric v2.1.1
6 | * Support for Hyperledger Fabric v1.4.6 as well
7 | *
8 |
9 | ## Bug Fixes and Updates
10 |
11 | * Fix segfault in Explorer container
12 | * Making Hyperledger Explorer compatible to Amazon Managed Blockchain Network
13 |
14 | ## Known Vulnerabilities
15 |
16 | ### client/package.json
17 |
18 | ```
19 | ┌───────────────┬──────────────────────────────────────────────────────────────┐
20 | │ Low │ Prototype Pollution │
21 | ├───────────────┼──────────────────────────────────────────────────────────────┤
22 | │ Package │ yargs-parser │
23 | ├───────────────┼──────────────────────────────────────────────────────────────┤
24 | │ Patched in │ >=13.1.2 <14.0.0 || >=15.0.1 <16.0.0 || >=18.1.2 │
25 | ├───────────────┼──────────────────────────────────────────────────────────────┤
26 | │ Dependency of │ react-scripts │
27 | ├───────────────┼──────────────────────────────────────────────────────────────┤
28 | │ Path │ react-scripts > webpack-dev-server > yargs > yargs-parser │
29 | ├───────────────┼──────────────────────────────────────────────────────────────┤
30 | │ More info │ https://npmjs.com/advisories/1500 │
31 | └───────────────┴──────────────────────────────────────────────────────────────┘
32 | found 1 low severity vulnerability in 2141 scanned packages
33 | 1 vulnerability requires manual review. See the full report for details.
34 | ```
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------