{"id":20217383,"url":"https://github.com/settlemint/hyperledger-explorer","last_synced_at":"2025-03-03T11:26:20.755Z","repository":{"id":194183329,"uuid":"686028860","full_name":"settlemint/hyperledger-explorer","owner":"settlemint","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-27T00:13:06.000Z","size":173111,"stargazers_count":0,"open_issues_count":75,"forks_count":0,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-01T15:47:20.162Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/settlemint.png","metadata":{"files":{"readme":"README-CONFIG.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-01T15:08:39.000Z","updated_at":"2025-01-29T06:06:12.000Z","dependencies_parsed_at":"2024-11-14T12:32:22.343Z","dependency_job_id":null,"html_url":"https://github.com/settlemint/hyperledger-explorer","commit_stats":null,"previous_names":["settlemint/hyperledger-explorer"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/settlemint%2Fhyperledger-explorer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/settlemint%2Fhyperledger-explorer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/settlemint%2Fhyperledger-explorer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/settlemint%2Fhyperledger-explorer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/settlemint","download_url":"https://codeload.github.com/settlemint/hyperledger-explorer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241654605,"owners_count":19997894,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T06:33:51.557Z","updated_at":"2025-03-03T11:26:20.730Z","avatar_url":"https://github.com/settlemint.png","language":"JavaScript","readme":"\u003c!-- (SPDX-License-Identifier: CC-BY-4.0) --\u003e\n\n## Configuration\n\nThis document will describe about the detail of each configuration:\n\n## Database\n\n* Modify `app/explorerconfig.json` to update PostgreSQL database settings.\n  \n    ```json\n    \"postgreSQL\": {\n        \"host\": \"127.0.0.1\",\n        \"port\": \"5432\",\n        \"database\": \"fabricexplorer\",\n        \"username\": \"hppoc\",\n        \"passwd\": \"password\"\n    }\n    ```\n\n* Another alternative to configure database settings is to use environment variables, example of settings:\n\n    ```shell\n    export DATABASE_HOST=127.0.0.1\n    export DATABASE_PORT=5432\n    export DATABASE_DATABASE=fabricexplorer\n    export DATABASE_USERNAME=hppoc\n    export DATABASE_PASSWD=pass12345\n    ```\n\n## Authorization\n\n* Modify `app/explorerconfig.json` to update Authorization (JWT) settings.\n\n    ```json\n    \"jwt\": {\n        \"secret\" : \"a secret phrase!!\",\n        \"expiresIn\": \"2 days\"\n    }\n    ```\n  * `secret`: secret string to sign the payload.\n  * `expiresIn`: expressed in seconds or a string describing a time span [zeit/ms](https://github.com/zeit/ms).\n    Eg: `60`, `\"2 days\"`, `\"10h\"`, `\"7d\"`. A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), otherwise milliseconds unit is used by default (`\"120\"` is equal to `\"120ms\"`).\n\n* Modify the connection profile (e.g. `app/platform/fabric/connection-profile/test-network.json`) to configure authorization of login user.\n\n    ```json\n    \"client\": {\n      \"adminCredential\": {\n        \"id\": \"exploreradmin\",\n        \"password\": \"exploreradminpw\"\n      },\n      \"enableAuthentication\": true,\n    ```\n  * `adminCredential.id` is the the admin user to login Explorer. Currently Explorer only supports single user mode (can't add more users. We're working on it)\n  * `adminCredential.password` is the password for the admin user to login Explorer.\n  * `enableAuthentication` is a flag to enable authentication using a login page, setting to false will skip authentication.\n    * Even if disable user authentication, you still need to get `adminCredential.id` specified, because it's used to get access to the wallet.\n\n## Disable Explorer login authentication\n\n* If you want to disable login authentication, set `false` to  `enableAuthentication` in the connection profile\n    ```json\n    \"client\": {\n      \"enableAuthentication\": false\n    }\n    ```\n\n## User management\n\n### Register user\n\n* Only admin and users who has admin roles can register a new user.\n* admin user can register a user who has `admin` or `user` roles\n  * `user` roles doesn't include a privilege to manipulate user\n* If multiple profiles are configured, user information of each profile is completely isolated.\n  * e.g. Admin of org1-network can't manipulate user of org2-network.\n* There are 2 ways to register a new user to Explorer. You can do that via GUI or Web API.\n\n  * GUI\n![](docs/source/images/UserRegisterGUI.png)\n\n  * Web API\nFirst you need to login using admin credential to get a JSON Web token.\n    ```shell\n    $ curl -s --location --request POST 'localhost:8080/auth/login' \\\n    --header 'Content-Type: application/json' --data-raw '{\n    \"user\": \"exploreradmin\",\n    \"password\": \"exploreradminpw\",\n    \"network\": \"test-network\"\n    }' | jq .\n\n    {\n      \"success\": true,\n      \"message\": \"You have successfully logged in!\",\n      \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZXhwbG9yZXJhZG1pbiIsIm5ldHdvcmsiOiJmaXJzdC1uZXR3b3JrIiwiaWF0IjoxNTk3MTMyMTY0LCJleHAiOjE1OTcxMzkzNjR9.5Z9nyQi93fsKNV9Y7RgAXaXKds70fivZOVAEefHzlx4\",\n      \"user\": {\n        \"message\": \"logged in\",\n        \"name\": \"exploreradmin\"\n      }\n    }\n    ```\n\n    Then post a request for registering a new user with the retrieved token and mandatorily required parameters.\n\n    ```shell\n    $ curl -s --location --request POST 'localhost:8080/api/register' \\\n    --header 'Content-Type: application/json' \\\n    --header 'Authorization: Bearer eyJheyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZXhwbG9yZXJhZG1pbiIsIm5ldHdvcmsiOiJmaXJzdC1uZXR3b3JrIiwiaWF0IjoxNTk3MTMyMTY0LCJleHAiOjE1OTcxMzkzNjR9.5Z9nyQi93fsKNV9Y7RgAXaXKds70fivZOVAEefHzlx4' \\\n    --data-raw '{\n      \"user\": \"newuser\",\n      \"password\": \"newuser\",\n        \"roles\": \"user\"\n    }' | jq .\n\n    {\n      \"status\": 200\n    }\n    ```\n\n### List registered user\n\n* Anyone can request this Web API after sing in Explorer dashboard.\n* You can list registered user via Web API (GUI for this operation has not been supported yet).\n\n    ```shell\n    $ curl -s --location --request GET 'localhost:8080/api/userlist' \\\n    --header 'conten: application/json' \\\n    --header 'Authorization: Bearer eyJheyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZXhwbG9yZXJhZG1pbiIsIm5ldHdvcmsiOiJmaXJzdC1uZXR3b3JrIiwiaWF0IjoxNTk3MTMyMTY0LCJleHAiOjE1OTcxMzkzNjR9.5Z9nyQi93fsKNV9Y7RgAXaXKds70fivZOVAEefHzlx4' \\\n    | jq .\n\n    {\n      \"status\": 200,\n      \"message\": [\n        {\n          \"username\": \"exploreradmin\",\n          \"email\": null,\n          \"networkName\": \"test-network\",\n          \"firstName\": null,\n          \"lastName\": null,\n          \"roles\": \"admin\"\n        },\n        {\n          \"username\": \"newuser\",\n          \"email\": null,\n          \"networkName\": \"test-network\",\n          \"firstName\": null,\n          \"lastName\": null,\n          \"roles\": \"user\"\n        }\n      ]\n    }\n    ```\n\n### Unregister user\n\n* Root admin user can't be unregistered\n* It's not allowed to unregister user who's sending this request itself\n* You can unregister user via Web API (GUI for this operation has not been supported yet).\n\n```shell\n$ curl -s --location --request POST 'localhost:8080/api/unregister' \\\n--header 'Content-Type: application/json' \\\n--header 'Authorization: Bearer eyJheyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiZXhwbG9yZXJhZG1pbiIsIm5ldHdvcmsiOiJmaXJzdC1uZXR3b3JrIiwiaWF0IjoxNTk3MTMyMTY0LCJleHAiOjE1OTcxMzkzNjR9.5Z9nyQi93fsKNV9Y7RgAXaXKds70fivZOVAEefHzlx4' \\\n--data-raw '{\n\"user\": \"newuser\"\n}' | jq .\n\n{\n  \"status\": 200,\n  \"message\": \"Unregistered successfully!\"\n}\n```\n\n## Enable TLS\n\n* If your fabric network enables TLS, then set `true` to `client.tlsEnable` in the connection profile (e.g. `app/platform/fabric/connection-profile/test-network.json`).\n  And you also need to specify peer URL with `grpcs://`. If your fabrice network disables TLS, use `grpc://` instead.\n\n    ```json\n    \"client\": {\n      \"tlsEnable\": true,\n    ```\n    ```json\n    \"peers\": {\n      \"peer0.org1.example.com\": {\n        \"url\": \"grpcs://localhost:7051\",\n    ```\n\n## Connection profile for Hyperledger Fabric network\n\n* Modify `app/platform/fabric/config.json` to define your fabric network connection profile:\n\n    ```json\n    {\n        \"network-configs\": {\n            \"test-network\": {\n                \"name\": \"Test Network\",\n                \"profile\": \"./connection-profile/test-network.json\"\n            }\n        },\n        \"license\": \"Apache-2.0\"\n    }\n    ```\n  * `test-network` is the name of your connection profile, and can be changed to any name.\n  * `name` is a name you want to give to your fabric network, you can change only value of the key \"name\".\n  * `profile` is the location of your connection profile, you can change only value of the key \"profile\"\n  * Change `fabric-path` to your fabric network disk path in the `test-network.json` file \n  * Provide the full disk path to the adminPrivateKey config option, it ussually ends with \"_sk\"\\\n  e.g.\n    ```json\n    \"adminPrivateKey\": {\n      \"path\": \"/opt/dev/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/aaacd899a6362a5c8cc1e6f86d13bfccc777375365bbda9c710bb7119993d71c_sk\"\n    },\n    ```\n    or\n    Provide the pem string instead.\n    ```json\n    \"adminPrivateKey\": {\n      \"pem\": \"-----BEGIN PRIVATE KEY-----\\nMIGHAgEAMBMG ... utE5HtrGM\\n-----END PRIVATE KEY-----\\n\"\n    },\n    ```\n\n## Using Fabric-CA\n\n* You need to specify the following keys in the connection profile for using Fabric CA to retrieve certificate:\n  * client.caCredential\n    * id\n    * passowrd\n  * client.adminCredential\n    * affiliation\n  * organizations.[org name]\n    * certificateAuthorities\n\n    ```json\n    \"client\": {\n      \"tlsEnable\": true,\n      \"caCredential\": {\n        \"id\": \"admin\",\n        \"password\": \"adminpw\"\n      },\n      \"adminCredential\": {\n        \"id\": \"exploreradmin\",\n        \"password\": \"exploreradminpw\",\n        \"affiliation\": \"org1.department1\"\n      },\n      \"enableAuthentication\": true,\n    ```\n    ```json\n    \"organizations\": {\n      \"org1\": {\n        \"mspid\": \"Org1ExampleCom\",\n        \"peers\": [\"peer0-org1\"],\n        \"certificateAuthorities\": [\"ca0\"]\n      }\n    },\n    ```\n\n  * Refer to the following sample connection files:\n    * `examples/net1/connection-profile/test-network-ca.json` (for using Docker)\n      * To use this profile, modify `docker-compose.yaml` as below:\n        ```diff\n        diff --git a/docker-compose.yaml b/docker-compose.yaml\n        index 9478ca1..ea6ae74 100644\n        --- a/docker-compose.yaml\n        +++ b/docker-compose.yaml\n        @@ -46,7 +46,7 @@ services:\n              - LOG_CONSOLE_STDOUT=true\n              - DISCOVERY_AS_LOCALHOST=false\n            volumes:\n        -      - ./examples/net1/config.json:/opt/explorer/app/platform/fabric/config.json\n        +      - ./examples/net1/config-ca.json:/opt/explorer/app/platform/fabric/config.json\n              - ./examples/net1/connection-profile:/opt/explorer/app/platform/fabric/connection-profile\n              - /fabric-path/fabric-samples/test-network/organizations:/tmp/crypto\n              - walletstore:/opt/explorer/wallet\n        ```\n    * `app/platform/fabric/connection-profile/test-network-ca.json` (for using source tree)\n      * To use this profile, modify `app/platform/fabric/config.json` as below:\n        ```diff\n        diff --git a/app/platform/fabric/config.json b/app/platform/fabric/config.json\n        index f99d37b..9825060 100644\n        --- a/app/platform/fabric/config.json\n        +++ b/app/platform/fabric/config.json\n        @@ -2,7 +2,7 @@\n                \"network-configs\": {\n                        \"test-network\": {\n                                \"name\": \"Test Network\",\n        -                       \"profile\": \"./connection-profile/test-network.json\"\n        +                       \"profile\": \"./connection-profile/test-network-ca.json\"\n                        }\n                },\n                \"license\": \"Apache-2.0\"\n        ```\n\n### Disable using Fabric CA\n\n* You need to specify the following keys:\n  * organizations.[org name]\n    * adminPrivateKey\n    * signedCert\n    ```json\n    \"client\": {\n      \"tlsEnable\": true,\n      \"adminCredential\": {\n        \"id\": \"exploreradmin\",\n        \"password\": \"exploreradminpw\",\n      },\n      \"enableAuthentication\": true,\n    ```\n    ```json\n    \"organizations\": {\n      \"org1\": {\n        \"mspid\": \"Org1ExampleCom\",\n        \"adminPrivateKey\": {\n          \"path\": \"[path to private key]\"\n        },\n        \"peers\": [\"peer0-org1\"],\n        \"signedCert\": {\n          \"path\": \"[path to cert]\"\n        }\n      }\n    },\n    ```\n\n## Using client TLS\n\n* When you set an identity label to `clientTlsIdentity` in the connection profile and store identity, which is correspondent with it, into the wallet (`EXPLORER_ROOTDIR/wallet`), client TLS (mutual TLS) is enabled.\n    ```json\n    \"client\": {\n      \"clientTlsIdentity\": \"clientTlsId\"\n    }\n    ```\n\n\n## Monitoring multiple organizations\n\n* You can also configure multiple profiles in `app/platform/fabric/config.json` for monitoring multiple organizations in a single Explorer instance. It's quite straightforward. You just need to prepare config.json as below and connection profile for each organization (e.g. `org1-network.json` \u0026 `org2-network.json`). Note that you need to initialize your backend database once when applying v1.0.0-rc3 and above first time in your local environment. Because we've changed database schema in backend database since this version.\n\n    ```json\n    {\n      \"network-configs\": {\n        \"org1-network\": {\n          \"name\": \"org1-network\",\n          \"profile\": \"./connection-profile/org1-network.json\"\n        },\n        \"org2-network\": {\n          \"name\": \"org2-network\",\n          \"profile\": \"./connection-profile/org2-network.json\"\n        }\n      },\n      \"license\": \"Apache-2.0\"\n    }\n    ```\n\n## Enable HTTPS access to Hyperledger Explorer\n\n* Configure Hyperledger Explorer for HTTPS based on this link [CONFIG-HTTPS-HLEXPLORER.md](CONFIG-HTTPS-HLEXPLORER.md)\n\n## Sync process mode\n\n* Modify `app/explorerconfig.json` to update sync properties\n* Please restart Explorer if any changes made to explorerconfig.json\n* Ensure same configuration in Explorer explorerconfig.json if sync process is running from different locations\n\n### Host (Standalone)\n\n```json\n\"sync\": {\n  \"type\": \"host\",\n  \"platform\": \"fabric\",\n  \"blocksSyncTime\": \"1\"\n},\n```\n\n### Local (Run with Explorer)\n\n```json\n\"sync\": {\n  \"type\": \"local\",\n  \"platform\": \"fabric\",\n  \"blocksSyncTime\": \"1\"\n},\n```\n\n* `sync`: sync type. `local`(run with Explorer) or `host`(standalone)\n* `platform`: platform name\n* `blocksSyncTime`: sync interval in minute\n\n## Logging\n\n* By using the following environmet variables, you can control log level of each component (app, db and console). You can set these `ALL \u003c TRACE \u003c DEBUG \u003c INFO \u003c WARN \u003c ERROR \u003c FATAL \u003c MARK \u003c OFF` string to each level. Each file is rolled by both date (7days) and size (8MB).\n\n  * LOG_LEVEL_APP\n    * Log level regarding application layer. The logs are written to `logs/app/app.log`.\n    * default `DEBUG`\n  * LOG_LEVEL_DB\n    * Log level regarding backend layer. The logs are written to `logs/db/db.log`.\n    * default `DEBUG`\n  * LOG_LEVEL_CONSOLE\n    * Log level regarding console. The logs are written to `logs/console/console.log`.\n    * default `INFO`\n  * LOG_CONSOLE_STDOUT\n    * You can switch the destination of console log from file to standard output.\n    * default `false`\n\n## Run Hyperledger Explorer Using Docker Compose\n\n* Modify an example of `docker-compose.yaml` to align with your environment\n  * networks \u003e mynetwork.com \u003e external \u003e name\n    ```yaml\n    networks:\n        mynetwork.com:\n            external:\n                name: net_byfn\n    ```\n  * services \u003e explorer.mynetwork.com \u003e volumes\n    * Connection config file path (ex. ./examples/net1/config.json)\n    * Connection profile directory path (ex. ./examples/net1/connection-profile, which is referred from config.json)\n    * Directory path for crypto artifacts of fabric network (ex. ./examples/net1/crypto)\n    ```yaml\n    volumes:\n      - ./examples/net1/config.json:/opt/explorer/app/platform/fabric/config.json\n      - ./examples/net1/connection-profile:/opt/explorer/app/platform/fabric/connection-profile\n      - ./examples/net1/crypto:/tmp/crypto\n    ```\n  * When you connect the explorer to your fabric network through bridge network, you need to set `DISCOVERY_AS_LOCALHOST` to `false` for disabling hostname mapping into `localhost`.\n    ```yaml\n    explorer.mynetwork.com:\n        ...\n        environment:\n        ...\n        - DISCOVERY_AS_LOCALHOST=false\n    ```\n  * In this docker-compose.yaml, two named volumes are allocated for persistent data (for Postgres data and user wallet), if you would like to clear these named volumes, run the following:\n    ```shell\n    docker-compose down -v\n    ```\n\n## Value encoding in Transaction Details\n\n* By default, the value of each read/write set is encoded by UTF-8. If you want to change the type of encoding, you can configure with the following property in the connection profile. Please refer to [Buffer | Node.js v14.7.0 Documentation](https://nodejs.org/docs/latest/api/buffer.html#buffer_buffers_and_character_encodings) for the supported encoding.\n\n    ```json\n    \"client\": {\n      \"rwSetEncoding\": \"hex\"\n    }\n    ```\n\n## Add a subdomain by adding proxy server\n\n* By putting a proxy server (NGINX server), you can change domain that users access. (e.g. change from `http://my.example.com` to `http://my.example.com/explorer`.\n  * First, prepare configuration file `nginx_subdomain.conf` on root directory of explorer project for NGINX server as follow.\n    ```\n    server {\n    \n        location /explorer/ {\n            proxy_pass http://explorer.mynetwork.com:8080/;\n        }\n\n        location / {\n            proxy_pass http://explorer.mynetwork.com:8080/;\n            proxy_http_version 1.1;\n            proxy_set_header Upgrade $http_upgrade;\n            proxy_set_header Connection \"Upgrade\";\n            proxy_set_header Host $host;\n        }\n    }\n    ```\n  * Add a service of proxy server to `docker-compose.yaml`\n    ```diff\n    diff --git a/docker-compose.yaml b/docker-compose.yaml\n    index 9478ca1..a0c9d03 100644\n    --- a/docker-compose.yaml\n    +++ b/docker-compose.yaml\n    @@ -57,3 +57,14 @@ services:\n            condition: service_healthy\n        networks:\n          - mynetwork.com\n    +\n    +  my-custom-nginx-container:\n    +    image: nginx:latest\n    +    container_name: my-custom-nginx-container\n    +    hostname: my-custom-nginx-container\n    +    volumes:\n    +      - ./nginx_subdomain.conf:/etc/nginx/conf.d/default.conf\n    +    ports:\n    +      - 80:80\n    +    networks:\n    +      - mynetwork.com\n    ```\n  * Start the proxy server with `docker-compose up -d` and access `http://localhost/explorer`.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsettlemint%2Fhyperledger-explorer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsettlemint%2Fhyperledger-explorer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsettlemint%2Fhyperledger-explorer/lists"}