diff --git a/.github/workflows/erc-registry-indexer.yml b/.github/workflows/erc-registry-indexer.yml new file mode 100644 index 000000000..1b4e3c8eb --- /dev/null +++ b/.github/workflows/erc-registry-indexer.yml @@ -0,0 +1,162 @@ +name: ERC Registry Indexer + +on: + workflow_dispatch: + inputs: + HEDERA_NETWORK: + description: 'Target Hedera Network (e.g., previewnet, testnet, mainnet).' + required: true + MIRROR_NODE_URL: + description: 'Mirror Node Base URL (e.g., https://testnet.mirrornode.hedera.com).' + required: true + STARTING_POINT: + description: 'Starting Point (e.g., a contractId, a contract address, ect.). Leave empty to start from the beginning or from last saved starting point.' + required: false + +jobs: + index-and-update: + name: Index ERC Contracts on Hedera ${{ github.event.inputs.HEDERA_NETWORK }} and Update Registry + runs-on: smart-contracts-linux-large + env: + INDEXER_PATH: ./tools/erc-repository-indexer/erc-contract-indexer + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + submodules: recursive + + - name: Use Node.js [20] + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + node-version: 20 + + - name: Set Environment Variables + run: | + echo "HEDERA_NETWORK=${{ github.event.inputs.HEDERA_NETWORK }}" >> ${{ env.INDEXER_PATH }}/.env + echo "MIRROR_NODE_URL=${{ github.event.inputs.MIRROR_NODE_URL }}" >> ${{ env.INDEXER_PATH }}/.env + echo "STARTING_POINT=${{ github.event.inputs.STARTING_POINT }}" >> ${{ env.INDEXER_PATH }}/.env + + - name: Install Dependencies + run: | + cd ${{env.INDEXER_PATH}} + npm install + + - name: Backup Existing Registry + run: | + mkdir -p ${{ env.INDEXER_PATH }}/backup + if [ -d "${{ env.INDEXER_PATH }}/erc-registry/${{ github.event.inputs.HEDERA_NETWORK }}" ] && [ "$(ls -A ${{ env.INDEXER_PATH }}/erc-registry/${{ github.event.inputs.HEDERA_NETWORK }}/*.json 2>/dev/null)" ]; then + cp ${{ env.INDEXER_PATH }}/erc-registry/${{ github.event.inputs.HEDERA_NETWORK }}/*.json ${{ env.INDEXER_PATH }}/backup/ + echo "Backup successful." + else + echo "No JSON files found to back up." + fi + + - name: Start Timer + id: timer_start + run: echo "START_TIME=$(date +%s)" >> $GITHUB_ENV + + - name: Start ERC Registry Indexer + id: start_erc_indexer + run: | + cd ${{env.INDEXER_PATH}} + npm start + + - name: Stop Timer + id: timer_end + run: echo "END_TIME=$(date +%s)" >> $GITHUB_ENV + + - name: Calculate Duration + id: calculate_duration + run: | + # Calculate the duration in seconds + DURATION=$((END_TIME - START_TIME)) + + # Resolve duration + if [ "$DURATION" -lt 60 ]; then + FORMATTED_DURATION="${DURATION} seconds" + elif [ "$DURATION" -lt 3600 ]; then + MINUTES=$((DURATION / 60)) + SECONDS=$((DURATION % 60)) + FORMATTED_DURATION="${MINUTES} minute(s) and ${SECONDS} second(s)" + else + HOURS=$((DURATION / 3600)) + MINUTES=$(((DURATION % 3600) / 60)) + FORMATTED_DURATION="${HOURS} hour(s) and ${MINUTES} minute(s)" + fi + echo "INDEXING_DURATION=${FORMATTED_DURATION}" >> $GITHUB_ENV + + - name: Count New Records + id: count_records + run: | + cd ${{ env.INDEXER_PATH }} + # Determine the new amount of ERC-20 records + if [ -f backup/erc-20.json ]; then + NEW_ERC20_RECORDS=$(jq -s '.[1] - .[0] | length' backup/erc-20.json erc-registry/${{ github.event.inputs.HEDERA_NETWORK }}/erc-20.json) + else + NEW_ERC20_RECORDS=$(jq '. | length' erc-registry/${{ github.event.inputs.HEDERA_NETWORK }}/erc-20.json) + fi + + # Determine the new amount of of ERC-721 records + if [ -f backup/erc-721.json ]; then + NEW_ERC721_RECORDS=$(jq -s '.[1] - .[0] | length' backup/erc-721.json erc-registry/${{ github.event.inputs.HEDERA_NETWORK }}/erc-721.json) + else + NEW_ERC721_RECORDS=$(jq '. | length' erc-registry/${{ github.event.inputs.HEDERA_NETWORK }}/erc-721.json) + fi + + # Export the results to GitHub environment variables + echo "NEW_ERC20_RECORDS=${NEW_ERC20_RECORDS}" >> $GITHUB_ENV + echo "NEW_ERC721_RECORDS=${NEW_ERC721_RECORDS}" >> $GITHUB_ENV + + - name: Delete backup registry folder + run: | + if [ -d ${{ env.INDEXER_PATH }}/backup ]; then + rm -rf ${{ env.INDEXER_PATH }}/backup + echo "Deleted backup folder." + else + echo "backup folder not found, skipping deletion." + fi + + - name: Import GPG Key + id: gpg_importer + uses: step-security/ghaction-import-gpg@6c8fe4d0126a59d57c21f87c9ae5dd3451fa3cca # v6.1.0 + with: + git_commit_gpgsign: true + git_tag_gpgsign: true + git_user_signingkey: true + gpg_private_key: ${{ secrets.GPG_KEY_CONTENTS }} + passphrase: ${{ secrets.GPG_KEY_PASSPHRASE }} + + - name: Get Current Date + id: current_date + run: echo "CURRENT_DATE=$(date -u +"%m-%d-%Y")" >> $GITHUB_ENV + + - name: Create Pull Request + uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5 + with: + branch: ERC-Registry-Periodical-Update/${{ github.run_id }} + commit-message: 'chore: update ERC Registry with latest ERC-20 and ERC-721 tokens on Hedera ${{github.event.inputs.HEDERA_NETWORK}}' + committer: ${{ steps.gpg_importer.outputs.name }} <${{ steps.gpg_importer.outputs.email }}> + author: ${{ steps.gpg_importer.outputs.name }} <${{ steps.gpg_importer.outputs.email }}> + token: ${{ secrets.GH_ACCESS_TOKEN }} + delete-branch: true + signoff: true + title: 'chore: update ERC Registry with latest ERC-20 and ERC-721 tokens on Hedera ${{github.event.inputs.HEDERA_NETWORK}}' + body: > + **Description**: + + This PR updates the ERC Registry to include the most recent ERC-20 and ERC-721 tokens. + + **Registry Update Summary**: + - **Hedera Network**: ${{ github.event.inputs.HEDERA_NETWORK }} + - **New ERC-20 Records Added**: ${{ env.NEW_ERC20_RECORDS }} + - **New ERC-721 Records Added**: ${{ env.NEW_ERC721_RECORDS }} + - **Indexing Duration**: ${{ env.INDEXING_DURATION }} + - **Current Date**: ${{ env.CURRENT_DATE }} + labels: 'internal' + assignees: 'swirlds-automation' diff --git a/package-lock.json b/package-lock.json index 006f3d71e..c63927da0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@hashgraph/smart-contracts", - "version": "0.11.0-SNAPSHOT", + "version": "0.12.0-SNAPSHOT", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@hashgraph/smart-contracts", - "version": "0.11.0-SNAPSHOT", + "version": "0.12.0-SNAPSHOT", "license": "Apache-2.0", "dependencies": { "@nomicfoundation/solidity-analyzer": "^0.1.2", @@ -17,7 +17,7 @@ }, "devDependencies": { "@hashgraph/hedera-local": "^2.32.6", - "@hashgraph/sdk": "^2.55.0", + "@hashgraph/sdk": "^2.55.1", "@nomicfoundation/hardhat-chai-matchers": "^2.0.8", "@nomicfoundation/hardhat-foundry": "^1.1.3", "@openzeppelin/contracts": "^5.0.2", @@ -620,9 +620,9 @@ } }, "node_modules/@hashgraph/proto": { - "version": "2.16.0-beta.2", - "resolved": "https://registry.npmjs.org/@hashgraph/proto/-/proto-2.16.0-beta.2.tgz", - "integrity": "sha512-BTPShOMhxZqHmayyhg+dqXX1ABP2/znYJ9LKxr2QIf2Jqk2ZfBByPLlp94PzW3Zn9jwJGVJT01Kdl7Rh1Xkxkg==", + "version": "2.16.0-beta.3", + "resolved": "https://registry.npmjs.org/@hashgraph/proto/-/proto-2.16.0-beta.3.tgz", + "integrity": "sha512-gbnE8MXi8N7CGqKXt6FFOFYeEvmcQczRkNICiBEhRLO3YmYWuHyE7MU8cWuSt1KnB8kahw90TbxOYAlCxa317g==", "dev": true, "dependencies": { "long": "^5.2.3", @@ -657,9 +657,9 @@ } }, "node_modules/@hashgraph/sdk": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@hashgraph/sdk/-/sdk-2.55.0.tgz", - "integrity": "sha512-fSRAYtdMCLGOM2SLuNP3Y9P66hlN+0ryX5ppFVD91LhUfKo4sbUMEfn7nOmvUDrWEjJ0TJiRVaHsmYHi8cmlCQ==", + "version": "2.55.1", + "resolved": "https://registry.npmjs.org/@hashgraph/sdk/-/sdk-2.55.1.tgz", + "integrity": "sha512-fiY+V2jVk+vOtIScvtF7gGfsFeSBej2+ESzWDzNT8XklB8bAdKtDeI4w7iNLtxXdP7lkoHRJaxbB9ZHU3dPv/Q==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.7.0", @@ -668,7 +668,7 @@ "@ethersproject/rlp": "^5.7.0", "@grpc/grpc-js": "1.8.2", "@hashgraph/cryptography": "1.4.8-beta.10", - "@hashgraph/proto": "2.16.0-beta.2", + "@hashgraph/proto": "2.16.0-beta.3", "axios": "^1.6.4", "bignumber.js": "^9.1.1", "bn.js": "^5.1.1", @@ -6004,9 +6004,9 @@ } }, "@hashgraph/proto": { - "version": "2.16.0-beta.2", - "resolved": "https://registry.npmjs.org/@hashgraph/proto/-/proto-2.16.0-beta.2.tgz", - "integrity": "sha512-BTPShOMhxZqHmayyhg+dqXX1ABP2/znYJ9LKxr2QIf2Jqk2ZfBByPLlp94PzW3Zn9jwJGVJT01Kdl7Rh1Xkxkg==", + "version": "2.16.0-beta.3", + "resolved": "https://registry.npmjs.org/@hashgraph/proto/-/proto-2.16.0-beta.3.tgz", + "integrity": "sha512-gbnE8MXi8N7CGqKXt6FFOFYeEvmcQczRkNICiBEhRLO3YmYWuHyE7MU8cWuSt1KnB8kahw90TbxOYAlCxa317g==", "dev": true, "requires": { "long": "^5.2.3", @@ -6036,9 +6036,9 @@ } }, "@hashgraph/sdk": { - "version": "2.55.0", - "resolved": "https://registry.npmjs.org/@hashgraph/sdk/-/sdk-2.55.0.tgz", - "integrity": "sha512-fSRAYtdMCLGOM2SLuNP3Y9P66hlN+0ryX5ppFVD91LhUfKo4sbUMEfn7nOmvUDrWEjJ0TJiRVaHsmYHi8cmlCQ==", + "version": "2.55.1", + "resolved": "https://registry.npmjs.org/@hashgraph/sdk/-/sdk-2.55.1.tgz", + "integrity": "sha512-fiY+V2jVk+vOtIScvtF7gGfsFeSBej2+ESzWDzNT8XklB8bAdKtDeI4w7iNLtxXdP7lkoHRJaxbB9ZHU3dPv/Q==", "dev": true, "requires": { "@ethersproject/abi": "^5.7.0", @@ -6047,7 +6047,7 @@ "@ethersproject/rlp": "^5.7.0", "@grpc/grpc-js": "1.8.2", "@hashgraph/cryptography": "1.4.8-beta.10", - "@hashgraph/proto": "2.16.0-beta.2", + "@hashgraph/proto": "2.16.0-beta.3", "axios": "^1.6.4", "bignumber.js": "^9.1.1", "bn.js": "^5.1.1", diff --git a/package.json b/package.json index 5ec2a9189..ebd3ef6ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@hashgraph/smart-contracts", - "version": "0.11.0-SNAPSHOT", + "version": "0.12.0-SNAPSHOT", "description": "Hedera Smart Contract Service supporting files", "files": [ "/contracts/**/*.sol", @@ -34,7 +34,7 @@ }, "devDependencies": { "@hashgraph/hedera-local": "^2.32.6", - "@hashgraph/sdk": "^2.55.0", + "@hashgraph/sdk": "^2.55.1", "@nomicfoundation/hardhat-chai-matchers": "^2.0.8", "@nomicfoundation/hardhat-foundry": "^1.1.3", "@openzeppelin/contracts": "^5.0.2", diff --git a/tools/erc-repository-indexer/erc-contract-indexer/README.md b/tools/erc-repository-indexer/erc-contract-indexer/README.md index 7d159f8e9..15d4fb88b 100644 --- a/tools/erc-repository-indexer/erc-contract-indexer/README.md +++ b/tools/erc-repository-indexer/erc-contract-indexer/README.md @@ -41,8 +41,6 @@ The ERC Contract Indexer is a tool designed to facilitate the indexing and manag | `MIRROR_NODE_URL` | The URL for the Hedera mirror node API. | A valid URL pointing to the Hedera mirror node (e.g., `https://{previewnet\|testnet\|mainnet}.mirrornode.hedera.com`) | | `MIRROR_NODE_URL_WEB3` | The URL for the Hedera Mirror Node Web3Module API, required only when `HEDERA_NETWORK` is set to `local-node`. | Any value | | `STARTING_POINT` | The starting point for contract indexing. | A Hedera contract ID (e.g., `0.0.369`), an EVM 20-byte address (e.g., `0x0000000000000000000000000000000000000369`), or a get contract list next pointer (e.g., `/api/v1/contracts?limit=100&order=asc&contract.id=gt:0.0.369`) | -| `SDK_OPERATOR_ID` | The operator ID used to initialize a Hashgraph SDK, applicable only for testing. | Hedera Account IDs | -| `SDK_OPERATOR_KEY` | The operator Key used to initialize a Hashgraph SDK, applicable only for testing. | Hedera Account DER Private Key | Example configuration: @@ -86,12 +84,25 @@ This will initiate the indexing process, fetching contracts from the specified s > **Note:** Future updates will enhance the JSON file format to include additional details about the ERC tokens. -### Testing +### Unit Testing -To run the tests for the project, use the following command: +To run the unit tests for the project, use the following command: ```bash -npm test +npm test:unit ``` -This will execute the test suite and provide feedback on the functionality of the services. +### Acceptance Testing + +To enable acceptance testing, new configurations must be added to the `.env` file: + +| Variable | Description | Accepted Values | +| ------------------ | ---------------------------------------------------- | ------------------------------ | +| `SDK_OPERATOR_ID` | The operator ID used to initialize a Hashgraph SDK. | Hedera Account IDs | +| `SDK_OPERATOR_KEY` | The operator key used to initialize a Hashgraph SDK. | Hedera Account DER Private Key | + +To execute the acceptance tests, use the following command: + +```bash +npm test:acceptance +```