diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..0e8e58a
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,9 @@
+build/
+.vscode/
+.idea/
+tmp/
+*.md
+*.txt
+profile.out
+*.yml
+*.yaml
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 0000000..8b37a6a
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1,12 @@
+# CODEOWNERS: https://help.github.com/articles/about-codeowners/
+
+# Everything goes through the following "global owners" by default.
+# Unless a later match takes precedence, these three will be
+# requested for review when someone opens a PR.
+# Note that the last matching pattern takes precedence, so
+# global owners are only requested if there isn't a more specific
+# codeowner specified below. For this reason, the global codeowners
+# are often repeated in package-level definitions.
+
+# global owners
+* @rach-id
diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
new file mode 100644
index 0000000..b408133
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -0,0 +1,49 @@
+name: Bug Report
+description: Create a report to help us squash bugs!
+title: "
"
+labels: ["bug"]
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ IMPORTANT: Prior to opening a bug report, check if it affects one of the
+ core modules and if it's eligible for a bug bounty on `SECURITY.md`.
+ Bugs that are not submitted through the appropriate channels won't
+ receive any bounty.
+
+ - type: textarea
+ id: summary
+ attributes:
+ label: Summary of Bug
+ description: Concisely describe the issue.
+ validations:
+ required: true
+
+ - type: textarea
+ id: version
+ attributes:
+ label: Version
+ description: git commit hash or release version
+ validations:
+ required: true
+
+ - type: textarea
+ id: repro
+ attributes:
+ label: Steps to Reproduce
+ description: >
+ What commands in order should someone run to reproduce your problem?
+ validations:
+ required: true
+
+ - type: checkboxes
+ id: admin
+ attributes:
+ label: For Admin Use
+ description: (do not edit)
+ options:
+ - label: Not duplicate issue
+ - label: Appropriate labels applied
+ - label: Appropriate contributors tagged
+ - label: Contributor assigned/self-assigned
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
new file mode 100644
index 0000000..e1ab348
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.yml
@@ -0,0 +1,52 @@
+name: Feature Request
+description: Create a proposal to request a feature
+title: ""
+labels: ["enhancement"]
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ✰ Thanks for opening an issue! ✰
+ Before smashing the submit button please fill in the template.
+ Word of caution: poorly thought-out proposals may be rejected without
+ deliberation.
+
+ - type: textarea
+ id: summary
+ attributes:
+ label: Summary
+ description: Short, concise description of the proposed feature.
+ validations:
+ required: true
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem Definition
+ description: |
+ Why do we need this feature?
+ What problems may be addressed by introducing this feature?
+ What benefits does the SDK stand to gain by including this feature?
+ Are there any disadvantages of including this feature?
+ validations:
+ required: true
+
+ - type: textarea
+ id: proposal
+ attributes:
+ label: Proposal
+ description: Detailed description of requirements of implementation.
+ validations:
+ required: true
+
+ - type: checkboxes
+ id: admin
+ attributes:
+ label: For Admin Use
+ description: (do not edit)
+ options:
+ - label: Not duplicate issue
+ - label: Appropriate labels applied
+ - label: Appropriate contributors tagged
+ - label: Contributor assigned/self-assigned
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..8e18b77
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,26 @@
+version: 2
+updates:
+ - package-ecosystem: docker
+ directory: "/"
+ schedule:
+ interval: daily
+ open-pull-requests-limit: 10
+ reviewers:
+ - "rach-id"
+ - package-ecosystem: github-actions
+ directory: "/"
+ schedule:
+ interval: daily
+ open-pull-requests-limit: 10
+ reviewers:
+ - "rach-id"
+ - package-ecosystem: gomod
+ directory: "/"
+ schedule:
+ interval: daily
+ open-pull-requests-limit: 10
+ labels:
+ - automerge
+ - dependencies
+ reviewers:
+ - "rach-id"
diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml
new file mode 100644
index 0000000..9342091
--- /dev/null
+++ b/.github/workflows/ci-release.yml
@@ -0,0 +1,108 @@
+name: CI and Release
+
+# Run this workflow on push events (i.e. PR merge) to main or release branches,
+# push events for new semantic version tags, all PRs, and manual triggers.
+on:
+ push:
+ branches:
+ - main
+ tags:
+ - "v[0-9]+.[0-9]+.[0-9]+"
+ - "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+"
+ - "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+"
+ - "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+"
+ pull_request:
+ workflow_dispatch:
+ # Inputs the workflow accepts.
+ inputs:
+ version:
+ # Friendly description to be shown in the UI instead of 'name'
+ description: "Semver type of new version (major / minor / patch)"
+ # Input has to be provided for the workflow to run
+ required: true
+ type: choice
+ options:
+ - patch
+ - minor
+ - major
+
+jobs:
+ lint:
+ uses: ./.github/workflows/lint.yml
+
+ test:
+ uses: ./.github/workflows/test.yml
+
+ goreleaser-check:
+ runs-on: ubuntu-latest
+ steps:
+ - name: checkout
+ uses: actions/checkout@v4
+ - uses: goreleaser/goreleaser-action@v5
+ with:
+ version: latest
+ args: check
+
+ # branch_name trims ref/heads/ from github.ref to access a clean branch name
+ branch_name:
+ runs-on: ubuntu-latest
+ outputs:
+ branch: ${{ steps.trim_ref.outputs.branch }}
+ steps:
+ - name: Trim branch name
+ id: trim_ref
+ run: |
+ echo "branch=$(${${{ github.ref }}:11})" >> $GITHUB_OUTPUT
+
+ # If this was a workflow dispatch event, we need to generate and push a tag
+ # for goreleaser to grab
+ version_bump:
+ needs: [lint, test, branch_name, goreleaser-check]
+ runs-on: ubuntu-latest
+ permissions: "write-all"
+ steps:
+ - uses: actions/checkout@v4
+ - name: Bump version and push tag
+ # Placing the if condition here is a workaround for needing to block
+ # on this step during workflow dispatch events but the step not
+ # needing to run on tags. If we had the if condition on the full
+ # version_bump section, it would skip and not run, which would result
+ # in goreleaser not running either.
+ if: ${{ github.event_name == 'workflow_dispatch' }}
+ uses: mathieudutour/github-tag-action@v6.1
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ default_bump: ${{ inputs.version }}
+ # Setting the branch name so that release branch other than
+ # master/main doesn't impact tag name
+ release_branches: ${{ needs.branch_name.outputs.branch }}
+
+ # Generate the release with goreleaser to include pre-built binaries
+ goreleaser:
+ needs: version_bump
+ runs-on: ubuntu-20.04
+ if: |
+ github.event_name == 'workflow_dispatch' ||
+ (github.event_name == 'push' && contains(github.ref, 'refs/tags/'))
+ permissions: "write-all"
+ steps:
+ - uses: actions/checkout@v4
+ - run: git fetch --force --tags
+ - uses: actions/setup-go@v5
+ with:
+ go-version: 1.21.6
+ - name: Import GPG key
+ id: import_gpg
+ uses: crazy-max/ghaction-import-gpg@v6
+ with:
+ gpg_private_key: ${{ secrets.GPG_SIGNING_KEY }}
+ passphrase: ${{ secrets.GPG_PASSPHRASE }}
+ # Generate the binaries and release
+ - uses: goreleaser/goreleaser-action@v5
+ with:
+ distribution: goreleaser
+ version: latest
+ args: release --clean
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 0000000..c164dca
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,77 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [ "main" ]
+ schedule:
+ - cron: '17 5 * * 1'
+
+env:
+ GO_VERSION: '1.21.6'
+
+jobs:
+ analyze:
+ name: Analyze
+ # Runner size impacts CodeQL analysis time. To learn more, please see:
+ # - https://gh.io/recommended-hardware-resources-for-running-codeql
+ # - https://gh.io/supported-runners-and-hardware-resources
+ # - https://gh.io/using-larger-runners
+ # Consider using larger runners for possible analysis time improvements.
+ runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
+ timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ 'go' ]
+ # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
+ # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
+ # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
+ # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v3
+ with:
+ languages: ${{ matrix.language }}
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+
+ # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+ # queries: security-extended,security-and-quality
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Build binary
+ run: |
+ make build
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v3
+ with:
+ category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/docker-build-publish.yml b/.github/workflows/docker-build-publish.yml
new file mode 100644
index 0000000..9880152
--- /dev/null
+++ b/.github/workflows/docker-build-publish.yml
@@ -0,0 +1,22 @@
+name: Docker Build & Publish
+
+# Trigger on all push events, new semantic version tags, and all PRs
+on:
+ push:
+ branches:
+ - "main"
+ tags:
+ - "v[0-9]+.[0-9]+.[0-9]+"
+ - "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+"
+ - "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+"
+ - "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+"
+ pull_request:
+
+jobs:
+ docker-security-build:
+ permissions:
+ contents: write
+ packages: write
+ uses: celestiaorg/.github/.github/workflows/reusable_dockerfile_pipeline.yml@v0.2.8 # yamllint disable-line rule:line-length
+ with:
+ dockerfile: Dockerfile
diff --git a/.github/workflows/lables.yml b/.github/workflows/lables.yml
new file mode 100644
index 0000000..e18a3e5
--- /dev/null
+++ b/.github/workflows/lables.yml
@@ -0,0 +1,19 @@
+name: Required Labels
+
+on:
+ pull_request:
+ types: [opened, labeled, unlabeled, synchronize]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ label:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: mheap/github-action-required-labels@v5
+ with:
+ mode: minimum
+ count: 1
+ labels: "bug, chore, CI/CD, enhancement, dependencies, documentation, github_actions, testing" # yamllint disable-line rule:line-length
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..beafc4f
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,35 @@
+name: Lint
+
+on:
+ workflow_call:
+
+jobs:
+ markdown-lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: celestiaorg/.github/.github/actions/markdown-lint@main
+
+ golangci:
+ name: golangci-lint
+ runs-on: ubuntu-latest
+ timeout-minutes: 8
+ env:
+ GO111MODULE: on
+ steps:
+ - uses: actions/setup-go@v5
+ with:
+ go-version: '1.21.6'
+ - uses: actions/checkout@v4
+ - uses: technote-space/get-diff-action@v6.1.2
+ with:
+ PATTERNS: |
+ **/**.go
+ go.mod
+ go.sum
+ - uses: golangci/golangci-lint-action@v3
+ with:
+ version: v1.54
+ args: --timeout 10m
+ github-token: ${{ secrets.github_token }}
+ if: env.GIT_DIFF
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 0000000..ad9ccb2
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,20 @@
+# TODO: Refactor to common workflow
+name: "Close stale issues & pull requests"
+on:
+ schedule:
+ - cron: "0 0 * * *"
+
+jobs:
+ stale:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/stale@v9
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ stale-pr-message: >
+ This pull request has been automatically marked as stale because it
+ has not had recent activity. It will be closed if no further
+ activity occurs. Thank you for your contributions.
+ days-before-stale: 45
+ days-before-close: 6
+ exempt-pr-labels: "pinned, security, proposal, blocked"
diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml
new file mode 100644
index 0000000..c2fdf2f
--- /dev/null
+++ b/.github/workflows/tag.yml
@@ -0,0 +1,27 @@
+name: Release
+# This workflow helps with creating releases.
+# This job will only be triggered when a tag (vX.X.x) is pushed
+on:
+ push:
+ # Sequence of patterns matched against refs/tags
+ tags:
+ - "v[0-9]+.[0-9]+.[0-9]+" # Push events to matching v*, i.e. v1.0, v20.15.10
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Install Go
+ uses: actions/setup-go@v5
+ with:
+ go-version: '1.21.6'
+ - name: Unshallow
+ run: git fetch --prune --unshallow
+ - name: Create release
+ uses: goreleaser/goreleaser-action@v5.0.0
+ with:
+ args: release --rm-dist
+ workdir: ./cmd/blobstreamx-monitor
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..8302ff6
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,43 @@
+name: Tests / Code Coverage
+# Tests / Code Coverage workflow runs unit tests and uploads a code coverage report
+# This workflow is run on pushes to main & every Pull Requests where a .go, .mod, .sum have been changed
+on:
+ workflow_call:
+
+env:
+ GO_VERSION: '1.21.6'
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+ - name: Run tests
+ run: make test
+
+ test-coverage:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+ - name: Generate coverage.txt
+ run: make test-cover
+ - name: Upload coverage.txt
+ uses: codecov/codecov-action@v3.1.4
+ with:
+ file: ./coverage.txt
+
+ test-race:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+ - name: Run tests in race mode
+ run: make test-race
diff --git a/.gitignore b/.gitignore
index 3b735ec..53354ee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,3 +19,5 @@
# Go workspace file
go.work
+.idea/
+build/
\ No newline at end of file
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..5ea7614
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,11 @@
+run:
+ timeout: 5m
+ modules-download-mode: readonly
+
+linters:
+ enable:
+ - exportloopref
+ - gofumpt
+ - misspell
+ - revive
+ - prealloc
diff --git a/.goreleaser.yaml b/.goreleaser.yaml
new file mode 100644
index 0000000..3ae9d09
--- /dev/null
+++ b/.goreleaser.yaml
@@ -0,0 +1,63 @@
+# This is an example .goreleaser.yml file with some sensible defaults.
+# Make sure to check the documentation at https://goreleaser.com
+
+before:
+ hooks:
+ - go mod tidy
+builds:
+ - main: ./cmd/blobstreamx-monitor
+ binary: blobstreamx-monitor
+ env:
+ - VersioningPath={{ "github.com/celestiaorg/blobstreamx-monitor/cmd/blobstreamx-monitor/version" }}
+ goarch:
+ - amd64
+ - arm64
+ goos:
+ - darwin
+ - linux
+ ldflags:
+ # Ref: https://goreleaser.com/customization/templates/#common-fields
+ #
+ # .CommitDate is used to help with reproducible builds, ensuring that the
+ # same date is always used
+ #
+ # .FullCommit is git commit hash goreleaser is using for the release
+ #
+ # .Version is the version being released
+ - -X "{{ .Env.VersioningPath }}.buildTime={{ .CommitDate }}"
+ - -X "{{ .Env.VersioningPath }}.lastCommit={{ .FullCommit }}"
+ - -X "{{ .Env.VersioningPath }}.semanticVersion={{ .Version }}"
+dist: ./build/goreleaser
+archives:
+ - format: tar.gz
+ # this name template makes the OS and Arch compatible with the results of
+ # uname.
+ name_template: >-
+ {{ .ProjectName }}_
+ {{- title .Os }}_
+ {{- if eq .Arch "amd64" }}x86_64
+ {{- else if eq .Arch "386" }}i386
+ {{- else }}{{ .Arch }}{{ end }}
+ {{- if .Arm }}v{{ .Arm }}{{ end }}
+checksum:
+ name_template: "checksums.txt"
+signs:
+ - artifacts: checksum
+ args:
+ [
+ "--batch",
+ "-u",
+ "{{ .Env.GPG_FINGERPRINT }}",
+ "--output",
+ "${signature}",
+ "--detach-sign",
+ "${artifact}",
+ ]
+snapshot:
+ name_template: "{{ incpatch .Version }}-next"
+changelog:
+ sort: asc
+ filters:
+ exclude:
+ - "^docs:"
+ - "^test:"
diff --git a/.markdownlint.yaml b/.markdownlint.yaml
new file mode 100644
index 0000000..0a57674
--- /dev/null
+++ b/.markdownlint.yaml
@@ -0,0 +1,5 @@
+"default": true # Default state for all rules
+"MD010":
+ "code_blocks": false # Disable rule for hard tabs in code blocks
+"MD013": false # Disable rule for line length
+"MD033": false # Disable rule banning inline HTML
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..7bc32c5
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,21 @@
+# Unreleased Changes
+
+## vX.Y.Z
+
+Month, DD, YYYY
+
+### BREAKING CHANGES
+
+- [go package] (Link to PR) Description @username
+
+### FEATURES
+
+- [go package] (Link to PR) Description @username
+
+### IMPROVEMENTS
+
+- [go package] (Link to PR) Description @username
+
+### BUG FIXES
+
+- [go package] (Link to PR) Description @username
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..d29a6db
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,47 @@
+# stage 1 Build blobstreamx-monitor binary
+FROM --platform=$BUILDPLATFORM docker.io/golang:1.21.6-alpine3.18 as builder
+
+ARG TARGETOS
+ARG TARGETARCH
+
+ENV CGO_ENABLED=0
+ENV GO111MODULE=on
+
+RUN apk update && apk --no-cache add make gcc musl-dev git bash
+
+COPY . /blobstreamx-monitor
+WORKDIR /blobstreamx-monitor
+RUN uname -a &&\
+ CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
+ make build
+
+# final image
+FROM docker.io/alpine:3.19.0
+
+ARG UID=10001
+ARG USER_NAME=celestia
+
+ENV CELESTIA_HOME=/home/${USER_NAME}
+
+# hadolint ignore=DL3018
+RUN apk update && apk add --no-cache \
+ bash \
+ curl \
+ jq \
+ # Creates a user with $UID and $GID=$UID
+ && adduser ${USER_NAME} \
+ -D \
+ -g ${USER_NAME} \
+ -h ${CELESTIA_HOME} \
+ -s /sbin/nologin \
+ -u ${UID}
+
+COPY --from=builder /blobstreamx-monitor/build/blobstreamx-monitor /bin/blobstreamx-monitor
+COPY --chown=${USER_NAME}:${USER_NAME} docker/entrypoint.sh /opt/entrypoint.sh
+
+USER ${USER_NAME}
+
+# p2p port
+EXPOSE 30000
+
+ENTRYPOINT [ "/bin/bash", "/opt/entrypoint.sh" ]
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..261eeb9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..56e2742
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,76 @@
+#!/usr/bin/make -f
+
+VERSION := $(shell echo $(shell git describe --tags 2>/dev/null || git log -1 --format='%h') | sed 's/^v//')
+DOCKER := $(shell which docker)
+versioningPath := "github.com/celestiaorg/blobstreamx-monitor/cmd/blobstreamx-monitor/version"
+LDFLAGS=-ldflags="-X '$(versioningPath).buildTime=$(shell date)' -X '$(versioningPath).lastCommit=$(shell git rev-parse HEAD)' -X '$(versioningPath).semanticVersion=$(shell git describe --tags --dirty=-dev 2>/dev/null || git rev-parse --abbrev-ref HEAD)'"
+
+all: install
+.PHONY: all
+
+install: mod-verify
+ @echo "--> Installing blobstreamx-monitor"
+ @go install -mod=readonly ${LDFLAGS} ./cmd/blobstreamx-monitor
+.PHONY: install
+
+mod-verify: mod
+ @echo "--> Verifying dependencies have expected content"
+ GO111MODULE=on go mod verify
+.PHONY: mod-verify
+
+mod:
+ @echo "--> Updating go.mod"
+ @go mod tidy
+.PHONY: mod
+
+pre-build:
+ @echo "--> Fetching latest git tags"
+ @git fetch --tags
+.PHONY: pre-build
+
+build: mod
+ @mkdir -p build/
+ @go build -o build ${LDFLAGS} ./cmd/blobstreamx-monitor
+.PHONY: build
+
+build-docker:
+ @echo "--> Building Docker image"
+ @$(DOCKER) build -t celestiaorg/blobstreamx-monitor -f Dockerfile .
+.PHONY: build-docker
+
+lint:
+ @echo "--> Running golangci-lint"
+ @golangci-lint run
+ @echo "--> Running markdownlint"
+ @markdownlint --config .markdownlint.yaml '**/*.md'
+.PHONY: lint
+
+fmt:
+ @echo "--> Running golangci-lint --fix"
+ @golangci-lint run --fix
+ @echo "--> Running markdownlint --fix"
+ @markdownlint --fix --quiet --config .markdownlint.yaml .
+.PHONY: fmt
+
+test:
+ @echo "--> Running unit tests"
+ @go test -mod=readonly ./...
+.PHONY: test
+
+test-all: test-race test-cover
+.PHONY: test-all
+
+test-race:
+ @echo "--> Running tests with -race"
+ @VERSION=$(VERSION) go test -mod=readonly -race -test.short ./...
+.PHONY: test-race
+
+test-cover:
+ @echo "--> Generating coverage.txt"
+ @export VERSION=$(VERSION); bash -x scripts/test_cover.sh
+.PHONY: test-cover
+
+benchmark:
+ @echo "--> Running tests with -bench"
+ @go test -mod=readonly -bench=. ./...
+.PHONY: benchmark
diff --git a/README.md b/README.md
index 86b816a..713d067 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
# blobstreamx-monitor
+
Simple monitoring tool for BlobstreamX contract
diff --git a/cmd/blobstreamx-monitor/main.go b/cmd/blobstreamx-monitor/main.go
new file mode 100644
index 0000000..2e658b6
--- /dev/null
+++ b/cmd/blobstreamx-monitor/main.go
@@ -0,0 +1,15 @@
+package main
+
+import (
+ "context"
+ "os"
+
+ "github.com/celestiaorg/blobstreamx-monitor/cmd/blobstreamx-monitor/root"
+)
+
+func main() {
+ rootCmd := root.Cmd()
+ if err := rootCmd.ExecuteContext(context.Background()); err != nil {
+ os.Exit(1)
+ }
+}
diff --git a/cmd/blobstreamx-monitor/root/cmd.go b/cmd/blobstreamx-monitor/root/cmd.go
new file mode 100644
index 0000000..5921dd8
--- /dev/null
+++ b/cmd/blobstreamx-monitor/root/cmd.go
@@ -0,0 +1,24 @@
+package root
+
+import (
+ "github.com/celestiaorg/blobstreamx-monitor/cmd/blobstreamx-monitor/version"
+ "github.com/spf13/cobra"
+)
+
+// Cmd creates a new root command for the Blobstreamx-monitor CLI. It is called once in the
+// main function.
+func Cmd() *cobra.Command {
+ rootCmd := &cobra.Command{
+ Use: "blobstreamx-monitor",
+ Short: "The BlobstreamX monitor CLI",
+ SilenceUsage: true,
+ }
+
+ rootCmd.AddCommand(
+ version.Cmd,
+ )
+
+ rootCmd.SetHelpCommand(&cobra.Command{})
+
+ return rootCmd
+}
diff --git a/cmd/blobstreamx-monitor/version/build_info.go b/cmd/blobstreamx-monitor/version/build_info.go
new file mode 100644
index 0000000..f75292a
--- /dev/null
+++ b/cmd/blobstreamx-monitor/version/build_info.go
@@ -0,0 +1,35 @@
+package version
+
+import (
+ "fmt"
+ "runtime"
+)
+
+var (
+ buildTime string
+ lastCommit string
+ semanticVersion string
+
+ systemVersion = fmt.Sprintf("%s/%s", runtime.GOARCH, runtime.GOOS)
+ golangVersion = runtime.Version()
+)
+
+// BuildInfo represents all necessary information about the current build.
+type BuildInfo struct {
+ BuildTime string
+ LastCommit string
+ SemanticVersion string
+ SystemVersion string
+ GolangVersion string
+}
+
+// GetBuildInfo returns information about the current build.
+func GetBuildInfo() *BuildInfo {
+ return &BuildInfo{
+ buildTime,
+ lastCommit,
+ semanticVersion,
+ systemVersion,
+ golangVersion,
+ }
+}
diff --git a/cmd/blobstreamx-monitor/version/version.go b/cmd/blobstreamx-monitor/version/version.go
new file mode 100644
index 0000000..9fa62ca
--- /dev/null
+++ b/cmd/blobstreamx-monitor/version/version.go
@@ -0,0 +1,23 @@
+package version
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+)
+
+var Cmd = &cobra.Command{
+ Use: "version",
+ Short: "Show information about the current binary build",
+ Args: cobra.NoArgs,
+ Run: printBuildInfo,
+}
+
+func printBuildInfo(_ *cobra.Command, _ []string) {
+ buildInfo := GetBuildInfo()
+ fmt.Printf("Semantic version: %s\n", buildInfo.SemanticVersion)
+ fmt.Printf("Commit: %s\n", buildInfo.LastCommit)
+ fmt.Printf("Build Date: %s\n", buildInfo.BuildTime)
+ fmt.Printf("System version: %s\n", buildInfo.SystemVersion)
+ fmt.Printf("Golang version: %s\n", buildInfo.GolangVersion)
+}
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
new file mode 100644
index 0000000..941da73
--- /dev/null
+++ b/docker/entrypoint.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+
+echo "Starting Celestia BlobstreamX-monitor with command:"
+echo "$@"
+echo ""
+
+exec "$@"
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..75199fb
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,10 @@
+module github.com/celestiaorg/blobstreamx-monitor
+
+go 1.21.6
+
+require github.com/spf13/cobra v1.8.0
+
+require (
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/spf13/pflag v1.0.5 // indirect
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..d0e8c2c
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,10 @@
+github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
+github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/scripts/test_cover.sh b/scripts/test_cover.sh
new file mode 100644
index 0000000..6e382c5
--- /dev/null
+++ b/scripts/test_cover.sh
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+set -e
+
+PKGS=$(go list ./...)
+
+set -e
+echo "mode: atomic" > coverage.txt
+# shellcheck disable=SC2068
+for pkg in ${PKGS[@]}; do
+ go test -v -timeout 30m -race -test.short -coverprofile=profile.out -covermode=atomic "$pkg"
+ if [ -f profile.out ]; then
+ tail -n +2 profile.out >> coverage.txt;
+ rm profile.out
+ fi
+done