diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 000000000..e5b6d8d6a --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/afraid-views-post.md b/.changeset/afraid-views-post.md new file mode 100644 index 000000000..f524e9f4a --- /dev/null +++ b/.changeset/afraid-views-post.md @@ -0,0 +1,5 @@ +--- +"@hashgraph/asset-tokenization-dapp": minor +--- + +Add getCouponAmountFor info (numerator, denominator, recordDateReached) to see coupon view diff --git a/.changeset/busy-loops-move.md b/.changeset/busy-loops-move.md new file mode 100644 index 000000000..f348cf366 --- /dev/null +++ b/.changeset/busy-loops-move.md @@ -0,0 +1,6 @@ +--- +"@hashgraph/asset-tokenization-sdk": major +"@hashgraph/asset-tokenization-dapp": minor +--- + +[ATS-SDK] Add tokenBalance and decimals to getCouponFor and [ATS-WEB] add fullRedeem in forceRedeem view and balance in seeCoupons and seeDividend views diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 000000000..976d50dbe --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [ + [ + "@hashgraph/asset-tokenization-contracts", + "@hashgraph/asset-tokenization-sdk", + "@hashgraph/asset-tokenization-dapp" + ] + ], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.changeset/fix-recursive-publish.md b/.changeset/fix-recursive-publish.md new file mode 100644 index 000000000..e1bb21c5a --- /dev/null +++ b/.changeset/fix-recursive-publish.md @@ -0,0 +1,17 @@ +--- +"@hashgraph/asset-tokenization-contracts": patch +"@hashgraph/asset-tokenization-sdk": patch +--- + +fix: CI workflow improvements for reliable releases + +1. **Fixed --ignore pattern in ats.release.yml**: Changed from non-existent + `@hashgraph/mass-payout*` to correct `@mass-payout/*` package namespace + +2. **Simplified publish trigger in ats.publish.yml**: Changed from + `release: published` to `push.tags` for automatic publishing on tag push + (no need to manually create GitHub release) + +3. **Removed recursive publish scripts**: Removed `"publish": "npm publish"` + from contracts and SDK package.json files that caused npm to recursively + call itself during publish lifecycle, resulting in 403 errors in CI diff --git a/.changeset/free-pears-make.md b/.changeset/free-pears-make.md new file mode 100644 index 000000000..a77d0a4a7 --- /dev/null +++ b/.changeset/free-pears-make.md @@ -0,0 +1,5 @@ +--- +"@hashgraph/asset-tokenization-contracts": minor +--- + +Add bytes operationData to ClearingOperationApproved event in case of creating a new hold to send the holdId or to be used by other operation in the future diff --git a/.changeset/full-ghosts-tan.md b/.changeset/full-ghosts-tan.md new file mode 100644 index 000000000..f4f4a6ebe --- /dev/null +++ b/.changeset/full-ghosts-tan.md @@ -0,0 +1,5 @@ +--- +"@hashgraph/asset-tokenization-contracts": patch +--- + +Lock and Clearing operations now trigger account balance snapshots. Frozen balance at snapshots methods created diff --git a/.changeset/large-aliens-train.md b/.changeset/large-aliens-train.md new file mode 100644 index 000000000..0e428dac4 --- /dev/null +++ b/.changeset/large-aliens-train.md @@ -0,0 +1,6 @@ +--- +"@hashgraph/asset-tokenization-dapp": minor +"@hashgraph/asset-tokenization-sdk": patch +--- + +Add a checkbox in force redeem view to redeem every tokens if the maturity date has arrived diff --git a/.changeset/social-cougars-wash.md b/.changeset/social-cougars-wash.md new file mode 100644 index 000000000..2045ec875 --- /dev/null +++ b/.changeset/social-cougars-wash.md @@ -0,0 +1,5 @@ +--- +"@hashgraph/asset-tokenization-dapp": minor +--- + +Add getDividendAmountFor info (numerator, denominator, recordDateReached) in see dividend view diff --git a/.github/WORKFLOWS.md b/.github/WORKFLOWS.md new file mode 100644 index 000000000..d2a361f27 --- /dev/null +++ b/.github/WORKFLOWS.md @@ -0,0 +1,342 @@ +# GitHub Workflows Documentation + +This document explains the CI/CD system for the Asset Tokenization Studio (ATS) monorepo, including development workflow, release processes, and how to work with changesets. + +## Overview + +The repository uses **Changesets** for version management with independent release cycles for: + +- **ATS Project**: Asset Tokenization Studio (contracts, SDK, web app) +- **Mass Payout Project**: Mass payout functionality + +All development happens on the `develop` branch with automated testing, changeset validation, and manual release controls by authorized teams. + +## Developer Workflow + +### Daily Development Process + +```mermaid +sequenceDiagram + participant D as develop + participant F as feature/branch + participant M as main + participant F1 as feature/branch-main + + Note over D,M: Daily Development Pattern + + D->>F: Create feature branch + Note over F: Code changes + changeset + F->>D: PR with changeset (tests + validation) + Note over D: Accumulate features + + D->>F1: Create branch from develop + Note over F1: Same changes (no changeset needed) + F1->>M: PR to main (ready for release) + Note over M: Production-ready code +``` + +### Step-by-Step Guide + +1. **Create feature branch from develop**: + + ```bash + git checkout develop && git pull origin develop + git checkout -b feature/your-feature-name + ``` + +2. **Make your changes** to ATS or Mass Payout packages + +3. **Create changeset** (required for all PRs): + + ```bash + npm run changeset + ``` + + - Select affected packages + - Choose change type (patch/minor/major) + - Write clear description + +4. **Commit with DCO and Signature compliance**: + +Commit messages should comply with the [conventional commits standard](https://www.conventionalcommits.org/en/v1.0.0/) + +```bash +git add . +git commit --signoff -S -m "feat: your commit message" +git push origin feature/your-feature-name +``` + +5. **Open PR to develop branch** - automated checks will run + +### Bypass Changeset Validation + +For non-feature changes, add these labels to skip changeset requirement: + +- `no-changeset`: Configuration or documentation changes +- `docs-only`: Documentation-only changes +- `chore`: Build system or dependency updates +- `hotfix`: Emergency fixes + +## Workflow Reference + +### Automated Workflows + +| Workflow | Trigger | Purpose | +| --------------------- | ---------------------------- | ------------------------------------- | +| **ATS Tests** | PR to main, ATS file changes | Run ATS contracts, SDK, and web tests | +| **Mass Payout Tests** | PR to main, MP file changes | Run Mass Payout package tests | +| **Changeset Check** | PR to develop | Validate changeset or bypass labels | + +### Manual Release Workflows + +| Workflow | Purpose | Authorized Teams | +| ----------------------- | ------------------------------------ | ------------------------------------------------------------ | +| **ATS Release** | Version ATS packages, create release | platform-ci, release-engineering-managers, iobuilders-hedera | +| **Mass Payout Release** | Version MP packages, create release | platform-ci, release-engineering-managers, iobuilders-hedera | + +### Automatic Publishing + +| Workflow | Trigger | Purpose | +| ----------------------- | ----------------- | --------------------------- | +| **ATS Publish** | Tag push `v*-ats` | Publish ATS packages to npm | +| **Mass Payout Publish** | Tag push `v*-mp` | Publish MP packages to npm | + +## Release Process + +The repository supports **two release approaches**: + +1. **Automated Release Workflows** (recommended for most releases) +2. **Manual Release Branches** (alternative for complex releases or when automation is unavailable) + +### Option 1: Automated Release Workflows + +#### ATS Release Flow + +```mermaid +sequenceDiagram + participant Dev as Developer + participant M as main + participant GH as GitHub Actions + participant NPM as NPM Registry + + Dev->>GH: Trigger ATS Release Workflow + GH->>GH: Validate ATS changesets exist + GH->>M: Run changeset version --ignore MP packages + GH->>M: Commit version changes + GH->>M: Push tag v1.16.0-ats + Note over GH,NPM: Tag push auto-triggers publish workflow + GH->>NPM: Publish contracts & SDK + Note over GH: GitHub release created (optional, for notes) +``` + +#### Mass Payout Release Flow + +```mermaid +sequenceDiagram + participant Dev as Developer + participant M as main + participant GH as GitHub Actions + participant NPM as NPM Registry + + Dev->>GH: Trigger MP Release Workflow + GH->>GH: Validate MP changesets exist + GH->>M: Run changeset version --ignore ATS packages + GH->>M: Commit version changes + GH->>M: Push tag v2.4.0-mp + Note over GH,NPM: Tag push auto-triggers publish workflow + GH->>NPM: Publish MP packages + Note over GH: GitHub release created (optional, for notes) +``` + +#### Release Options + +Both automated workflows support: + +- **Preview Mode**: Shows what would be released (dry-run) +- **Release Mode**: Actually creates releases and triggers publishing + +### Option 2: Manual Release Branches + +For complex releases or when automation is unavailable, you can use the traditional manual release branch approach: + +```mermaid +sequenceDiagram + participant M as main + participant D as develop + participant F as feat/example + participant F1 as feat/example-main + participant R as release/v1.22.2-ats + + Note over M,D: Initial state + + loop for each feature in sprint + D->>F: Create feature branch + Note over F: Feature development + changeset + F->>D: Merge PR with changeset + + D->>F1: Create branch from develop + F1->>M: Merge PR directly to main + end + + M->>R: Create release branch + Note over R: Run: npx changeset version + Note over R: Generate changelogs + version bump + R->>M: Merge version commit to main + + Note over M: Create tag v1.22.2-ats + Note over M: Manual GitHub release + Note over M: Automatic NPM publish via workflow + + M->>D: Merge main back to develop +``` + +#### Manual Release Steps + +1. **Create release branch from main**: + + ```bash + git checkout main && git pull origin main + git checkout -b release/v1.22.2-ats + ``` + +2. **Apply changesets and version packages**: + + ```bash + # For ATS release (ignore all Mass Payout packages) + npx changeset version \ + --ignore "@mass-payout/contracts" \ + --ignore "@mass-payout/sdk" \ + --ignore "@mass-payout/backend" \ + --ignore "@mass-payout/frontend" + + # For Mass Payout release (ignore all ATS packages) + npx changeset version \ + --ignore "@hashgraph/asset-tokenization-contracts" \ + --ignore "@hashgraph/asset-tokenization-sdk" + ``` + +3. **Commit version changes**: + + ```bash + git add . + git commit --signoff -S -m "chore: release v1.22.2-ats" + git push origin release/v1.22.2-ats + ``` + +4. **Merge release branch to main**: + - Create PR from `release/v1.22.2-ats` to `main` + - Review and merge the version changes + +5. **Create and push tag**: + + ```bash + git tag v1.22.2-ats + git push origin v1.22.2-ats + ``` + + - Tag push automatically triggers publish workflow + - Optionally create GitHub release for release notes + +6. **Sync main back to develop**: + ```bash + git checkout develop + git merge main + git push origin develop + ``` + +**Benefits of Manual Release Branches**: + +- ✅ Full control over version timing and content +- ✅ Ability to make additional changes during release process +- ✅ Works with existing automated publishing workflows +- ✅ Suitable for complex releases requiring manual intervention + +### Release Authorization + +Only these teams can trigger releases: + +- `platform-ci` +- `platform-ci-committers` +- `release-engineering-managers` +- `developer-advocates` +- `iobuilders-hedera` +- Users containing `hashgraph` + +## Workflow Interactions + +```mermaid +sequenceDiagram + participant D as develop + participant M as main + participant GH as GitHub Actions + participant NPM as NPM Registry + + Note over D,M: Workflow Overview + + loop Feature Development + Note over D: Features merge to develop + Note over D: Changesets accumulate + D->>M: Feature PRs to main + end + + Note over M: Ready for release + M->>GH: Manual release workflow trigger + GH->>M: Version packages + GH->>M: Push tag (e.g., v2.0.0-ats) + Note over GH,NPM: Tag push auto-triggers publish + GH->>NPM: Publish to NPM + Note over GH: GitHub release optional (for notes) + + M->>D: Sync version changes back +``` + +## Troubleshooting + +### Common Issues + +**❌ Changeset check failed** + +- **Solution**: Create changeset with `npm run changeset` or add bypass label + +**❌ "No changesets found to be bumped"** + +- **Solution**: Ensure changesets exist for the project you're releasing +- Use `npm run changeset:status` to check pending changes + +**❌ Release workflow unauthorized** + +- **Solution**: Ensure you're member of authorized teams listed in CODEOWNERS + +**❌ Tests failing on PR** + +- **Solution**: Run `npm run ats:test` or `npm run mass-payout:test` locally +- Fix failing tests before requesting review + +**❌ DCO check failed** + +- **Solution**: Ensure all commits use `--signoff` flag: + ```bash + git commit --signoff -S -m "your message" + ``` + +### Getting Help + +- **Changesets documentation**: [Changesets Intro](https://github.com/changesets/changesets/blob/main/docs/intro-to-using-changesets.md) +- **Check pending releases**: `npm run changeset:status` +- **Preview releases**: `npm run release:preview` +- **Local development**: See `CLAUDE.md` for complete development setup + +## Quick Commands + +```bash +# Development +npm run changeset # Create changeset +npm run changeset:status # Check pending changes +npm run ats:test # Run ATS tests +npm run mass-payout:test # Run MP tests + +# Preview releases +npm run release:preview # Show all pending releases +npm run release:ats # Preview ATS release (local) +npm run release:mp # Preview MP release (local) +``` diff --git a/.github/workflows/all.publish.yml b/.github/workflows/all.publish.yml deleted file mode 100644 index f0e263d1b..000000000 --- a/.github/workflows/all.publish.yml +++ /dev/null @@ -1,58 +0,0 @@ -name: Publishing - -on: - release: - types: - - published - -permissions: - contents: read - -jobs: - publish: - name: Publish NPM Packages - runs-on: ubuntu-latest - - steps: - - name: Harden Runner - uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 - with: - egress-policy: audit - - - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Setup NodeJS Environment - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 - with: - node-version: 20.x - - - name: Create file .npmrc - run: | - touch .npmrc - echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> .npmrc - cp .npmrc ./packages/ats/contracts/.npmrc - cp .npmrc ./packages/ats/sdk/.npmrc - - - name: Install dependencies - run: npm ci - - # --- ATS publishing --- - - name: Publish ats/contracts - if: contains(github.ref_name, 'ats') - run: npm run ats:contracts:publish --access=public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Publish ats/sdk - if: contains(github.ref_name, 'ats') - run: npm run ats:sdk:publish --access=public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - - # --- Mass Payout publishing --- - - name: Publish mass-payout - if: contains(github.ref_name, 'mp') - run: npm run mass-payout:publish --access=public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/ats.publish.yml b/.github/workflows/ats.publish.yml new file mode 100644 index 000000000..0729b1e1f --- /dev/null +++ b/.github/workflows/ats.publish.yml @@ -0,0 +1,166 @@ +name: ATS Publish + +on: + # Manual trigger with dry-run option + workflow_dispatch: + inputs: + dry-run-enabled: + description: "Run npm publish with dry-run flag" + required: false + type: boolean + default: false + + # Tag push trigger - simpler and automatic (no need to create GitHub release) + push: + tags: + - "v*-ats" + - "v*-ATS" + +defaults: + run: + shell: bash + +permissions: + contents: read + id-token: write + +jobs: + contracts: + name: Publish ATS Contracts + runs-on: token-studio-linux-large + # Only run if manual trigger OR tag push (already filtered by v*-ats pattern) + if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'push' }} + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + + - name: Setup NodeJS Environment + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22.20.0 + registry-url: https://registry.npmjs.org + + - name: Create .npmrc file + working-directory: packages/ats/contracts + run: | + cat << 'EOF' > .npmrc + //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} + EOF + + - name: Install dependencies + run: npm ci + + - name: Build ATS Contracts + run: npm run ats:contracts:build + + - name: Publish ATS Contracts + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + DRY_RUN: ${{ inputs.dry-run-enabled }} + working-directory: packages/ats/contracts + run: | + PUBLISH_ARGS=("--access=public") + if [[ "${DRY_RUN}" == "true" ]]; then + PUBLISH_ARGS+=("--dry-run") + echo "🔍 DRY RUN MODE: Would publish @hashgraph/asset-tokenization-contracts" + fi + + if ! npm publish "${PUBLISH_ARGS[@]}"; then + echo "❌ Failed to publish package: ${package_name}" + echo "📋 Package info:" && cat package.json | jq '.name, .version' + exit 1 + fi + + sdk: + name: Publish ATS SDK + runs-on: token-studio-linux-large + # Only run if manual trigger OR tag push (already filtered by v*-ats pattern) + if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'push' }} + # needs: contracts # Commented out for parallel execution + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + + - name: Setup NodeJS Environment + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22.20.0 + registry-url: https://registry.npmjs.org + + - name: Create .npmrc file + working-directory: packages/ats/sdk + run: | + cat << 'EOF' > .npmrc + //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} + EOF + + - name: Install dependencies + run: npm ci + + - name: Build ATS Contracts and SDK + run: | + npm run ats:contracts:build + npm run ats:sdk:build + + - name: Publish ATS SDK + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + DRY_RUN: ${{ inputs.dry-run-enabled }} + working-directory: packages/ats/sdk + run: | + PUBLISH_ARGS=("--access=public") + if [[ "${DRY_RUN}" == "true" ]]; then + PUBLISH_ARGS+=("--dry-run") + echo "🔍 DRY RUN MODE: Would publish @hashgraph/asset-tokenization-sdk" + fi + + if ! npm publish "${PUBLISH_ARGS[@]}"; then + echo "❌ Failed to publish package: ${package_name}" + echo "📋 Package info:" && cat package.json | jq '.name, .version' + exit 1 + fi + + # Summary job to report results + summary: + name: Publish Summary + runs-on: token-studio-linux-large + needs: + - contracts + - sdk + if: ${{ always() }} + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 + with: + egress-policy: audit + + - name: Report Results + run: | + echo "## ATS Publish Results" >> "${GITHUB_STEP_SUMMARY}" + echo "| Package | Status |" >> "${GITHUB_STEP_SUMMARY}" + echo "| --- | --- |" >> "${GITHUB_STEP_SUMMARY}" + echo "| Contracts | ${{ needs.contracts.result }} |" >> "${GITHUB_STEP_SUMMARY}" + echo "| SDK | ${{ needs.sdk.result }} |" >> "${GITHUB_STEP_SUMMARY}" + + if [[ "${{ inputs.dry-run-enabled }}" == "true" ]]; then + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "🔍 **DRY RUN MODE** - No packages were actually published" >> "${GITHUB_STEP_SUMMARY}" + fi diff --git a/.github/workflows/ats.release.yml b/.github/workflows/ats.release.yml new file mode 100644 index 000000000..28e8ff92a --- /dev/null +++ b/.github/workflows/ats.release.yml @@ -0,0 +1,160 @@ +name: ATS Release + +on: + # Manual trigger with preview/release option + workflow_dispatch: + inputs: + release-type: + description: "Type of release to perform" + required: true + type: choice + options: + - preview # Show what would be released (dry-run) + - release # Full production release + default: "preview" + +defaults: + run: + shell: bash + +permissions: + contents: write # For creating commits and tags + id-token: write + +jobs: + ats-release: + name: Create ATS Release + runs-on: token-studio-linux-large + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + # Use GitHub App token to bypass branch protection + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Setup NodeJS Environment + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: v22.20.0 + + - name: Install dependencies + run: npm ci + + - name: Validate ATS changesets exist + id: validate + run: | + echo "📋 Getting changeset status..." + npx changeset status --output=changeset-status.json + + ATS_PACKAGES_TO_BUMP=$(jq -r '.releases[] | select(.name | test("@hashgraph/asset-tokenization-")) | .name' changeset-status.json | wc -l) + + echo "ats-packages-to-bump=${ATS_PACKAGES_TO_BUMP}" >> "${GITHUB_OUTPUT}" + + if [ "${ATS_PACKAGES_TO_BUMP}" -eq 0 ]; then + echo "❌ No ATS packages found to be bumped" + echo "📋 Current changeset status:" + npx changeset status + exit 1 + fi + + echo "✅ Found ${ATS_PACKAGES_TO_BUMP} ATS package(s) ready for release" + + echo "📦 ATS packages to be released:" + jq -r '.releases[] | select(.name | test("@hashgraph/asset-tokenization-")) | " - \(.name) (\(.oldVersion) → \(.newVersion))"' changeset-status.json + + - name: Preview ATS release + if: ${{ inputs.release-type == 'preview' }} + run: | + echo "🔍 PREVIEW MODE - What would be released for ATS packages:" + echo "" + echo "📋 Current changeset status:" + npx changeset status + echo "" + echo "🚫 Mass Payout packages would be ignored during ATS release" + echo "🎯 Only @hashgraph/asset-tokenization-* packages would be processed" + echo "" + echo "To proceed with actual release, run this workflow with 'release' option." + + - name: Version ATS packages + if: ${{ inputs.release-type == 'release' }} + run: | + echo "🚀 Releasing ATS packages only (ignoring Mass Payout packages)" + + # Ignore all mass-payout packages (they use @mass-payout/* namespace) + npx changeset version \ + --ignore "@mass-payout/contracts" \ + --ignore "@mass-payout/sdk" \ + --ignore "@mass-payout/backend" \ + --ignore "@mass-payout/frontend" + + if [[ -n "$(git status --porcelain)" ]]; then + echo "✅ Version bump completed for ATS packages" + else + echo "❌ No version changes detected" + exit 1 + fi + + - name: Commit version changes + if: ${{ inputs.release-type == 'release' }} + run: | + git add . + + if git commit --signoff -S -m "chore: release ATS packages"; then + echo "✅ Version changes committed" + else + echo "ℹ️ No changes to commit" + fi + + - name: Create ATS release + id: create-release-tag + if: ${{ inputs.release-type == 'release' }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ATS_VERSION=$(node -p "require('./packages/ats/contracts/package.json').version") + TAG_NAME="v${ATS_VERSION}-ats" + echo "📦 Creating ATS release tag: ${TAG_NAME}" + git tag "${TAG_NAME}" + git push origin "${TAG_NAME}" + + echo "tag-name=${TAG_NAME}" >> "${GITHUB_OUTPUT}" + + - name: Create github release + if: ${{ inputs.release-type == 'release' }} + uses: step-security/release-action@03a57407052f15d1537fd5469a6fbbc536aba326 # v1.20.0 + with: + tag: ${{ steps.create-release-tag.outputs.tag-name }} + prerelease: false + draft: false + generateReleaseNotes: true + skipIfReleaseExists: true + + - name: Release Summary + if: always() + run: | + if [ "${{ inputs.release-type }}" = "preview" ]; then + echo "## 🔍 ATS Release Preview Completed" >> "${GITHUB_STEP_SUMMARY}" + echo "Preview mode was selected. No actual release was created." >> "${GITHUB_STEP_SUMMARY}" + elif [ "${{ job.status }}" = "success" ]; then + ATS_VERSION=$(node -p "require('./packages/ats/contracts/package.json').version" 2>/dev/null || echo "unknown") + echo "## ✅ ATS Release v${ATS_VERSION} Completed Successfully" >> "${GITHUB_STEP_SUMMARY}" + echo "| Package | Status |" >> "${GITHUB_STEP_SUMMARY}" + echo "| --- | --- |" >> "${GITHUB_STEP_SUMMARY}" + echo "| ATS Contracts | ✅ Released |" >> "${GITHUB_STEP_SUMMARY}" + echo "| ATS SDK | ✅ Released |" >> "${GITHUB_STEP_SUMMARY}" + echo "| GitHub Release | ✅ Created |" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "**Next Steps:**" >> "${GITHUB_STEP_SUMMARY}" + echo "- NPM publishing will be triggered automatically via ats.publish.yml" >> "${GITHUB_STEP_SUMMARY}" + echo "- Mass Payout packages were ignored and remain available for separate release" >> "${GITHUB_STEP_SUMMARY}" + else + echo "## ❌ ATS Release Failed" >> "${GITHUB_STEP_SUMMARY}" + echo "Check the logs above for details on what went wrong." >> "${GITHUB_STEP_SUMMARY}" + fi diff --git a/.github/workflows/ats.test.yml b/.github/workflows/ats.test.yml index 97e46c02b..04d049914 100644 --- a/.github/workflows/ats.test.yml +++ b/.github/workflows/ats.test.yml @@ -5,11 +5,11 @@ on: branches: [main] pull_request: paths: - - 'packages/ats/**' - - 'apps/ats/**' - - 'package.json' - - '.github/workflows/*ats*.yml' - - '.github/workflows/*ats*.yaml' + - "packages/ats/**" + - "apps/ats/**" + - "package.json" + - ".github/workflows/*ats*.yml" + - ".github/workflows/*ats*.yaml" workflow_dispatch: permissions: @@ -20,31 +20,31 @@ jobs: name: testing runs-on: token-studio-linux-large env: - NODE_OPTIONS: '--max-old-space-size=32768' - CONTRACT_SIZER_RUN_ON_COMPILE: 'false' - REPORT_GAS: 'false' + NODE_OPTIONS: "--max-old-space-size=32768" + CONTRACT_SIZER_RUN_ON_COMPILE: "false" + REPORT_GAS: "false" CLIENT_PRIVATE_KEY_ECDSA_1: ${{ secrets.CLIENT_PRIVATE_KEY_ECDSA_1 }} CLIENT_PUBLIC_KEY_ECDSA_1: ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_1 }} - CLIENT_ACCOUNT_ID_ECDSA_1: '0.0.1328' - CLIENT_EVM_ADDRESS_ECDSA_1_CORRECT: '0x97C50bb12E1C6284cF2855cdba95c5D60AEE44CF' - CLIENT_EVM_ADDRESS_ECDSA_1: '0x0000000000000000000000000000000000000530' + CLIENT_ACCOUNT_ID_ECDSA_1: "0.0.1328" + CLIENT_EVM_ADDRESS_ECDSA_1_CORRECT: "0x97C50bb12E1C6284cF2855cdba95c5D60AEE44CF" + CLIENT_EVM_ADDRESS_ECDSA_1: "0x0000000000000000000000000000000000000530" CLIENT_PRIVATE_KEY_ECDSA_2: ${{ secrets.CLIENT_PRIVATE_KEY_ECDSA_2 }} CLIENT_PUBLIC_KEY_ECDSA_2: ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }} - CLIENT_ACCOUNT_ID_ECDSA_2: '0.0.2168740' - CLIENT_EVM_ADDRESS_ECDSA_2: '0x00000000000000000000000000000000002117A4' - FACTORY_ADDRESS: '0.0.5480051' - RESOLVER_ADDRESS: '0.0.5479997' - FIREBLOCKS_HEDERA_ACCOUNT_ID: '0.0.2168740' + CLIENT_ACCOUNT_ID_ECDSA_2: "0.0.2168740" + CLIENT_EVM_ADDRESS_ECDSA_2: "0x00000000000000000000000000000000002117A4" + FACTORY_ADDRESS: "0.0.5480051" + RESOLVER_ADDRESS: "0.0.5479997" + FIREBLOCKS_HEDERA_ACCOUNT_ID: "0.0.2168740" FIREBLOCKS_HEDERA_PUBLIC_KEY: ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }} - DFNS_HEDERA_ACCOUNT_ID: '0.0.2168740' + DFNS_HEDERA_ACCOUNT_ID: "0.0.2168740" DFNS_WALLET_PUBLIC_KEY: ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }} - AWS_KMS_HEDERA_ACCOUNT_ID: '0.0.4394946' - AWS_KMS_HEDERA_PUBLIC_KEY: '302d300706052b8104000a03220003ee815bb9b5e53f5dbe7264a77e586127dfcb75da8c1246f5aa6ededdb13e6c21' - REACT_APP_MIRROR_NODE: 'https://testnet.mirrornode.hedera.com/api/v1/' - REACT_APP_RPC_NODE: 'https://testnet.hashio.io/api' - REACT_APP_RESOLVER: '0.0.5479997' - REACT_APP_FACTORY: '0.0.5480051' - REACT_APP_SHOW_DISCLAIMER: 'true' + AWS_KMS_HEDERA_ACCOUNT_ID: "0.0.4394946" + AWS_KMS_HEDERA_PUBLIC_KEY: "302d300706052b8104000a03220003ee815bb9b5e53f5dbe7264a77e586127dfcb75da8c1246f5aa6ededdb13e6c21" + REACT_APP_MIRROR_NODE: "https://testnet.mirrornode.hedera.com/api/v1/" + REACT_APP_RPC_NODE: "https://testnet.hashio.io/api" + REACT_APP_RESOLVER: "0.0.5479997" + REACT_APP_FACTORY: "0.0.5480051" + REACT_APP_SHOW_DISCLAIMER: "true" CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} steps: @@ -59,7 +59,7 @@ jobs: - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.x + node-version: 22.20.0 - name: Install dependencies run: npm ci diff --git a/.github/workflows/changeset-check.yml b/.github/workflows/changeset-check.yml new file mode 100644 index 000000000..b50461362 --- /dev/null +++ b/.github/workflows/changeset-check.yml @@ -0,0 +1,115 @@ +name: Changeset Check + +on: + pull_request: + branches: + - develop + types: + - opened + - synchronize + - reopened + - labeled + - unlabeled + +permissions: + contents: read + pull-requests: read + +jobs: + check-changeset: + name: Validate Changeset Required + runs-on: token-studio-linux-large + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + # Ensure we have the develop branch for comparison + ref: ${{ github.head_ref }} + + - name: Fetch develop branch + run: | + git fetch origin develop:develop || git fetch origin main:develop || true + git branch -a + + - name: Setup NodeJS Environment + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22.20.0 + + - name: Check for bypass labels + id: bypass + env: + GH_TOKEN: ${{ github.token }} + run: | + LABELS=$(gh pr view ${{ github.event.number }} --json labels --jq '.labels[].name' || echo "") + if echo "${LABELS}" | grep -E "(no-changeset|docs-only|hotfix|chore)" > /dev/null; then + echo "bypass=true" >> "${GITHUB_OUTPUT}" + echo "✅ Found bypass label. Skipping changeset check." + else + echo "bypass=false" >> "${GITHUB_OUTPUT}" + echo "🔍 No bypass labels found. Changeset check required." + fi + + - name: Install dependencies + if: ${{ steps.bypass.outputs.bypass == 'false' }} + run: npm ci + + - name: Check changeset status + if: ${{ steps.bypass.outputs.bypass == 'false' }} + run: | + echo "🔍 Checking for NEW changesets in this PR..." + + NEW_CHANGESETS=$(git diff develop...HEAD --name-only --diff-filter=A | grep "^\.changeset/.*\.md$" | grep -v "README.md" || true) + NEW_CHANGESET_COUNT=$(echo "${NEW_CHANGESETS}" | grep -c "\.md$" || echo "0") + + echo "Files changed in PR:" + git diff develop...HEAD --name-only --diff-filter=A | head -10 + echo "" + echo "NEW changeset files in this PR: ${NEW_CHANGESET_COUNT}" + if [ -n "${NEW_CHANGESETS}" ]; then + echo "Found NEW changesets:" + echo "${NEW_CHANGESETS}" + fi + + if [[ "${NEW_CHANGESET_COUNT}" -gt 0 ]]; then + echo "✅ Changeset validation passed - found NEW changeset files in PR" + else + echo "" + echo "❌ NEW CHANGESET REQUIRED" + echo "" + echo "This PR requires a NEW changeset to document the changes." + echo "We found no new .changeset/*.md files introduced by this PR." + echo "" + echo "To create a changeset:" + echo "1. Run: npm run changeset" + echo "2. Select the packages that changed" + echo "3. Choose the change type (patch/minor/major)" + echo "4. Write a description of your changes" + echo "5. Commit the generated .changeset/*.md file" + echo "" + echo "To bypass this check (for docs/chore changes only):" + echo "Add one of these labels to the PR:" + echo "- no-changeset: For pure documentation or config changes" + echo "- docs-only: For documentation-only changes" + echo "- chore: For build system or dependency updates" + echo "- hotfix: For emergency fixes" + echo "" + echo "More info: https://github.com/changesets/changesets/blob/main/docs/intro-to-using-changesets.md" + exit 1 + fi + + - name: Success summary + if: ${{ always() }} + run: | + if [ "${{ steps.bypass.outputs.bypass }}" = "true" ]; then + echo "✅ Changeset check bypassed due to label" + else + echo "✅ Changeset validation completed successfully" + fi diff --git a/.github/workflows/mp.publish.yml b/.github/workflows/mp.publish.yml new file mode 100644 index 000000000..e9bb5f83e --- /dev/null +++ b/.github/workflows/mp.publish.yml @@ -0,0 +1,122 @@ +name: Mass Payout Publish + +on: + # Manual trigger with dry-run option + workflow_dispatch: + inputs: + dry-run-enabled: + description: "Run npm publish with dry-run flag" + required: false + type: boolean + default: false + + # Tag push trigger - simpler and automatic (no need to create GitHub release) + push: + tags: + - "v*-mp" + - "v*-MP" + +defaults: + run: + shell: bash + +permissions: + contents: read + id-token: write + +jobs: + mass-payout: + name: Publish Mass Payout Packages + runs-on: token-studio-linux-large + # Only run if manual trigger OR tag push (already filtered by v*-mp pattern) + if: ${{ github.event_name == 'workflow_dispatch' || github.event_name == 'push' }} + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ github.ref }} + fetch-depth: 0 + + - name: Setup NodeJS Environment + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22.20.0 + registry-url: https://registry.npmjs.org + + - name: Create .npmrc file + run: | + cat << 'EOF' > .npmrc + //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} + EOF + + - name: Install dependencies + run: npm ci + + - name: Install NestJS CLI globally + run: npm install -g @nestjs/cli + + - name: Build Mass Payout packages + run: npm run mass-payout:build + + - name: Publish Mass Payout packages + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + DRY_RUN: ${{ inputs.dry-run-enabled }} + run: | + for package_dir in packages/mass-payout/*/; do + if [ -d "${package_dir}" ] && [ -f "${package_dir}package.json" ]; then + package_name=$(basename "${package_dir}") + echo "📦 Processing Mass Payout package: ${package_name}" + + cd "${package_dir}" + + if ! node -p "require('./package.json').private || false" | grep -q "true"; then + PUBLISH_ARGS=("--access=restricted") + if [[ "${DRY_RUN}" == "true" ]]; then + PUBLISH_ARGS+=("--dry-run") + echo "🔍 DRY RUN MODE: Would publish @hashgraph/mass-payout-${package_name}" + fi + + if ! npm publish "${PUBLISH_ARGS[@]}"; then + echo "❌ Failed to publish package: ${package_name}" + echo "📋 Package info:" && cat package.json | jq '.name, .version' + exit 1 + fi + else + echo "⏭️ Skipping private package: ${package_name}" + fi + + cd - > /dev/null + fi + done + + # Summary job to report results + summary: + name: Publish Summary + runs-on: token-studio-linux-large + needs: + - mass-payout + if: ${{ always() }} + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1 + with: + egress-policy: audit + + - name: Report Results + run: | + echo "## Mass Payout Publish Results" >> "${GITHUB_STEP_SUMMARY}" + echo "| Package Type | Status |" >> "${GITHUB_STEP_SUMMARY}" + echo "| --- | --- |" >> "${GITHUB_STEP_SUMMARY}" + echo "| Mass Payout | ${{ needs.mass-payout.result }} |" >> "${GITHUB_STEP_SUMMARY}" + + if [[ "${{ inputs.dry-run-enabled }}" == "true" ]]; then + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "🔍 **DRY RUN MODE** - No packages were actually published" >> "${GITHUB_STEP_SUMMARY}" + fi diff --git a/.github/workflows/mp.release.yml b/.github/workflows/mp.release.yml new file mode 100644 index 000000000..82eea2dea --- /dev/null +++ b/.github/workflows/mp.release.yml @@ -0,0 +1,154 @@ +name: Mass Payout Release + +on: + # Manual trigger with preview/release option + workflow_dispatch: + inputs: + release-type: + description: "Type of release to perform" + required: true + type: choice + options: + - preview # Show what would be released (dry-run) + - release # Full production release + default: "preview" + +defaults: + run: + shell: bash + +permissions: + contents: write # For creating commits and tags + id-token: write + +jobs: + mp-release: + name: Create Mass Payout Release + runs-on: token-studio-linux-large + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + # Use GitHub App token to bypass branch protection + token: ${{ secrets.GITHUB_TOKEN }} + fetch-depth: 0 + + - name: Setup NodeJS Environment + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version: 22.20.0 + + - name: Install dependencies + run: npm ci + + - name: Validate Mass Payout changesets exist + id: validate + run: | + echo "📋 Getting changeset status..." + npx changeset status --output=changeset-status.json + + MP_PACKAGES_TO_BUMP=$(jq -r '.releases[] | select(.name | test("@hashgraph/mass-payout")) | .name' changeset-status.json | wc -l) + + echo "mp-packages-to-bump=${MP_PACKAGES_TO_BUMP}" >> "${GITHUB_OUTPUT}" + + if [ "${MP_PACKAGES_TO_BUMP}" -eq 0 ]; then + echo "❌ No Mass Payout packages found to be bumped" + echo "📋 Current changeset status:" + npx changeset status + exit 1 + fi + + echo "✅ Found ${MP_PACKAGES_TO_BUMP} Mass Payout package(s) ready for release" + + echo "📦 Mass Payout packages to be released:" + jq -r '.releases[] | select(.name | test("@hashgraph/mass-payout")) | " - \(.name) (\(.oldVersion) → \(.newVersion))"' changeset-status.json + + - name: Preview Mass Payout release + if: ${{ inputs.release-type == 'preview' }} + run: | + echo "🔍 PREVIEW MODE - What would be released for Mass Payout packages:" + echo "" + echo "📋 Current changeset status:" + npx changeset status + echo "" + echo "🚫 ATS packages would be ignored during Mass Payout release" + echo "🎯 Only @hashgraph/mass-payout* packages would be processed" + echo "" + echo "To proceed with actual release, run this workflow with 'release' option." + + - name: Version Mass Payout packages + if: ${{ inputs.release-type == 'release' }} + run: | + echo "🚀 Releasing Mass Payout packages only (ignoring ATS packages)" + + npx changeset version --ignore "@hashgraph/asset-tokenization-*" + + if [[ -n "$(git status --porcelain)" ]]; then + echo "✅ Version bump completed for Mass Payout packages" + else + echo "❌ No version changes detected" + exit 1 + fi + + - name: Commit version changes + if: ${{ inputs.release-type == 'release' }} + run: | + git add . + + if git commit --signoff -S -m "chore: release Mass Payout packages"; then + echo "✅ Version changes committed" + else + echo "ℹ️ No changes to commit" + fi + + - name: Create Mass Payout release + id: create-mp-release-tag + if: ${{ inputs.release-type == 'release' }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + MP_VERSION=$(node -p "require('./packages/mass-payout/core/package.json').version" 2>/dev/null || echo "1.0.0") + TAG_NAME="v${MP_VERSION}-mp" + echo "📦 Creating Mass Payout release: ${TAG_NAME}" + git tag -s -a "${TAG_NAME}" -m "Creating Mass Payout Release with tag: ${TAG_NAME}" + git push origin "${TAG_NAME}" + + echo "release-tag=${TAG_NAME}" >> "${GITHUB_OUTPUT}" + + - name: Create github release + if: ${{ inputs.release-type == 'release' }} + uses: step-security/release-action@03a57407052f15d1537fd5469a6fbbc536aba326 # v1.20.0 + with: + tag: ${{ steps.create-mp-release-tag.outputs.release-tag }} + prerelease: false + draft: false + generateReleaseNotes: true + skipIfReleaseExists: true + + - name: Release Summary + if: ${{ always() }} + run: | + if [ "${{ inputs.release-type }}" = "preview" ]; then + echo "## 🔍 Mass Payout Release Preview Completed" >> "${GITHUB_STEP_SUMMARY}" + echo "Preview mode was selected. No actual release was created." >> "${GITHUB_STEP_SUMMARY}" + elif [ "${{ job.status }}" = "success" ]; then + MP_VERSION=$(node -p "require('./packages/mass-payout/core/package.json').version" 2>/dev/null || echo "unknown") + echo "## ✅ Mass Payout Release v${MP_VERSION} Completed Successfully" >> "${GITHUB_STEP_SUMMARY}" + echo "| Package | Status |" >> "${GITHUB_STEP_SUMMARY}" + echo "| --- | --- |" >> "${GITHUB_STEP_SUMMARY}" + echo "| Mass Payout Packages | ✅ Released |" >> "${GITHUB_STEP_SUMMARY}" + echo "| GitHub Release | ✅ Created |" >> "${GITHUB_STEP_SUMMARY}" + echo "" >> "${GITHUB_STEP_SUMMARY}" + echo "**Next Steps:**" >> "${GITHUB_STEP_SUMMARY}" + echo "- NPM publishing will be triggered automatically via mp.publish.yml" >> "${GITHUB_STEP_SUMMARY}" + echo "- ATS packages were ignored and remain available for separate release" >> "${GITHUB_STEP_SUMMARY}" + else + echo "## ❌ Mass Payout Release Failed" >> "${GITHUB_STEP_SUMMARY}" + echo "Check the logs above for details on what went wrong." >> "${GITHUB_STEP_SUMMARY}" + fi diff --git a/.github/workflows/mp.test.yml b/.github/workflows/mp.test.yml index 97c0cb3f4..41e67f6d4 100644 --- a/.github/workflows/mp.test.yml +++ b/.github/workflows/mp.test.yml @@ -5,11 +5,11 @@ on: branches: [main] pull_request: paths: - - 'packages/mass-payout/**' - - 'apps/mass-payout/**' - - 'package.json' - - '.github/workflows/*mp*.yml' - - '.github/workflows/*mp*.yaml' + - "packages/mass-payout/**" + - "apps/mass-payout/**" + - "package.json" + - ".github/workflows/*mp*.yml" + - ".github/workflows/*mp*.yaml" workflow_dispatch: permissions: @@ -20,31 +20,31 @@ jobs: name: testing runs-on: token-studio-linux-large env: - NODE_OPTIONS: '--max-old-space-size=32768' - CONTRACT_SIZER_RUN_ON_COMPILE: 'false' - REPORT_GAS: 'false' + NODE_OPTIONS: "--max-old-space-size=32768" + CONTRACT_SIZER_RUN_ON_COMPILE: "false" + REPORT_GAS: "false" CLIENT_PRIVATE_KEY_ECDSA_1: ${{ secrets.CLIENT_PRIVATE_KEY_ECDSA_1 }} CLIENT_PUBLIC_KEY_ECDSA_1: ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_1 }} - CLIENT_ACCOUNT_ID_ECDSA_1: '0.0.1328' - CLIENT_EVM_ADDRESS_ECDSA_1_CORRECT: '0x97C50bb12E1C6284cF2855cdba95c5D60AEE44CF' - CLIENT_EVM_ADDRESS_ECDSA_1: '0x0000000000000000000000000000000000000530' + CLIENT_ACCOUNT_ID_ECDSA_1: "0.0.1328" + CLIENT_EVM_ADDRESS_ECDSA_1_CORRECT: "0x97C50bb12E1C6284cF2855cdba95c5D60AEE44CF" + CLIENT_EVM_ADDRESS_ECDSA_1: "0x0000000000000000000000000000000000000530" CLIENT_PRIVATE_KEY_ECDSA_2: ${{ secrets.CLIENT_PRIVATE_KEY_ECDSA_2 }} CLIENT_PUBLIC_KEY_ECDSA_2: ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }} - CLIENT_ACCOUNT_ID_ECDSA_2: '0.0.2168740' - CLIENT_EVM_ADDRESS_ECDSA_2: '0x00000000000000000000000000000000002117A4' - FACTORY_ADDRESS: '0.0.5480051' - RESOLVER_ADDRESS: '0.0.5479997' - FIREBLOCKS_HEDERA_ACCOUNT_ID: '0.0.2168740' + CLIENT_ACCOUNT_ID_ECDSA_2: "0.0.2168740" + CLIENT_EVM_ADDRESS_ECDSA_2: "0x00000000000000000000000000000000002117A4" + FACTORY_ADDRESS: "0.0.5480051" + RESOLVER_ADDRESS: "0.0.5479997" + FIREBLOCKS_HEDERA_ACCOUNT_ID: "0.0.2168740" FIREBLOCKS_HEDERA_PUBLIC_KEY: ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }} - DFNS_HEDERA_ACCOUNT_ID: '0.0.2168740' + DFNS_HEDERA_ACCOUNT_ID: "0.0.2168740" DFNS_WALLET_PUBLIC_KEY: ${{ secrets.CLIENT_PUBLIC_KEY_ECDSA_2 }} - AWS_KMS_HEDERA_ACCOUNT_ID: '0.0.4394946' - AWS_KMS_HEDERA_PUBLIC_KEY: '302d300706052b8104000a03220003ee815bb9b5e53f5dbe7264a77e586127dfcb75da8c1246f5aa6ededdb13e6c21' - REACT_APP_MIRROR_NODE: 'https://testnet.mirrornode.hedera.com/api/v1/' - REACT_APP_RPC_NODE: 'https://testnet.hashio.io/api' - REACT_APP_RESOLVER: '0.0.5479997' - REACT_APP_FACTORY: '0.0.5480051' - REACT_APP_SHOW_DISCLAIMER: 'true' + AWS_KMS_HEDERA_ACCOUNT_ID: "0.0.4394946" + AWS_KMS_HEDERA_PUBLIC_KEY: "302d300706052b8104000a03220003ee815bb9b5e53f5dbe7264a77e586127dfcb75da8c1246f5aa6ededdb13e6c21" + REACT_APP_MIRROR_NODE: "https://testnet.mirrornode.hedera.com/api/v1/" + REACT_APP_RPC_NODE: "https://testnet.hashio.io/api" + REACT_APP_RESOLVER: "0.0.5479997" + REACT_APP_FACTORY: "0.0.5480051" + REACT_APP_SHOW_DISCLAIMER: "true" CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} steps: @@ -59,13 +59,16 @@ jobs: - name: Setup NodeJS Environment uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: 22.x + node-version: 22.20.0 - name: Install dependencies run: npm ci - # - name: Build mass-payout - # run: npm run mp:build + - name: Install NestJS CLI globally + run: npm install -g @nestjs/cli - # - name: Test mass-payout - # run: npm run mp:test + - name: Build mass-payout + run: npm run mass-payout:build + + - name: Test mass-payout + run: npm run mass-payout:test diff --git a/.gitignore b/.gitignore index 85fb6c4b4..19628de72 100644 --- a/.gitignore +++ b/.gitignore @@ -135,7 +135,5 @@ asset-tokenization-studio.iml # AI files .kiro/ +.claude/ CLAUDE.md - -# Extracted methods from contracts -contracts/extracted-methods.txt diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 37e918e45..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - // Force Prettier as default formatter for all, and specifically for file types - "editor.defaultFormatter": "esbenp.prettier-vscode", - "[json]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - "editor.tabSize": 2, - "editor.insertSpaces": true - }, - "[jsonc]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true, - "editor.tabSize": 2, - "editor.insertSpaces": true - }, - "[solidity]": { - "editor.defaultFormatter": "esbenp.prettier-vscode", - "editor.formatOnSave": true - }, - // Avoid VS Code built-in or other extensions re-formatting - "editor.formatOnSave": true, - // Ensure any other formatters (like solidity language server) do not auto format on save - "solidity.formatter": "prettier", // for JuanBlanco.solidity extension - "solidity.compileUsingRemoteVersion": "v0.8.18+commit.87f61d96", - // Consistent tab size override for Solidity if needed (Prettier overrides with its config anyway) - "[solidity][*.sol]": { - "editor.tabSize": 4 - }, - // Respect EditorConfig but Prettier should take precedence on format run - "editor.useEditorConfig": true, - // Configure Prettier settings to match prettier.config.mjs - "prettier.tabWidth": 2, - "prettier.useTabs": false, - "prettier.semi": true, - "prettier.singleQuote": true, - "prettier.trailingComma": "all", - "prettier.bracketSpacing": true, - "prettier.printWidth": 80, - // Disable any ESLint format on save to avoid double-format passes; rely on Prettier only - "editor.codeActionsOnSave": { - // Keep ESLint fix separate; if you want ESLint fixes too, set to "explicit" or true, but avoid formatting flip-flop - // "source.fixAll.eslint": "explicit" - } -} diff --git a/README.md b/README.md index ad746dd10..752545ceb 100644 --- a/README.md +++ b/README.md @@ -6,337 +6,206 @@ -### Table of Contents - -- **[Development manifesto](#development-manifesto)**
-- **[Prerequisites](#prerequisites)**
-- **[Installation](#installation)**
-- **[Workspace Overview](#workspace-overview)**
-- **[Build](#build)**
-- **[Setting Up the Environment](#setting-up-the-environment)**
- - **[Required Environment Variables](#required-environment-variables)**
- - **[Optional Environment Variables (Hedera Wallet Connect)](#optional-environment-variables-hedera-wallet-connect)**
- - **[Steps to set up the `.env` file](#steps-to-set-up-the-env-file)**
-- **[Run](#run)**
-- **[Support](#support)**
-- **[Contributing](#contributing)**
-- **[Code of conduct](#code-of-conduct)**
-- **[License](#license)**
- -# Description - -Asset Tokenization Studio (ATS) is a suite designed to enable the creation, management, and trading of security tokens on the Hedera network. - -The ATS facilitates the tokenization of traditional financial assets (equities and bonds) onto the Hedera distributed ledger, providing a framework for: - -- Creating and deploying security tokens -- Managing token lifecycles -- Implementing compliance and regulatory requirements -- Enabling secure token transfers and operations +## Introduction -## Monorepo Structure - -The project is organized as a monorepo using npm workspaces: - -``` -├── packages/ # Core packages -│ ├── ats/ -│ │ ├── contracts/ # Smart contracts deployed on Hedera -│ │ └── sdk/ # TypeScript SDK for contract interaction -│ └── mass-payout/ # Mass payout functionality -├── apps/ # Applications -│ ├── ats/ -│ │ └── web/ # React web application -│ └── mass-payout/ # Mass payout app -└── package.json # Root workspace configuration -``` +The **Asset Tokenization Studio (ATS) Monorepo** provides a unified environment to design, deploy, and operate tokenized financial assets on the **Hedera network**, as well as to manage **large-scale payout distributions**. -The ATS consists of three primary components that work together to provide a complete tokenization solution: +It brings together two complementary suites: -- **Smart Contracts** (`packages/ats/contracts`) - The on-chain components deployed on the Hedera network -- **SDK** (`packages/ats/sdk`) - A software development kit that provides programmatic access to the contracts -- **Web Application** (`apps/ats/web`) - A user interface for interacting with the tokenized assets +- **Asset Tokenization Studio (ATS):** Tools for creating, managing, and interacting with **security tokens** (equities and bonds) that comply with enterprise-grade standards. +- **Scheduler Payment Distribution (Mass Payout):** Infrastructure to execute **batch payments** (e.g., dividends, bond coupons, recurring obligations) efficiently across thousands of accounts. -The standard ERC for security tokens used in the smart contracts is ERC1400. +This monorepo is structured with **npm workspaces** and is designed for scalability, modularity, and enterprise adoption. -Version 1.15.0 introduces partial compatibility with the ERC-3643 (TREX) standard; full support will follow in upcoming releases. +--- -# Development manifesto +## Key Features -The development of the project follows enterprise-grade practices for software development. Using DDD, hexagonal architecture, and the CQS pattern, all within an agile methodology. +- **Tokenization Framework** + - Security tokens compliant with **ERC-1400** and partial support for **ERC-3643 (T-REX)**. + - Modular **diamond pattern architecture** for upgradeability. + - Identity registry, compliance modules, and granular freeze controls. + - Role-based access control with administrative and operational roles. -## Domain driven design +- **Mass Payout Framework** + - Batch operations optimized for large-scale distributions. + - Supports both **HBAR** and **HTS tokens**. + - Lifecycle cash flow management for recurring obligations. + - Gas-optimized operations and proxy-based upgradeable contracts. -By using DDD (Domain-Driven Design), we aim to create a shared language among all members of the project team, which allows us to focus our development efforts on thoroughly understanding the processes and rules of the domain. This helps to bring benefits such as increased efficiency and improved communication. +- **Enterprise Development Practices** + - **Domain-Driven Design (DDD)**, **Hexagonal Architecture**, and **CQS pattern**. + - Separation of concerns across smart contracts, SDKs, frontends, and backends. + - Strong CI/CD workflows with conditional builds and tests for each module. + - Custodian integration at the SDK level (Dfns, Fireblocks, AWS KMS). -## Token Standards Support +## Monorepo Structure -The Asset Tokenization Studio supports multiple security token standards: +``` +├── packages/ +│ ├── ats/ +│ │ ├── contracts # Solidity smart contracts for ATS +│ │ └── sdk # TypeScript SDK for ATS contracts +│ └── mass-payout/ +│ ├── contracts # Solidity smart contracts for payout flows +│ └── sdk # TypeScript SDK for payout flows +├── apps/ +│ ├── ats/ +│ │ └── web # Frontend dApp for Asset Tokenization Studio +│ └── mass-payout/ +│ ├── backend # API backend for payout orchestration +│ └── frontend # Admin panel for managing payouts +└── package.json # Workspace configuration and root scripts +``` -- **ERC1400**: Core security token standard with partition-based token management -- **ERC3643 (T-REX)**: Advanced compliance framework with identity registry, compliance modules, and sophisticated freeze capabilities +## Architecture + +### High-Level Overview + +```mermaid +flowchart TD + subgraph Users + U1[Investor] + U2[Issuer] + U3[Admin] + end + + subgraph ATS + W[Web App React] + S[SDK TypeScript] + C[Smart Contracts ERC-1400 / ERC-3643] + end + + subgraph MassPayout + F[Frontend Admin Panel] + B[Backend API NestJS + PostgreSQL] + MP[Mass Payout Contracts] + end + + subgraph Hedera + H1[(Mirror Node)] + H2[(RPC Node)] + end + + U1 <--> W + U2 <--> W + U3 <--> F + + W <--> S + F <--> B + S <--> C + B <--> MP + + C <--> H1 + C <--> H2 + MP <--> H1 + MP <--> H2 +``` -# Prerequisites +## Installation & Setup -Ensure the following tools are installed: +### Prerequisites -- **Node:** v20.19.4 (LTS: Iron) or newer -- **NPM :** v10.8.2 or newer +- Node.js + - ATS requires v20.19.4 or newer + - Mass Payout backend requires v24.0.0 or newer +- npm v10.9.0 or newer +- PostgreSQL (for the Mass Payout backend) -# Installation +### Quick Setup -This project uses npm workspaces for dependency management. In a terminal at the root directory: +From the monorepo root: ```bash + +# Install all dependencies npm ci ``` -This will install all dependencies for all workspaces and automatically set up the links between packages. +```bash +# Build all packages and applications +npm run setup +``` -You can now start developing in any of the workspace modules. +This command will compile contracts, build SDKs, and set up web and backend environments. -# Workspace Overview +### Environment Configuration -This monorepo uses npm workspaces to manage dependencies and build processes across multiple packages and applications. +Each application has its own .env configuration file. -## Available Workspace Commands +- ATS Web App: apps/ats/web/.env.local + Defines Hedera endpoints, resolver and factory IDs, and WalletConnect settings. -### ATS (Asset Tokenization Studio) +- Mass Payout Backend: apps/mass-payout/backend/.env + Includes PostgreSQL connection and runtime configuration. -```bash -# Build commands -npm run ats:build # Build all ATS components -npm run ats:contracts:build # Build smart contracts only -npm run ats:sdk:build # Build SDK only -npm run ats:web:build # Build web app only - -# Test commands -npm run ats:test # Test all ATS components -npm run ats:contracts:test # Test contracts only -npm run ats:sdk:test # Test SDK only -npm run ats:web:test # Test web app only -npm run ats:test:ci # Run CI tests - -# Development commands -npm run ats:start # Build contracts/SDK and start web dev server -npm run ats:web:dev # Start web dev server only - -# Publishing (for maintainers) -npm run ats:publish # Publish contracts and SDK to npm -``` +- Mass Payout Frontend: apps/mass-payout/frontend/.env + Requires VITE_API_URL and VITE_PORT. -### Mass Payout (Placeholder) +Sample files are provided (.env.sample or .env.example) in each module. -```bash -npm run mass-payout:build # Build mass payout components -npm run mass-payout:test # Test mass payout components -npm run mass-payout:dev # Start mass payout development -``` +## Development Workflows -### Utility Commands +### ATS ```bash -npm run clean:deps # Remove all node_modules and lock files -npm run lint # Lint JavaScript and Solidity code -npm run format # Format code with Prettier +npm run ats:build # Build contracts, SDK, and web app +npm run ats:start # Start web app (with contracts & SDK built) +npm run ats:test # Run tests for all ATS modules ``` -## Workspace Dependencies +- Contracts (packages/ats/contracts) → Solidity, Hardhat, diamond pattern +- SDK (packages/ats/sdk) → TypeScript SDK for client and web integration +- Web App (apps/ats/web) → React 18 frontend for asset management -The workspaces have the following dependency relationships: +### Mass Payout -``` -packages/ats/contracts → (standalone) -packages/ats/sdk → depends on contracts -apps/ats/web → depends on SDK (and transitively contracts) +```bash +npm run mass-payout:build # Build contracts, SDK, backend, and frontend +npm run mass-payout:backend:dev # Start backend in dev mode +npm run mass-payout:frontend:dev # Start frontend in dev mode +npm run mass-payout:test # Run all payout-related tests ``` -When you run workspace commands, npm automatically handles building dependencies in the correct order. +- Contracts (packages/mass-payout/contracts) → Solidity payout contracts +- SDK (packages/mass-payout/sdk) → TypeScript SDK for payout execution +- Backend (apps/mass-payout/backend) → API with PostgreSQL +- Frontend (apps/mass-payout/frontend) → Admin panel in React + Chakra UI -# Build +## Testing -The project uses workspace-aware build commands. When making modifications to any module, rebuild the dependencies in the following order: +Run tests for all modules: ```bash -# Build all ATS components (recommended) -npm run ats:build - -# Or build individual components: -npm run ats:contracts:build # 1st - Smart contracts -npm run ats:sdk:build # 2nd - SDK (depends on contracts) -npm run ats:web:build # 3rd - Web app (depends on SDK) - -# Mass Payout (when available) -npm run mass-payout:build +npm run ats:test +npm run mass-payout:test ``` -# Setting Up the Environment - -To run the project, you'll need to configure environment variables in the `.env` file. Below are the required and optional variables, along with their descriptions. - -## Required Environment Variables - -### _General Settings_ - -- **`REACT_APP_EQUITY_CONFIG_ID`**: Configuration Id for Equities. -- **`REACT_APP_EQUITY_CONFIG_VERSION`**: Equity Version. -- **`REACT_APP_BOND_CONFIG_ID`**: configuration Id for Bonds. -- **`REACT_APP_BOND_CONFIG_VERSION`**: Bond Version. -- **`REACT_APP_SHOW_DISCLAIMER`**: Set this value to `"true"` to show a disclaimer in the application. - -### _Network Configuration_ +Each submodule provides additional test options (unit, e2e, coverage). -- **`REACT_APP_MIRROR_NODE`**: The URL of the Hedera Mirror Node API used to query historical data from the Hedera testnet. Example: `https://testnet.mirrornode.hedera.com/api/v1/` -- **`REACT_APP_RPC_NODE`**: The RPC node URL used to communicate with the Hedera testnet. Example: `https://testnet.hashio.io/api` -- **`REACT_APP_RPC_RESOLVER`**: The Hedera testnet account ID for the resolver. Example: `0.0.5479997` -- **`REACT_APP_RPC_FACTORY`**: The Hedera testnet account ID for the factory. Example: `0.0.5480051` +## Architecture Highlights -## Optional Environment Variables (Hedera Wallet Connect) +### Smart Contracts -These variables are only required if you are integrating Hedera Wallet Connect for decentralized application (dApp) interactions. If not needed, they can be omitted. +- Diamond pattern with modular facets (ERC-1400, ERC-3643, Hold, Clearing) +- Role-based access control with fine-grained permissions -- **`REACT_APP_PROJECT_ID`**: Project ID for Wallet Connect integration. You can obtain it from the [WalletConnect website](https://walletconnect.com/). -- **`REACT_APP_DAPP_NAME`**: The name of your dApp as displayed in Wallet Connect. -- **`REACT_APP_DAPP_DESCRIPTION`**: A description of your dApp, typically displayed in Wallet Connect. -- **`REACT_APP_DAPP_URL`**: The URL of your dApp that will be referenced in Wallet Connect. -- **`REACT_APP_DAPP_ICONS`**: An array of URLs pointing to icons for the dApp, typically used in Wallet Connect interfaces. Example: `['https://stablecoinstudio.com/static/media/hedera-hbar-logo.4fd73fb360de0fc15d378e0c3ebe6c80.svg']` +### SDKs -## Steps to set up the `.env` file: +- TypeScript APIs for deploying and managing securities, payouts, compliance, and lifecycle events +- Batch operations for minting, burning, freezing, and payouts -1. Navigate to the `apps/ats/web` directory. -2. Copy the `.env.sample` file to create a new `.env` file: +### Applications - ```bash - cp .env.sample .env - ``` - -3. Open the `.env` file in your preferred text editor. -4. Replace the placeholder values with your actual environment settings. For example: - - ```bash - REACT_APP_EQUITY_CONFIG_ID='0x0000000000000000000000000000000000000000000000000000000000000001' - REACT_APP_EQUITY_CONFIG_VERSION="0" - REACT_APP_BOND_CONFIG_ID="0x0000000000000000000000000000000000000000000000000000000000000002" - REACT_APP_BOND_CONFIG_VERSION="0" - REACT_APP_SHOW_DISCLAIMER="true" - - REACT_APP_MIRROR_NODE="https://testnet.mirrornode.hedera.com/api/v1/" - REACT_APP_RPC_NODE="https://testnet.hashio.io/api" - REACT_APP_RPC_RESOLVER='0.0.6457760' - REACT_APP_RPC_FACTORY='0.0.6457855' - - REACT_APP_PROJECT_ID="your_project_id_from_walletconnect" - REACT_APP_DAPP_NAME="Asset Tokenization Studio" - REACT_APP_DAPP_DESCRIPTION="Asset Tokenization Studio. Built on Hedera Hashgraph." - REACT_APP_DAPP_URL="https://wc.ats.com/" - REACT_APP_DAPP_ICONS='["https://stablecoinstudio.com/static/media/hedera-hbar-logo.4fd73fb360de0fc15d378e0c3ebe6c80.svg"]' - ``` - -5. Save the file and proceed with running the application. - -## Critical Setup Recommendation for Optimal Performance - -For the best experience, we strongly recommend installing the [hiero-json-rpc-relay](https://github.com/hiero-ledger/hiero-json-rpc-relay/tree/main) on your local machine. The hashio API (`REACT_APP_RPC_NODE="https://testnet.hashio.io/api"`) has rate limits that may cause errors during operations. By setting up the relay locally, you can replace the `REACT_APP_RPC_NODE` environment variable with a local endpoint (e.g., `REACT_APP_RPC_NODE="http://localhost:7546"`) to ensure stable and uninterrupted performance. - -## Key Features +- **ATS Web**: dApp for asset issuance and management +- **Mass Payout Backend**: Orchestrates scheduled payouts +- **Mass Payout Frontend**: Admin dashboard for payout monitoring -### ERC3643 Compliance Framework +### Integrations -The platform now includes comprehensive ERC3643 (T-REX) support featuring: - -- **Identity Registry**: Manage investor identities and compliance status -- **Compliance Module**: Configurable compliance rules and restrictions -- **Advanced Freeze Capabilities**: Partial token freezing and address-level freeze controls -- **Agent Management**: Dedicated agent roles for compliance operations -- **Batch Operations**: Efficient batch transfers, mints, burns, and freeze operations -- **Recovery Address**: Account recovery mechanisms for lost access scenarios - -### Enhanced Token Operations - -- **Forced Transfers**: Controller-initiated transfers for regulatory compliance -- **Batch Processing**: Multiple operations in single transactions for gas efficiency -- **Granular Freeze Controls**: Freeze specific amounts or entire addresses -- **Token Metadata Management**: On-chain token name, symbol, and metadata updates - -## Custodian Integration - -The ATS project utilizes a `custodians` library to facilitate interactions with various external custody providers. - -The integration with custodian services is **available at the SDK level only**, that means that the current implementation does not support direct dApp integration workflows and is limited to SDK tests right now. You can use your custodian providers using the .env file ([.env.sample](./sdk/.env.sample)). - -At the time the integration was first built, the SDKs provided by Dfns and Fireblocks did not yet support direct dApp integration workflows. Consequently, the current implementation focuses solely on SDK-based operations. - -### Supported Custodians and SDK Versions - -The following custody providers are supported through their respective SDKs within the ATS `custodians` library: - -- **Dfns:** SDK Version `0.1.0-beta.5` -- **Fireblocks:** SDK Version `5.11.0` -- **AWS KMS:** AWS SDK Version `3.624.0` - -For further details or assistance regarding the custodian integration, please consult the relevant source code within the SDK or reach out to the development team. [Custodians Library](https://github.com/hashgraph/hedera-custodians-library) - -# Run - -To run the application locally: - -- Clone the repository -- Install dependencies as described in the _Installation_ section: `npm ci` -- Create a ".env" file in the `apps/ats/web` directory (using the ".env.sample" file as a template) -- Run the application using one of these commands: - - ```bash - # Start the full ATS application (builds contracts & SDK, then starts web dev server) - npm start - # or - npm run ats:start - - # For development of the web app only (assumes contracts & SDK are already built) - npm run ats:web:dev - ``` - -- Open a browser and navigate to the URL displayed in the terminal (by default: _http://localhost:5173_) - -## Development Workflows - -### Full Development Setup - -```bash -# Option 1: Quick setup (install dependencies and build all ATS components) -npm run ats:setup # Install dependencies and build all ATS components -npm run ats:web:dev # Start web development server - -# Option 2: Step by step -npm ci # Install all dependencies -npm run ats:build # Build contracts and SDK -npm run ats:web:dev # Start web development server -``` - -### Running Tests - -```bash -# Test all ATS components -npm run ats:test - -# Test individual components -npm run ats:contracts:test -npm run ats:sdk:test -npm run ats:web:test - -# CI testing -npm run ats:test:ci -``` - -### Clean and Rebuild - -```bash -# Clean all build artifacts -npm run ats:clean - -# Clean dependencies (nuclear option) -npm run clean:deps -npm ci -``` +- Hedera Mirror Node and RPC Node +- WalletConnect for dApp integration +- Custodian libraries: Dfns, Fireblocks, AWS KMS ## Continuous Integration @@ -348,28 +217,28 @@ The project uses separate GitHub Actions workflows for different components: Tests are automatically triggered only when relevant files are modified, improving CI efficiency. -# Support +## Support If you have a question on how to use the product, please see our [support guide](https://github.com/hashgraph/.github/blob/main/SUPPORT.md). -# Contributing +## Contributing Contributions are welcome. Please see the [contributing guide](https://github.com/hashgraph/.github/blob/main/CONTRIBUTING.md) to see how you can get involved. -# Code of conduct +## Code of conduct This project is governed by the [Contributor Covenant Code of Conduct](https://github.com/hashgraph/.github/blob/main/CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to [oss@hedera.com](mailto:oss@hedera.com). -# License +## License [Apache License 2.0](LICENSE) -# 🔐 Security +## Security Please do not file a public ticket mentioning the vulnerability. Refer to the security policy defined in the [SECURITY.md](https://github.com/hashgraph/assettokenization-studio/blob/main/SECURITY.md). diff --git a/apps/ats/web/.env.sample b/apps/ats/web/.env.sample index d8250d8fe..303b1aaa4 100644 --- a/apps/ats/web/.env.sample +++ b/apps/ats/web/.env.sample @@ -8,8 +8,8 @@ REACT_APP_SHOW_DISCLAIMER="true" # * Network Configuration REACT_APP_MIRROR_NODE='https://testnet.mirrornode.hedera.com/api/v1/' REACT_APP_RPC_NODE='https://testnet.hashio.io/api' -REACT_APP_RPC_RESOLVER='0.0.6574176' -REACT_APP_RPC_FACTORY='0.0.6574245' +REACT_APP_RPC_RESOLVER='0.0.6797832' +REACT_APP_RPC_FACTORY='0.0.6797955' # * Hedera Wallet Connnect REACT_APP_PROJECT_ID='1a2b3c4d [...] 9a0b1c2d3e4f' diff --git a/apps/ats/web/.gitignore b/apps/ats/web/.gitignore deleted file mode 100644 index c1e66e955..000000000 --- a/apps/ats/web/.gitignore +++ /dev/null @@ -1,27 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -# dependencies -node_modules -dist -dist-ssr -*.local - -# misc -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/apps/ats/web/CHANGELOG.md b/apps/ats/web/CHANGELOG.md new file mode 100644 index 000000000..2cd8aab93 --- /dev/null +++ b/apps/ats/web/CHANGELOG.md @@ -0,0 +1,43 @@ +# @hashgraph/asset-tokenization-dapp + +## 1.17.0 + +### Minor Changes + +- a36b1c8: Integrate Changesets for version management and implement enterprise-grade release workflow + + #### Changesets Integration + - Add Changesets configuration with fixed versioning for ATS packages (contracts, SDK, dapp) + - Configure develop-branch strategy as base for version management + - Add comprehensive changeset management scripts: create, version, publish, status, snapshot + - Implement automated semantic versioning and changelog generation + - Add @changesets/cli dependency for modern monorepo version management + + #### Enterprise Release Workflow + - Implement new ats.publish.yml workflow focused exclusively on contracts and SDK packages + - Add manual trigger with dry-run capability for safe testing before actual releases + - Configure parallel execution of contracts and SDK publishing jobs for improved performance + - Support automatic triggers on version tags, release branches, and GitHub releases + - Add changeset validation workflow to enforce one changeset per PR requirement + - Include bypass labels for non-feature changes (no-changeset, docs-only, hotfix, chore) + + #### Repository Configuration + - Update .gitignore to properly track .github/ workflows while excluding build artifacts + - Remove deprecated all.publish.yml workflow in favor of focused ATS publishing + - Update package.json with complete changeset workflow scripts and release commands + - Enhance documentation with new version management workflow and enterprise practices + + #### Benefits + - **Modern Version Management**: Semantic versioning with automated changelog generation + - **Enterprise Compliance**: Manual release control with proper audit trails + - **Parallel Publishing**: Improved CI/CD performance with independent job execution + - **Developer Experience**: Simplified workflow with comprehensive documentation + - **Quality Assurance**: Mandatory changeset validation ensures all changes are documented + + This establishes a production-ready, enterprise-grade release management system that follows modern monorepo practices while maintaining backward compatibility with existing development workflows. + +### Patch Changes + +- Display proceed recipients' data in text format in ats web +- Updated dependencies + - @hashgraph/asset-tokenization-sdk@1.17.0 diff --git a/apps/ats/web/eslint.config.mjs b/apps/ats/web/eslint.config.mjs new file mode 100644 index 000000000..20bed0850 --- /dev/null +++ b/apps/ats/web/eslint.config.mjs @@ -0,0 +1,55 @@ +/** + * ESLint configuration for ATS Web App + * Extends root monorepo configuration with React/Web-specific rules + */ +import baseConfig from '../../../eslint.config.mjs'; +import reactHooks from 'eslint-plugin-react-hooks'; +import reactRefresh from 'eslint-plugin-react-refresh'; +import globals from 'globals'; + +// Filter base config to get general rules and adapt paths for web app +const webConfig = baseConfig + .filter( + (config) => + // Include base ignores, default config, but exclude package-specific rules + !config.files || config.files.includes('**/*.{js,mjs,cjs,ts,tsx,mts}'), + ) + .concat([ + // React/Web app files - adapted paths + { + files: ['**/*.{ts,tsx,js,jsx}'], + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + ...globals.jest, + }, + parserOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + settings: { + react: { + version: 'detect', + }, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-non-null-asserted-optional-chain': 'off', + '@typescript-eslint/no-empty-function': 'off', + }, + }, + ]); + +export default webConfig; diff --git a/apps/ats/web/package.json b/apps/ats/web/package.json index 3e2bd1a08..34538725e 100644 --- a/apps/ats/web/package.json +++ b/apps/ats/web/package.json @@ -1,6 +1,6 @@ { "name": "@hashgraph/asset-tokenization-dapp", - "version": "1.16.0", + "version": "1.17.0", "license": "Apache-2.0", "scripts": { "build": "tsc && vite build", @@ -10,11 +10,15 @@ "dev": "vite", "start": "vite preview", "clean:node": "npx --yes rimraf node_modules", - "clean:build": "npx --yes rimraf build", + "clean:build": "npx --yes rimraf dist", "clean:lock": "npx --yes rimraf package-lock.json yarn.lock", "test:update": "NODE_ENV=test jest --updateSnapshot", "test:clear:cache": "npx jest --clearCache", - "theme": "chakra-cli tokens src/theme/index.ts" + "theme": "chakra-cli tokens src/theme/index.ts", + "lint": "eslint '**/*.{js,jsx,mjs,cjs,ts,tsx,mts}' --cache", + "lint:fix": "eslint '**/*.{js,jsx,mjs,cjs,ts,tsx,mts}' --fix --cache && npm run format", + "format": "prettier --write '**/*.{js,jsx,mjs,cjs,ts,tsx,mts,json,md,yml,yaml}' --cache", + "format:check": "prettier --check '**/*.{js,jsx,mjs,cjs,ts,tsx,mts,json,md,yml,yaml}' --cache" }, "devDependencies": { "@babel/preset-env": "^7.21.4", @@ -25,7 +29,7 @@ "@esbuild-plugins/node-modules-polyfill": "^0.2.2", "@rollup/plugin-commonjs": "^28.0.6", "@testing-library/jest-dom": "^5.16.5", - "@testing-library/react": "^14.0.0", + "@testing-library/react": "^14.2.0", "@testing-library/user-event": "^14.4.3", "@types/format-util": "^1.0.2", "@types/jest": "^29.5.1", @@ -45,10 +49,11 @@ "rimraf": "^6.0.1", "ts-jest": "^29.1.0", "ts-xor": "^1.1.0", - "typescript": "4.9.5", + "typescript": "5.3.3", "util": "^0.12.5", "vite": "4.5.5", "vite-plugin-environment": "^1.1.3", + "vite-plugin-node-polyfills": "^0.24.0", "vite-plugin-rewrite-all": "1.0.1", "vite-tsconfig-paths": "^4.2.1" }, @@ -56,25 +61,21 @@ "@chakra-ui/react": "2.6.1", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", - "@hashgraph/asset-tokenization-sdk": "file:../../../packages/ats/sdk", + "@hashgraph/asset-tokenization-sdk": "*", "@tanstack/react-query": "^4.35.3", "framer-motion": "^10.16.4", - "i18next": "23.5.1", - "i18next-browser-languagedetector": "7.1.0", - "io-bricks-ui": "^2.7.4", + "i18next": "23.10.1", + "i18next-browser-languagedetector": "7.2.0", + "io-bricks-ui": "2.7.4", + "@phosphor-icons/react": "2.0.9", "named-urls": "^2.0.1", "react": "^18.2.0", "react-device-detect": "^2.2.3", "react-dom": "^18.2.0", - "react-hook-form": "^7.41.5", - "react-i18next": "^13.2.0", - "react-router-dom": "^6.10.0", + "react-hook-form": "7.41.5", + "react-i18next": "13.2.0", + "react-router-dom": "6.10.0", "use-react-router-breadcrumbs": "^4.0.1", - "zustand": "^4.4.1" - }, - "overrides": { - "ws": "7.5.10", - "elliptic": "6.6.1", - "path-to-regexp": "6.3.0" + "zustand": "4.4.1" } } diff --git a/apps/ats/web/prettier.config.mjs b/apps/ats/web/prettier.config.mjs new file mode 100644 index 000000000..4810489f6 --- /dev/null +++ b/apps/ats/web/prettier.config.mjs @@ -0,0 +1,7 @@ +/** + * Prettier configuration for ATS Web App + * Extends root monorepo configuration + */ +import baseConfig from '../../../prettier.config.mjs'; + +export default baseConfig; diff --git a/apps/ats/web/src/hooks/mutations/useProceedRecipients.tsx b/apps/ats/web/src/hooks/mutations/useProceedRecipients.tsx new file mode 100644 index 000000000..a1fad0b46 --- /dev/null +++ b/apps/ats/web/src/hooks/mutations/useProceedRecipients.tsx @@ -0,0 +1,162 @@ +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import SDKService from '../../services/SDKService'; +import { + AddProceedRecipientRequest, + RemoveProceedRecipientRequest, + UpdateProceedRecipientDataRequest, +} from '@hashgraph/asset-tokenization-sdk'; +import { useToast } from 'io-bricks-ui'; +import { useTranslation } from 'react-i18next'; +import { GET_PROCEED_RECIPIENT_LIST } from '../queries/useProceedRecipients'; + +export const useAddProceedRecipient = () => { + const queryClient = useQueryClient(); + const toast = useToast(); + const { t } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients.create.messages', + }); + + return useMutation( + (req: AddProceedRecipientRequest) => SDKService.addProceedRecipient(req), + { + onSuccess(data, variables) { + queryClient.invalidateQueries({ + queryKey: [GET_PROCEED_RECIPIENT_LIST(variables.securityId)], + }); + + console.log( + 'SDK message --> Add proceed recipient operation success: ', + data, + ); + + if (!data) { + return; + } + + toast.show({ + duration: 3000, + title: t('success'), + description: t('descriptionSuccess'), + variant: 'subtle', + status: 'success', + }); + }, + onError: (error) => { + console.log( + 'SDK message --> Add proceed recipient operation error: ', + error, + ); + + toast.show({ + duration: 3000, + title: t('error'), + description: t('descriptionFailed'), + variant: 'subtle', + status: 'error', + }); + }, + }, + ); +}; + +export const useUpdateProceedRecipient = () => { + const queryClient = useQueryClient(); + const toast = useToast(); + const { t } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients.update.messages', + }); + + return useMutation( + (req: UpdateProceedRecipientDataRequest) => + SDKService.updateProceedRecipientData(req), + { + onSuccess(data, variables) { + queryClient.invalidateQueries({ + queryKey: [GET_PROCEED_RECIPIENT_LIST(variables.securityId)], + }); + + console.log( + 'SDK message --> Update proceed recipient operation success: ', + data, + ); + + if (!data) { + return; + } + + toast.show({ + duration: 3000, + title: t('success'), + description: t('descriptionSuccess'), + variant: 'subtle', + status: 'success', + }); + }, + onError: (error) => { + console.log( + 'SDK message --> Update proceed recipient operation error: ', + error, + ); + + toast.show({ + duration: 3000, + title: t('error'), + description: t('descriptionFailed'), + variant: 'subtle', + status: 'error', + }); + }, + }, + ); +}; + +export const useRemoveProceedRecipient = () => { + const queryClient = useQueryClient(); + const toast = useToast(); + const { t } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients.remove.messages', + }); + + return useMutation( + (req: RemoveProceedRecipientRequest) => + SDKService.removeProceedRecipient(req), + { + onSuccess(data, variables) { + queryClient.invalidateQueries({ + queryKey: [GET_PROCEED_RECIPIENT_LIST(variables.securityId)], + }); + + console.log( + 'SDK message --> Remove proceed recipient operation success: ', + data, + ); + + if (!data) { + return; + } + + toast.show({ + duration: 3000, + title: t('success'), + description: t('descriptionSuccess'), + variant: 'subtle', + status: 'success', + }); + }, + onError: (error) => { + console.log( + 'SDK message --> Remove proceed recipient operation error: ', + error, + ); + + toast.show({ + duration: 3000, + title: t('error'), + description: t('descriptionFailed'), + variant: 'subtle', + status: 'error', + }); + }, + }, + ); +}; diff --git a/packages/ats/contracts/scripts/commands/RegisterDeployedContractBusinessLogicsCommand.ts b/apps/ats/web/src/hooks/mutations/useUpdateCompliance.tsx similarity index 88% rename from packages/ats/contracts/scripts/commands/RegisterDeployedContractBusinessLogicsCommand.ts rename to apps/ats/web/src/hooks/mutations/useUpdateCompliance.tsx index a3cb372b1..eac0df3a7 100644 --- a/packages/ats/contracts/scripts/commands/RegisterDeployedContractBusinessLogicsCommand.ts +++ b/apps/ats/web/src/hooks/mutations/useUpdateCompliance.tsx @@ -203,44 +203,53 @@ */ -import { - DeployAtsContractsResult, - BusinessLogicResolverProxyNotFound, - BaseAtsContractListCommand, - BaseBlockchainCommandParams, -} from '@scripts' - -interface RegisterDeployedContractBusinessLogicsCommandParams - extends BaseBlockchainCommandParams { - readonly deployedContractList: DeployAtsContractsResult -} - -export default class RegisterDeployedContractBusinessLogicsCommand extends BaseAtsContractListCommand { - constructor({ - deployedContractList, - signer, - overrides, - }: RegisterDeployedContractBusinessLogicsCommandParams) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { deployer, businessLogicResolver, ...contractListToRegister } = - deployedContractList - const contractAddressList = Object.values(contractListToRegister).map( - (contract) => contract.address - ) - - if (!businessLogicResolver.proxyAddress) { - throw new BusinessLogicResolverProxyNotFound() +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import SDKService from '../../services/SDKService'; +import { SetComplianceRequest } from '@hashgraph/asset-tokenization-sdk'; +import { useToast } from 'io-bricks-ui'; +import { useTranslation } from 'react-i18next'; +import { GET_COMPLIANCE } from '../queries/useCompliance'; + +export const useUpdateCompliance = () => { + const queryClient = useQueryClient(); + const toast = useToast(); + const { t } = useTranslation('security', { + keyPrefix: 'details.bond.updateCompliance.messages', + }); + + return useMutation( + (req: SetComplianceRequest) => SDKService.updateCompliance(req), + { + onSuccess(data, variables) { + queryClient.invalidateQueries({ + queryKey: [GET_COMPLIANCE(variables.securityId)], + }); + + console.log('SDK message --> Update compliance success: ', data); + + if (!data) { + return; } - super({ - contractAddressList, - businessLogicResolverProxyAddress: - businessLogicResolver.proxyAddress, - signer, - overrides, - }) - } - get deployedContractAddressList() { - return this.contractAddressList - } -} + toast.show({ + duration: 3000, + title: t('success'), + description: t('updateComplianceSuccessful'), + variant: 'subtle', + status: 'success', + }); + }, + onError: (error) => { + console.log('SDK message --> Update compliance error: ', error); + + toast.show({ + duration: 3000, + title: t('error'), + description: t('updateComplianceFailed'), + variant: 'subtle', + status: 'error', + }); + }, + }, + ); +}; diff --git a/apps/ats/web/src/hooks/mutations/useUpdateIdentityRegistry.tsx b/apps/ats/web/src/hooks/mutations/useUpdateIdentityRegistry.tsx new file mode 100644 index 000000000..90796f383 --- /dev/null +++ b/apps/ats/web/src/hooks/mutations/useUpdateIdentityRegistry.tsx @@ -0,0 +1,255 @@ +/* + 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. + +*/ + +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import SDKService from '../../services/SDKService'; +import { SetIdentityRegistryRequest } from '@hashgraph/asset-tokenization-sdk'; +import { useToast } from 'io-bricks-ui'; +import { useTranslation } from 'react-i18next'; +import { GET_IDENTITY_REGISTRY } from '../queries/useIdentityRegistry'; + +export const useUpdateIdentityRegistry = () => { + const queryClient = useQueryClient(); + const toast = useToast(); + const { t } = useTranslation('security', { + keyPrefix: 'details.bond.updateIdentityRegistry.messages', + }); + + return useMutation( + (req: SetIdentityRegistryRequest) => SDKService.updateIdentityRegistry(req), + { + onSuccess(data, variables) { + queryClient.invalidateQueries({ + queryKey: [GET_IDENTITY_REGISTRY(variables.securityId)], + }); + + console.log('SDK message --> Update identity registry success: ', data); + + if (!data) { + return; + } + + toast.show({ + duration: 3000, + title: t('success'), + description: t('updateIdentityRegistrySuccessful'), + variant: 'subtle', + status: 'success', + }); + }, + onError: (error) => { + console.log('SDK message --> Update identity registry error: ', error); + + toast.show({ + duration: 3000, + title: t('error'), + description: t('updateIdentityRegistryFailed'), + variant: 'subtle', + status: 'error', + }); + }, + }, + ); +}; diff --git a/apps/ats/web/src/hooks/queries/useCoupons.ts b/apps/ats/web/src/hooks/queries/useCoupons.ts index 449f35f54..20b34fe33 100644 --- a/apps/ats/web/src/hooks/queries/useCoupons.ts +++ b/apps/ats/web/src/hooks/queries/useCoupons.ts @@ -1,212 +1,9 @@ -/* - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +// SPDX-License-Identifier: Apache-2.0 - 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. - -*/ - -import { UseQueryOptions, useMutation, useQuery } from '@tanstack/react-query'; -import { SDKService } from '../../services/SDKService'; -import { useToast } from 'io-bricks-ui'; -import { useTranslation } from 'react-i18next'; +import { UseQueryOptions, useMutation, useQuery } from "@tanstack/react-query"; +import { SDKService } from "../../services/SDKService"; +import { useToast } from "io-bricks-ui"; +import { useTranslation } from "react-i18next"; import { CouponForViewModel, CouponViewModel, @@ -216,61 +13,53 @@ import { GetCouponRequest, GetTotalCouponHoldersRequest, SetCouponRequest, -} from '@hashgraph/asset-tokenization-sdk'; + CouponAmountForViewModel, +} from "@hashgraph/asset-tokenization-sdk"; -export const GET_SECURITY_COUPONS_FOR = ( - securityId: string, - couponId: number, - targetId: string, -) => `GET_SECURITY_COUPONS_FOR_${securityId}_${couponId}_${targetId}`; +export const GET_SECURITY_COUPONS_FOR = (securityId: string, couponId: number, targetId: string) => + `GET_SECURITY_COUPONS_FOR_${securityId}_${couponId}_${targetId}`; export const GET_SECURITY_COUPONS = (securityId: string, couponId: number) => `GET_SECURITY_COUPONS_${securityId}_${couponId}`; -export const GET_SECURITY_ALL_COUPONS = (securityId: string) => - `GET_SECURITY_ALL_COUPONS_${securityId}`; +export const GET_SECURITY_ALL_COUPONS = (securityId: string) => `GET_SECURITY_ALL_COUPONS_${securityId}`; + +export const GET_SECURITY_COUPONS_HOLDERS = (securityId: string, couponId: number) => + `GET_SECURITY_COUPONS_HOLDERS_${securityId}_${couponId}`; -export const GET_SECURITY_COUPONS_HOLDERS = ( - securityId: string, - couponId: number, -) => `GET_SECURITY_COUPONS_HOLDERS_${securityId}_${couponId}`; +export const GET_SECURITY_COUPONS_TOTAL_HOLDERS = (securityId: string, couponId: number) => + `GET_SECURITY_COUPONS_TOTAL_HOLDERS_${securityId}_${couponId}`; -export const GET_SECURITY_COUPONS_TOTAL_HOLDERS = ( - securityId: string, - couponId: number, -) => `GET_SECURITY_COUPONS_TOTAL_HOLDERS_${securityId}_${couponId}`; +export const GET_SECURITY_AMOUNT_COUPONS_FOR = (securityId: string, couponId: number, targetId: string) => + `GET_SECURITY_AMOUNT_COUPONS_FOR_${securityId}_${couponId}_${targetId}`; export const useCoupons = () => { const toast = useToast(); - const { t } = useTranslation('security', { keyPrefix: 'details.coupons' }); + const { t } = useTranslation("security", { keyPrefix: "details.coupons" }); - return useMutation( - (setCouponRequest: SetCouponRequest) => - SDKService.setCoupon(setCouponRequest), - { - onSuccess: (data) => { - console.log('SDK message --> Coupon creation success: ', data); + return useMutation((setCouponRequest: SetCouponRequest) => SDKService.setCoupon(setCouponRequest), { + onSuccess: (data) => { + console.log("SDK message --> Coupon creation success: ", data); - if (!data) return; + if (!data) return; - toast.show({ - title: t('messages.success'), - description: t('messages.creationSuccessful'), - variant: 'subtle', - status: 'success', - }); - }, - onError: (error) => { - console.log('SDK message --> Coupon creation error: ', error); - toast.show({ - title: t('messages.error'), - description: t('messages.creationFailed'), - variant: 'subtle', - status: 'error', - }); - }, + toast.show({ + title: t("messages.success"), + description: t("messages.creationSuccessful"), + variant: "subtle", + status: "success", + }); }, - ); + onError: (error) => { + console.log("SDK message --> Coupon creation error: ", error); + toast.show({ + title: t("messages.error"), + description: t("messages.creationFailed"), + variant: "subtle", + status: "error", + }); + }, + }); }; export const useGetCouponsFor = ( @@ -278,13 +67,7 @@ export const useGetCouponsFor = ( options: UseQueryOptions, ) => { return useQuery( - [ - GET_SECURITY_COUPONS_FOR( - params.securityId, - params.couponId, - params.targetId, - ), - ], + [GET_SECURITY_COUPONS_FOR(params.securityId, params.couponId, params.targetId)], () => SDKService.getCouponFor(params), options, ); @@ -305,11 +88,7 @@ export const useGetAllCoupons = ( params: GetAllCouponsRequest, options: UseQueryOptions = {}, ) => { - return useQuery( - [GET_SECURITY_ALL_COUPONS(params.securityId)], - () => SDKService.getAllCoupons(params), - options, - ); + return useQuery([GET_SECURITY_ALL_COUPONS(params.securityId)], () => SDKService.getAllCoupons(params), options); }; export const useGetCouponsHolders = ( @@ -333,3 +112,14 @@ export const useGetCouponsTotalHolders = ( options, ); }; + +export const useGetCouponsAmountFor = ( + params: GetCouponForRequest, + options: UseQueryOptions, +) => { + return useQuery( + [GET_SECURITY_AMOUNT_COUPONS_FOR(params.securityId, params.couponId, params.targetId)], + () => SDKService.getCouponAmountFor(params), + options, + ); +}; diff --git a/apps/ats/web/src/hooks/queries/useDividends.ts b/apps/ats/web/src/hooks/queries/useDividends.ts index f3db8af26..0d52a497a 100644 --- a/apps/ats/web/src/hooks/queries/useDividends.ts +++ b/apps/ats/web/src/hooks/queries/useDividends.ts @@ -1,212 +1,9 @@ -/* - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +//SPDX-License-Identifier: Apache-2.0 - 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. - -*/ - -import { UseQueryOptions, useMutation, useQuery } from '@tanstack/react-query'; -import { SDKService } from '../../services/SDKService'; -import { useToast } from 'io-bricks-ui'; -import { useTranslation } from 'react-i18next'; +import { UseQueryOptions, useMutation, useQuery } from "@tanstack/react-query"; +import { SDKService } from "../../services/SDKService"; +import { useToast } from "io-bricks-ui"; +import { useTranslation } from "react-i18next"; import { DividendsForViewModel, DividendsViewModel, @@ -215,62 +12,53 @@ import { GetDividendsRequest, GetTotalDividendHoldersRequest, SetDividendsRequest, -} from '@hashgraph/asset-tokenization-sdk'; + DividendAmountForViewModel, +} from "@hashgraph/asset-tokenization-sdk"; -export const GET_SECURITY_DIVIDENDS_FOR = ( - securityId: string, - dividendId: number, - targetId: string, -) => `GET_SECURITY_DIVIDENDS_${securityId}_${dividendId}_${targetId}`; +export const GET_SECURITY_DIVIDENDS_FOR = (securityId: string, dividendId: number, targetId: string) => + `GET_SECURITY_DIVIDENDS_${securityId}_${dividendId}_${targetId}`; -export const GET_SECURITY_DIVIDENDS = ( - securityId: string, - dividendId: number, -) => `GET_SECURITY_DIVIDENDS_${securityId}_${dividendId}`; +export const GET_SECURITY_DIVIDENDS = (securityId: string, dividendId: number) => + `GET_SECURITY_DIVIDENDS_${securityId}_${dividendId}`; -export const GET_SECURITY_DIVIDENDS_HOLDERS = ( - securityId: string, - dividendId: number, -) => `GET_SECURITY_DIVIDENDS_HOLDERS_${securityId}_${dividendId}`; +export const GET_SECURITY_DIVIDENDS_HOLDERS = (securityId: string, dividendId: number) => + `GET_SECURITY_DIVIDENDS_HOLDERS_${securityId}_${dividendId}`; -export const GET_SECURITY_DIVIDENDS_TOTAL_HOLDERS = ( - securityId: string, - dividendId: number, -) => `GET_SECURITY_DIVIDENDS_TOTAL_HOLDERS_${securityId}_${dividendId}`; +export const GET_SECURITY_DIVIDENDS_TOTAL_HOLDERS = (securityId: string, dividendId: number) => + `GET_SECURITY_DIVIDENDS_TOTAL_HOLDERS_${securityId}_${dividendId}`; + +export const GET_SECURITY_DIVIDENDS_AMOUNT_FOR = (securityId: string, dividendId: number, targetId: string) => + `GET_SECURITY_DIVIDENDS_AMOUNT_FOR_${securityId}_${dividendId}_${targetId}`; export const useDividends = () => { const toast = useToast(); - const { t } = useTranslation('security', { keyPrefix: 'details.dividends' }); + const { t } = useTranslation("security", { keyPrefix: "details.dividends" }); - return useMutation( - (setDividendsRequest: SetDividendsRequest) => - SDKService.setDividends(setDividendsRequest), - { - onSuccess: (data) => { - console.log('SDK message --> Dividend creation success: ', data); + return useMutation((setDividendsRequest: SetDividendsRequest) => SDKService.setDividends(setDividendsRequest), { + onSuccess: (data) => { + console.log("SDK message --> Dividend creation success: ", data); - if (!data) return; + if (!data) return; - toast.show({ - duration: 3000, - title: t('messages.succes'), - description: t('messages.creationSuccessful'), - variant: 'subtle', - status: 'success', - }); - }, - onError: (error) => { - console.log('SDK message --> Dividend creation error: ', error); - toast.show({ - duration: 3000, - title: t('messages.error'), - description: t('messages.creationFailed'), - variant: 'subtle', - status: 'error', - }); - }, + toast.show({ + duration: 3000, + title: t("messages.succes"), + description: t("messages.creationSuccessful"), + variant: "subtle", + status: "success", + }); }, - ); + onError: (error) => { + console.log("SDK message --> Dividend creation error: ", error); + toast.show({ + duration: 3000, + title: t("messages.error"), + description: t("messages.creationFailed"), + variant: "subtle", + status: "error", + }); + }, + }); }; export const useGetDividendsFor = ( @@ -278,13 +66,7 @@ export const useGetDividendsFor = ( options: UseQueryOptions, ) => { return useQuery( - [ - GET_SECURITY_DIVIDENDS_FOR( - params.securityId, - params.dividendId, - params.targetId, - ), - ], + [GET_SECURITY_DIVIDENDS_FOR(params.securityId, params.dividendId, params.targetId)], () => SDKService.getDividendsFor(params), options, ); @@ -317,13 +99,19 @@ export const useGetDividendHoldersTotal = ( options: UseQueryOptions, ) => { return useQuery( - [ - GET_SECURITY_DIVIDENDS_TOTAL_HOLDERS( - params.securityId, - params.dividendId, - ), - ], + [GET_SECURITY_DIVIDENDS_TOTAL_HOLDERS(params.securityId, params.dividendId)], () => SDKService.getTotalDividendHolders(params), options, ); }; + +export const useGetDividendsAmountFor = ( + params: GetDividendsForRequest, + options: UseQueryOptions, +) => { + return useQuery( + [GET_SECURITY_DIVIDENDS_AMOUNT_FOR(params.securityId, params.dividendId, params.targetId)], + () => SDKService.getDividendAmountFor(params), + options, + ); +}; diff --git a/apps/ats/web/src/hooks/queries/useFullRedeemAtMaturity.ts b/apps/ats/web/src/hooks/queries/useFullRedeemAtMaturity.ts new file mode 100644 index 000000000..f0f1e25c0 --- /dev/null +++ b/apps/ats/web/src/hooks/queries/useFullRedeemAtMaturity.ts @@ -0,0 +1,40 @@ +//SPDX-License-Identifier: Apache-2.0 + +import { UseMutationOptions, useMutation } from "@tanstack/react-query"; +import { SDKService } from "../../services/SDKService"; +import { FullRedeemAtMaturityRequest } from "@hashgraph/asset-tokenization-sdk"; +import { useToast } from "io-bricks-ui"; +import { useTranslation } from "react-i18next"; + +export const useFullRedeemAtMaturity = ( + options: UseMutationOptions = {}, +) => { + const toast = useToast(); + const { t } = useTranslation("security", { keyPrefix: "redeem" }); + + return useMutation((request: FullRedeemAtMaturityRequest) => SDKService.fullRedeemAtMaturity(request), { + onSuccess: (data) => { + if (data) { + toast.show({ + duration: 3000, + title: `${t("messages.success")}`, + description: `${t("messages.descriptionSuccess")}`, + variant: "subtle", + status: "success", + }); + } else { + toast.show({ + duration: 3000, + title: t("messages.error"), + description: t("messages.descriptionFailed"), + variant: "subtle", + status: "error", + }); + } + }, + onError: (error) => { + console.log("SDK message --> Full redeem at maturity error: ", error); + }, + ...options, + }); +}; diff --git a/apps/ats/web/src/hooks/queries/useIdentityRegistry.ts b/apps/ats/web/src/hooks/queries/useIdentityRegistry.ts new file mode 100644 index 000000000..41e11aa88 --- /dev/null +++ b/apps/ats/web/src/hooks/queries/useIdentityRegistry.ts @@ -0,0 +1,222 @@ +/* + 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. + +*/ + +import { UseQueryOptions, useQuery } from '@tanstack/react-query'; +import SDKService from '../../services/SDKService'; +import { IdentityRegistryRequest } from '@hashgraph/asset-tokenization-sdk'; + +export const GET_IDENTITY_REGISTRY = (securityId: string) => + `GET_IDENTITY_REGISTRY_${securityId}`; + +export const useGetIdentityRegistry = ( + request: IdentityRegistryRequest, + options?: UseQueryOptions, +) => { + return useQuery( + [GET_IDENTITY_REGISTRY(request.securityId)], + () => SDKService.getIdentityRegistry(request), + options, + ); +}; diff --git a/packages/ats/contracts/contracts/layer_0/scheduledTasks/scheduledSnapshots/ScheduledSnapshotsStorageWrapperRead.sol b/apps/ats/web/src/hooks/queries/useProceedRecipients.ts similarity index 83% rename from packages/ats/contracts/contracts/layer_0/scheduledTasks/scheduledSnapshots/ScheduledSnapshotsStorageWrapperRead.sol rename to apps/ats/web/src/hooks/queries/useProceedRecipients.ts index 58ab095d6..eb29da0ac 100644 --- a/packages/ats/contracts/contracts/layer_0/scheduledTasks/scheduledSnapshots/ScheduledSnapshotsStorageWrapperRead.sol +++ b/apps/ats/web/src/hooks/queries/useProceedRecipients.ts @@ -203,83 +203,75 @@ */ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.18; - -import { - IScheduledSnapshots -} from '../../../layer_2/interfaces/scheduledTasks/scheduledSnapshots/IScheduledSnapshots.sol'; -import { - ScheduledTasksLib -} from '../../../layer_2/scheduledTasks/ScheduledTasksLib.sol'; +import { useQuery, UseQueryOptions } from '@tanstack/react-query'; +import SDKService from '../../services/SDKService'; import { - ScheduledTasksStorageWrapper -} from '../scheduledTasks/ScheduledTasksStorageWrapper.sol'; -import { - _SCHEDULED_SNAPSHOTS_STORAGE_POSITION -} from '../../constants/storagePositions.sol'; - -abstract contract ScheduledSnapshotsStorageWrapperRead is - ScheduledTasksStorageWrapper -{ - function _addScheduledSnapshot( - uint256 _newScheduledTimestamp, - bytes memory _newData - ) internal { - ScheduledTasksLib.addScheduledTask( - _scheduledSnapshotStorage(), - _newScheduledTimestamp, - _newData - ); - } - - function _triggerScheduledSnapshots( - uint256 _max - ) internal returns (uint256) { - return - ScheduledTasksLib.triggerScheduledTasks( - _scheduledSnapshotStorage(), - IScheduledSnapshots.onScheduledSnapshotTriggered.selector, - _max, - _blockTimestamp() - ); - } - - function _getScheduledSnapshotCount() internal view returns (uint256) { - return - ScheduledTasksLib.getScheduledTaskCount( - _scheduledSnapshotStorage() - ); - } - - function _getScheduledSnapshots( - uint256 _pageIndex, - uint256 _pageLength - ) - internal - view - returns (ScheduledTasksLib.ScheduledTask[] memory scheduledSnapshot_) - { - return - ScheduledTasksLib.getScheduledTasks( - _scheduledSnapshotStorage(), - _pageIndex, - _pageLength - ); - } - - function _scheduledSnapshotStorage() - internal - pure - returns ( - ScheduledTasksLib.ScheduledTasksDataStorage - storage scheduledSnapshots_ - ) - { - bytes32 position = _SCHEDULED_SNAPSHOTS_STORAGE_POSITION; - // solhint-disable-next-line no-inline-assembly - assembly { - scheduledSnapshots_.slot := position - } - } + GetProceedRecipientsCountRequest, + GetProceedRecipientsRequest, + GetProceedRecipientDataRequest, +} from '@hashgraph/asset-tokenization-sdk'; + +export interface ProceedRecipientDataViewModelResponse { + address: string; + data?: string; } + +export const GET_PROCEED_RECIPIENT_LIST = (securityId: string) => + `GET_PROCEED_RECIPIENT_LIST_${securityId}`; + +export const IS_INTERNAL_PROCEED_RECIPIENT_ACTIVATED = (securityId: string) => + `IS_INTERNAL_PROCEED_RECIPIENT_ACTIVATED_${securityId}`; + +export const useGetProceedRecipientList = ( + request: GetProceedRecipientsCountRequest, + options?: UseQueryOptions< + ProceedRecipientDataViewModelResponse[], + unknown, + ProceedRecipientDataViewModelResponse[], + string[] + >, +) => { + return useQuery( + [GET_PROCEED_RECIPIENT_LIST(request.securityId)], + async () => { + try { + const proceedRecipientsCount = + await SDKService.getProceedRecipientsCount(request); + + const proceedRecipients = await SDKService.getProceedRecipients( + new GetProceedRecipientsRequest({ + securityId: request.securityId, + pageIndex: 0, + pageSize: proceedRecipientsCount ?? 100, + }), + ); + + const proceedRecipientsWithData = await Promise.all( + proceedRecipients.map(async (proceedRecipient) => { + try { + const data = await SDKService.getProceedRecipientData( + new GetProceedRecipientDataRequest({ + securityId: request.securityId, + proceedRecipientId: proceedRecipient, + }), + ); + return { + address: proceedRecipient, + data, + } as ProceedRecipientDataViewModelResponse; + } catch (error) { + console.error('Error fetching proceed recipient data', error); + return { address: proceedRecipient, data: undefined }; + } + }), + ); + + return proceedRecipientsWithData; + } catch (error) { + console.error('Error fetching proceed recipients', error); + throw error; + } + }, + options, + ); +}; diff --git a/apps/ats/web/src/i18n/en/index.ts b/apps/ats/web/src/i18n/en/index.ts index 8ef858ea6..dcd4207ee 100644 --- a/apps/ats/web/src/i18n/en/index.ts +++ b/apps/ats/web/src/i18n/en/index.ts @@ -258,6 +258,7 @@ export default { evmAddress: 'EVM Address', id: 'ID', compliance: 'Compliance', + identityRegistry: 'Identity Registry', totalSupply: 'Total Supply', maxSupply: 'Max Supply', pendingToBeMinted: 'Pending to be minted', @@ -324,6 +325,8 @@ export default { kycListManager: 'KYC Manager role', internalKYCManager: 'Internal KYC Manager role', freezer: 'Freeze Manager Role', + trexOwner: 'TREX Owner Role', + proceedRecipientManager: 'Proceed Recipient Manager Role', }, landing, routes, diff --git a/apps/ats/web/src/i18n/en/rules.ts b/apps/ats/web/src/i18n/en/rules.ts index 5bca0db96..76fb6e739 100644 --- a/apps/ats/web/src/i18n/en/rules.ts +++ b/apps/ats/web/src/i18n/en/rules.ts @@ -218,4 +218,5 @@ export default { isISINValid: 'Length should be {{length}}.', isISINValidFormat: 'Invalid format', isValidHederaId: 'Wrong id', + isValidHex: 'Invalid hex format', }; diff --git a/apps/ats/web/src/i18n/en/security/coupons.ts b/apps/ats/web/src/i18n/en/security/coupons.ts index 2a0e88d34..653d42bc7 100644 --- a/apps/ats/web/src/i18n/en/security/coupons.ts +++ b/apps/ats/web/src/i18n/en/security/coupons.ts @@ -1,287 +1,97 @@ -/* - 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. - -*/ +// SPDX-License-Identifier: Apache-2.0 export default { tabs: { - program: 'Program coupon', - see: 'See coupon', - holders: 'Holders', - list: 'List', + program: "Program coupon", + see: "See coupon", + holders: "Holders", + list: "List", }, list: { columns: { - id: 'ID', - recordDate: 'Record Date', - executionDate: 'Execution Date', - rate: 'Coupon Rate', - snapshotId: 'Snapshot', + id: "ID", + recordDate: "Record Date", + executionDate: "Execution Date", + rate: "Coupon Rate", + period: "Period", + snapshotId: "Snapshot", }, - emptyTable: 'No coupons found', + emptyTable: "No coupons found", }, program: { input: { - expired: 'You cannot program a coupon since the bond is expired.', + expired: "You cannot program a coupon since the bond is expired.", recordDate: { - label: 'Record date', - placeholder: 'Select record date', - tooltip: - 'Coupon’s record date. A snapshot of Bond holder’s balances will be triggered on this date.', + label: "Record date", + placeholder: "Select record date", + tooltip: "Coupon’s record date. A snapshot of Bond holder’s balances will be triggered on this date.", }, paymentDate: { - label: 'Payment date', - placeholder: 'Select payment date', - tooltip: 'Coupon’s execution date, must occur after the record date.', + label: "Payment date", + placeholder: "Select payment date", + tooltip: "Coupon’s execution date, must occur after the record date.", }, rate: { - label: 'Coupon rate', - placeholder: '0,123%', - tooltip: 'Interest rate for the coupon.', + label: "Coupon rate", + placeholder: "0,123%", + tooltip: "Interest rate for the coupon.", + }, + period: { + label: "Coupon period", + placeholder: "Select coupon period", + tooltip: "The period between coupon payments. This field is required for all coupon operations.", + options: { + day: "1 Day", + week: "1 Week", + month: "1 Month", + quarter: "3 Months", + year: "1 Year", + }, }, }, }, see: { input: { coupon: { - label: 'Coupon ID', - placeholder: 'Add ID', - tooltip: 'ID of the coupon to display.', + label: "Coupon ID", + placeholder: "Add ID", + tooltip: "ID of the coupon to display.", }, account: { - label: 'Account ID', - placeholder: 'Add ID', - tooltip: 'ID of the account to display the coupon for.', + label: "Account ID", + placeholder: "Add ID", + tooltip: "ID of the account to display the coupon for.", }, }, error: { - general: - 'Sorry, there was an error. Please check data and try again, please', + general: "Sorry, there was an error. Please check data and try again, please", }, details: { - title: 'Detail', - paymentDay: 'Payment day', - amount: 'Amount', + title: "Detail", + paymentDay: "Payment day", + balance: "Balance", + amount: "Amount", + recordDateReached: "Record Date Reached", }, }, holders: { - title: 'Holders', + title: "Holders", couponIdInput: { - label: 'Coupon ID', - placeholder: '1', - tooltip: 'ID of the coupon to display.', + label: "Coupon ID", + placeholder: "1", + tooltip: "ID of the coupon to display.", }, - searchButton: 'Search', - emptyTable: 'No data', + searchButton: "Search", + emptyTable: "No data", table: { - couponId: 'Coupon ID', - holderAddress: 'Holder address', + couponId: "Coupon ID", + holderAddress: "Holder address", }, }, messages: { - success: 'Success: ', - creationSuccessful: 'coupon creation was successful', - error: 'Error: ', - creationFailed: 'coupon creation failed', + success: "Success: ", + creationSuccessful: "coupon creation was successful", + error: "Error: ", + creationFailed: "coupon creation failed", }, }; diff --git a/apps/ats/web/src/i18n/en/security/createBond.ts b/apps/ats/web/src/i18n/en/security/createBond.ts index 609d9ec8f..d317f38ed 100644 --- a/apps/ats/web/src/i18n/en/security/createBond.ts +++ b/apps/ats/web/src/i18n/en/security/createBond.ts @@ -293,6 +293,20 @@ export default { totalCoupons: 'Total coupons', }, + stepProceedRecipients: { + title: 'Proceed Recipients', + subtitle: 'Add proceed recipients', + mandatoryFields: '*Mandatory fields', + address: 'Address', + addressPlaceholder: '0.0.1234567', + data: 'Data', + dataPlaceholder: '0x', + invalidHederaId: 'Invalid Hedera ID', + actions: 'Actions', + invalidHexFormat: 'Invalid hex format', + addProceedRecipient: 'Add proceed recipient', + }, + stepERC3643: { title: 'ERC3643', subtitle: 'Add ERC3643 configurations', diff --git a/apps/ats/web/src/i18n/en/security/details.ts b/apps/ats/web/src/i18n/en/security/details.ts index 66591418a..d45aab35d 100644 --- a/apps/ats/web/src/i18n/en/security/details.ts +++ b/apps/ats/web/src/i18n/en/security/details.ts @@ -219,6 +219,7 @@ import clearingOperations from './clearingOperations'; import externalPause from './externalPause'; import externalControl from './externalControl'; import externalKYC from './externalKYC'; +import proceedRecipients from './proceedRecipients'; export default { header: { @@ -249,6 +250,7 @@ export default { externalPause: 'External Pause', externalKYCList: 'External KYC', freeze: 'Freeze', + proceedRecipients: 'Proceed Recipients', }, actions: { redeem: 'Redeem', @@ -309,6 +311,7 @@ export default { externalPause, externalControl, externalKYC, + proceedRecipients, benefits: { dividends: 'Dividends', balanceAdjustments: 'Balance Adjustments', @@ -338,5 +341,34 @@ export default { updateMaturityDateFailed: 'Update maturity date failed', }, }, + updateCompliance: { + toast: { + title: 'Confirmation', + subtitle: 'Are you sure you want to change the compliance?', + cancelButtonText: 'Cancel', + confirmButtonText: 'Confirm', + }, + messages: { + success: 'Success: ', + updateComplianceSuccessful: 'Compliance has been updated successfully', + error: 'Error: ', + updateComplianceFailed: 'Update compliance failed', + }, + }, + updateIdentityRegistry: { + toast: { + title: 'Confirmation', + subtitle: 'Are you sure you want to change the identity registry?', + cancelButtonText: 'Cancel', + confirmButtonText: 'Confirm', + }, + messages: { + success: 'Success: ', + updateIdentityRegistrySuccessful: + 'Identity registry has been updated successfully', + error: 'Error: ', + updateIdentityRegistryFailed: 'Update identity registry failed', + }, + }, }, }; diff --git a/apps/ats/web/src/i18n/en/security/dividends.ts b/apps/ats/web/src/i18n/en/security/dividends.ts index be2d996a3..ba4487705 100644 --- a/apps/ats/web/src/i18n/en/security/dividends.ts +++ b/apps/ats/web/src/i18n/en/security/dividends.ts @@ -1,286 +1,83 @@ -/* - 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. - -*/ +//SPDX-License-Identifier: Apache-2.0 export default { tabs: { - program: 'Program dividend', - see: 'See dividend', - holders: 'Holders', - list: 'List', + program: "Program dividend", + see: "See dividend", + holders: "Holders", + list: "List", }, list: { columns: { - id: 'ID', - recordDate: 'Record Date', - executionDate: 'Execution Date', - dividendAmount: 'Dividend Amount', - snapshotId: 'Snapshot', + id: "ID", + recordDate: "Record Date", + executionDate: "Execution Date", + dividendAmount: "Dividend Amount", + snapshotId: "Snapshot", }, - emptyTable: 'No dividends found', + emptyTable: "No dividends found", }, program: { input: { recordDate: { - label: 'Record date', - placeholder: 'Select record date', - tooltip: - 'Dividend’s record date. A snapshot of Equity holder’s balances will be triggered on this date.', + label: "Record date", + placeholder: "Select record date", + tooltip: "Dividend’s record date. A snapshot of Equity holder’s balances will be triggered on this date.", }, paymentDate: { - label: 'Payment date', - placeholder: 'Select payment date', - tooltip: 'Dividend’s execution date, must occur after the record date.', + label: "Payment date", + placeholder: "Select payment date", + tooltip: "Dividend’s execution date, must occur after the record date.", }, amount: { - label: 'Dividend amount', - placeholder: '000 $', - tooltip: 'Amount per equity that will be paid to equity holder’s.', + label: "Dividend amount", + placeholder: "000 $", + tooltip: "Amount per equity that will be paid to equity holder’s.", }, }, }, see: { input: { dividend: { - label: 'Dividend ID', - placeholder: 'Add ID', - tooltip: 'ID of the dividend to display.', + label: "Dividend ID", + placeholder: "Add ID", + tooltip: "ID of the dividend to display.", }, account: { - label: 'Account ID', - placeholder: 'Add ID', - tooltip: 'ID of the account to display the dividend for.', + label: "Account ID", + placeholder: "Add ID", + tooltip: "ID of the account to display the dividend for.", }, }, error: { - general: - 'Sorry, there was an error. Please check data and try again, please', + general: "Sorry, there was an error. Please check data and try again, please", }, details: { - title: 'Detail', - paymentDay: 'Payment day', - amount: 'Amount', + title: "Detail", + paymentDay: "Payment day", + balance: "Balance", + amount: "Amount", + recordDateReached: "Record date reached", }, }, holders: { - title: 'Holders', + title: "Holders", dividendIdInput: { - label: 'Dividend ID', - placeholder: '1', - tooltip: 'ID of the dividend to display.', + label: "Dividend ID", + placeholder: "1", + tooltip: "ID of the dividend to display.", }, - searchButton: 'Search', - emptyTable: 'No data', + searchButton: "Search", + emptyTable: "No data", table: { - dividendId: 'Dividend ID', - holderAddress: 'Holder address', + dividendId: "Dividend ID", + holderAddress: "Holder address", }, }, messages: { - succes: 'Success: ', - creationSuccessful: 'Dividend creation was successful', - error: 'Error: ', - creationFailed: 'Dividend creation failed', + succes: "Success: ", + creationSuccessful: "Dividend creation was successful", + error: "Error: ", + creationFailed: "Dividend creation failed", }, }; diff --git a/apps/ats/web/src/i18n/en/security/forceRedeem.ts b/apps/ats/web/src/i18n/en/security/forceRedeem.ts index 9f52ba66d..d0b8d6c03 100644 --- a/apps/ats/web/src/i18n/en/security/forceRedeem.ts +++ b/apps/ats/web/src/i18n/en/security/forceRedeem.ts @@ -1,236 +1,36 @@ -/* - 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. - -*/ +//SPDX-License-Identifier: Apache-2.0 export default { header: { - title: 'Force redeem digital security', + title: "Force redeem digital security", }, - title: 'Force redeem securities', - subtitle: 'Choose the amount you want to redeem', + title: "Force redeem securities", + subtitle: "Choose the amount you want to redeem", input: { amount: { - label: 'Amount to redeem', - placeholder: 'Enter the amount to redeem', + label: "Amount to redeem", + placeholder: "Enter the amount to redeem", }, source: { - label: 'Add source Account', - placeholder: 'Enter the account', + label: "Add source Account", + placeholder: "Enter the account", }, }, list: { details: { - label: 'Details', + label: "Details", }, }, button: { - accept: 'Redeem', + accept: "Redeem", }, messages: { - success: 'Success: ', - descriptionSuccess: 'The redeem operation has been executed successfully', - error: 'Error: ', - descriptionFailed: 'The redeem operation has failed', + success: "Success: ", + descriptionSuccess: "The redeem operation has been executed successfully", + error: "Error: ", + descriptionFailed: "The redeem operation has failed", + }, + checkbox: { + label: "Select to redeem the full amount after maturity date", }, }; diff --git a/apps/ats/web/src/i18n/en/security/proceedRecipients.ts b/apps/ats/web/src/i18n/en/security/proceedRecipients.ts new file mode 100644 index 000000000..8146e9b2a --- /dev/null +++ b/apps/ats/web/src/i18n/en/security/proceedRecipients.ts @@ -0,0 +1,284 @@ +/* + 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. + +*/ + +export default { + title: 'Proceed Recipients', + subtitle: 'List of proceed recipients of the bond', + add: 'Add', + table: { + fields: { + address: 'Address', + data: 'Data', + actions: 'Actions', + edit: 'Edit', + remove: 'Remove', + }, + }, + create: { + title: 'Add Proceed Recipient', + description: 'Fill in the form below to add a proceed recipient', + form: { + address: { + label: 'Address', + placeholder: '0.0.1234567', + }, + data: { + label: 'Data', + placeholder: '0x', + invalidHexFormat: 'Invalid hex format', + }, + }, + buttons: { + cancel: 'Cancel', + add: 'Add', + }, + messages: { + success: 'Success: ', + descriptionSuccess: 'Proceed recipient creation was successful', + error: 'Error: ', + descriptionFailed: 'Proceed recipient creation failed', + }, + }, + update: { + title: 'Update Proceed Recipient', + description: 'Fill in the form below to update a proceed recipient', + form: { + address: { + label: 'Address', + placeholder: '0.0.1234567', + }, + data: { + label: 'Data', + placeholder: '0x', + invalidHexFormat: 'Invalid hex format', + }, + }, + buttons: { + cancel: 'Cancel', + update: 'Update', + }, + messages: { + success: 'Success: ', + descriptionSuccess: 'Proceed recipient update was successful', + error: 'Error: ', + descriptionFailed: 'Proceed recipient update failed', + }, + }, + remove: { + confirmPopUp: { + title: 'Remove Proceed Recipient', + description: 'Are you sure you want to remove this proceed recipient?', + confirmText: 'Remove', + cancelText: 'Cancel', + }, + messages: { + success: 'Success: ', + descriptionSuccess: + 'The removal operation has been executed successfully', + error: 'Error: ', + descriptionFailed: 'The removal operation has failed', + }, + }, +}; diff --git a/apps/ats/web/src/i18n/en/security/roleManagement.ts b/apps/ats/web/src/i18n/en/security/roleManagement.ts index 4e887e123..423975ba9 100644 --- a/apps/ats/web/src/i18n/en/security/roleManagement.ts +++ b/apps/ats/web/src/i18n/en/security/roleManagement.ts @@ -213,6 +213,8 @@ export default { subtitle: 'Add the ID account to manage its roles', currentRoles: 'Current roles', rolesDefinitions: 'Roles definitions', + selectAllRoles: 'Select all roles', + rolesSelected: 'roles selected', inputs: { search: { placeholder: '0.0.12345', diff --git a/apps/ats/web/src/i18n/index.ts b/apps/ats/web/src/i18n/index.ts index 94eb280d2..03099b7e6 100644 --- a/apps/ats/web/src/i18n/index.ts +++ b/apps/ats/web/src/i18n/index.ts @@ -215,8 +215,8 @@ declare module 'i18next' { } i18n - .use(initReactI18next) .use(LanguageDetector) + .use(initReactI18next) .init({ defaultNS: 'globals', detection: { diff --git a/apps/ats/web/src/services/SDKService.ts b/apps/ats/web/src/services/SDKService.ts index 72ef8bdf9..cba935964 100644 --- a/apps/ats/web/src/services/SDKService.ts +++ b/apps/ats/web/src/services/SDKService.ts @@ -1,207 +1,4 @@ -/* - 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. - -*/ +//SPDX-License-Identifier: Apache-2.0 import { ApplyRolesRequest, @@ -210,8 +7,9 @@ import { BondDetailsViewModel, ConnectRequest, ControlListRequest, - CouponDetailsViewModel, CouponForViewModel, + CouponAmountForViewModel, + PrincipalForViewModel, CouponViewModel, CreateBondRequest, CreateEquityRequest, @@ -230,8 +28,8 @@ import { GetControlListCountRequest, GetControlListMembersRequest, GetControlListTypeRequest, - GetCouponDetailsRequest, GetCouponForRequest, + GetPrincipalForRequest, GetCouponRequest, GetDividendsForRequest, GetDividendsRequest, @@ -365,21 +163,33 @@ import { UnfreezePartialTokensRequest, GetFrozenPartialTokensRequest, ComplianceRequest, + IdentityRegistryRequest, GetCouponHoldersRequest, GetTotalCouponHoldersRequest, GetTotalDividendHoldersRequest, GetDividendHoldersRequest, GetTotalVotingHoldersRequest, GetVotingHoldersRequest, -} from '@hashgraph/asset-tokenization-sdk'; + SetComplianceRequest, + SetIdentityRegistryRequest, + AddProceedRecipientRequest, + RemoveProceedRecipientRequest, + UpdateProceedRecipientDataRequest, + GetProceedRecipientsCountRequest, + GetProceedRecipientsRequest, + IsProceedRecipientRequest, + GetProceedRecipientDataRequest, + DividendAmountForViewModel, + FullRedeemAtMaturityRequest, +} from "@hashgraph/asset-tokenization-sdk"; export class SDKService { static initData?: InitializationData = undefined; - static testnetNetwork = 'testnet'; + static testnetNetwork = "testnet"; static testnetMirrorNode = { - baseUrl: process.env.REACT_APP_MIRROR_NODE ?? '', - apiKey: '', - headerName: '', + baseUrl: process.env.REACT_APP_MIRROR_NODE ?? "", + apiKey: "", + headerName: "", }; static testnetMirrorNodes = { nodes: [ @@ -390,10 +200,10 @@ export class SDKService { ], }; static testnetRPCNode = { - baseUrl: process.env.REACT_APP_RPC_NODE ?? '', + baseUrl: process.env.REACT_APP_RPC_NODE ?? "", //baseUrl: "http://127.0.0.1:7546", - apiKey: '', - headerName: '', + apiKey: "", + headerName: "", }; static testnetRPCNodes = { nodes: [ @@ -403,8 +213,8 @@ export class SDKService { }, ], }; - static testnetResolverAddress = process.env.REACT_APP_RPC_RESOLVER ?? '0.0.0'; - static testnetFactoryAddress = process.env.REACT_APP_RPC_FACTORY ?? '0.0.0'; + static testnetResolverAddress = process.env.REACT_APP_RPC_RESOLVER ?? "0.0.0"; + static testnetFactoryAddress = process.env.REACT_APP_RPC_FACTORY ?? "0.0.0"; static testnetConfiguration = { factoryAddress: this.testnetFactoryAddress, @@ -434,11 +244,11 @@ export class SDKService { public static async connectWallet(wallet: SupportedWallets) { let hwcSettings; if (wallet === SupportedWallets.HWALLETCONNECT) { - const projectId = process.env.REACT_APP_PROJECT_ID ?? ''; - const dappName = process.env.REACT_APP_DAPP_NAME ?? ''; - const dappDescription = process.env.REACT_APP_DAPP_DESCRIPTION ?? ''; - const dappURL = process.env.REACT_APP_DAPP_URL ?? ''; - const dappIcons = process.env.REACT_APP_DAPP_ICONS?.split(',') ?? []; + const projectId = process.env.REACT_APP_PROJECT_ID ?? ""; + const dappName = process.env.REACT_APP_DAPP_NAME ?? ""; + const dappDescription = process.env.REACT_APP_DAPP_DESCRIPTION ?? ""; + const dappURL = process.env.REACT_APP_DAPP_URL ?? ""; + const dappIcons = process.env.REACT_APP_DAPP_ICONS?.split(",") ?? []; if (projectId) { hwcSettings = { @@ -481,9 +291,9 @@ export class SDKService { return init; } catch (e) { - console.error('Error initializing the Network : ' + e); + console.error("Error initializing the Network : " + e); console.error( - 'There was an error initializing the network, please check your .env file and make sure the configuration is correct', + "There was an error initializing the network, please check your .env file and make sure the configuration is correct", ); } } @@ -492,16 +302,12 @@ export class SDKService { return await Network.disconnect(); } // FACTORY //////////////////////////////////////////// - public static async getRegulationDetails( - req: GetRegulationDetailsRequest, - ): Promise { + public static async getRegulationDetails(req: GetRegulationDetailsRequest): Promise { return await Factory.getRegulationDetails(req); } // SECURITY //////////////////////////////////////////// - public static async getSecurityDetails( - req: GetSecurityDetailsRequest, - ): Promise { + public static async getSecurityDetails(req: GetSecurityDetailsRequest): Promise { return await Security.getInfo(req); } @@ -513,35 +319,21 @@ export class SDKService { return response; } - public static async getEquityDetails( - req: GetEquityDetailsRequest, - ): Promise { + public static async getEquityDetails(req: GetEquityDetailsRequest): Promise { return await Equity.getEquityDetails(req); } // BOND //////////////////////////////////////////// - public static async createBond( - createRequest: CreateBondRequest, - ): Promise<{ security: SecurityViewModel } | null> { + public static async createBond(createRequest: CreateBondRequest): Promise<{ security: SecurityViewModel } | null> { const response = await Bond.create(createRequest); return response; } - public static async getBondDetails( - req: GetBondDetailsRequest, - ): Promise { + public static async getBondDetails(req: GetBondDetailsRequest): Promise { return await Bond.getBondDetails(req); } - public static async getCouponDetails( - req: GetCouponDetailsRequest, - ): Promise { - return await Bond.getCouponDetails(req); - } - - public static async updateBondMaturityDate( - req: UpdateMaturityDateRequest, - ): Promise { + public static async updateBondMaturityDate(req: UpdateMaturityDateRequest): Promise { const response = await Bond.updateMaturityDate(req); return response.payload; } @@ -550,39 +342,89 @@ export class SDKService { return await Security.compliance(req); } + public static async updateCompliance(req: SetComplianceRequest): Promise<{ + payload: boolean; + }> { + return await Security.setCompliance(req); + } + + public static async getIdentityRegistry(req: IdentityRegistryRequest): Promise { + return await Security.identityRegistry(req); + } + + public static async updateIdentityRegistry(req: SetIdentityRegistryRequest): Promise<{ + payload: boolean; + }> { + return await Security.setIdentityRegistry(req); + } + + // Proceed Recipients + public static async getProceedRecipientsCount(req: GetProceedRecipientsCountRequest): Promise { + const request = await Bond.getProceedRecipientsCount(req); + return request.payload; + } + + public static async getProceedRecipients(req: GetProceedRecipientsRequest): Promise { + const request = await Bond.getProceedRecipients(req); + return request.payload; + } + + public static async getProceedRecipientData(req: GetProceedRecipientDataRequest): Promise { + const request = await Bond.getProceedRecipientData(req); + return request.payload; + } + + public static async isProceedRecipient(req: IsProceedRecipientRequest): Promise { + const request = await Bond.isProceedRecipient(req); + return request.payload; + } + + public static async addProceedRecipient(req: AddProceedRecipientRequest): Promise { + const response = await Bond.addProceedRecipient(req); + return response.payload; + } + + public static async removeProceedRecipient(req: RemoveProceedRecipientRequest): Promise { + const response = await Bond.removeProceedRecipient(req); + return response.payload; + } + + public static async updateProceedRecipientData(req: UpdateProceedRecipientDataRequest): Promise { + const response = await Bond.updateProceedRecipientData(req); + return response.payload; + } + // COUPONS //////////////////////////////////////////// public static async setCoupon(req: SetCouponRequest): Promise { const response = await Bond.setCoupon(req); return response.payload; } - public static async getCouponFor( - req: GetCouponForRequest, - ): Promise { + public static async getCouponFor(req: GetCouponForRequest): Promise { return await Bond.getCouponFor(req); } - public static async getCoupon( - req: GetCouponRequest, - ): Promise { + public static async getCouponAmountFor(req: GetCouponForRequest): Promise { + return await Bond.getCouponAmountFor(req); + } + + public static async getPrincipalFor(req: GetPrincipalForRequest): Promise { + return await Bond.getPrincipalFor(req); + } + + public static async getCoupon(req: GetCouponRequest): Promise { return await Bond.getCoupon(req); } - public static async getAllCoupons( - req: GetAllCouponsRequest, - ): Promise { + public static async getAllCoupons(req: GetAllCouponsRequest): Promise { return await Bond.getAllCoupons(req); } - public static async getCouponHolders( - req: GetCouponHoldersRequest, - ): Promise { + public static async getCouponHolders(req: GetCouponHoldersRequest): Promise { return await Bond.getCouponHolders(req); } - public static async getTotalCouponHolders( - req: GetTotalCouponHoldersRequest, - ): Promise { + public static async getTotalCouponHolders(req: GetTotalCouponHoldersRequest): Promise { return await Bond.getTotalCouponHolders(req); } @@ -597,21 +439,15 @@ export class SDKService { return response.payload; } - public static async getRoleMemberCount( - req: GetRoleMemberCountRequest, - ): Promise { + public static async getRoleMemberCount(req: GetRoleMemberCountRequest): Promise { return await Role.getRoleMemberCount(req); } - public static async getRoleMembers( - req: GetRoleMembersRequest, - ): Promise { + public static async getRoleMembers(req: GetRoleMembersRequest): Promise { return await Role.getRoleMembers(req); } - public static async getRoleCountFor( - req: GetRoleCountForRequest, - ): Promise { + public static async getRoleCountFor(req: GetRoleCountForRequest): Promise { return await Role.getRoleCountFor(req); } @@ -625,41 +461,29 @@ export class SDKService { } // CONTROL LIST //////////////////////////////////////////// - public static async addToControlList( - req: ControlListRequest, - ): Promise { + public static async addToControlList(req: ControlListRequest): Promise { const response = await Security.addToControlList(req); return response.payload; } - public static async removeFromControlList( - req: ControlListRequest, - ): Promise { + public static async removeFromControlList(req: ControlListRequest): Promise { const response = await Security.removeFromControlList(req); return response.payload; } - public static async isAccountInControlList( - req: ControlListRequest, - ): Promise { + public static async isAccountInControlList(req: ControlListRequest): Promise { return await Security.isAccountInControlList(req); } - public static async getControlListCount( - req: GetControlListCountRequest, - ): Promise { + public static async getControlListCount(req: GetControlListCountRequest): Promise { return await Security.getControlListCount(req); } - public static async getControlListMembers( - req: GetControlListMembersRequest, - ): Promise { + public static async getControlListMembers(req: GetControlListMembersRequest): Promise { return await Security.getControlListMembers(req); } - public static async getControlListType( - req: GetControlListTypeRequest, - ): Promise { + public static async getControlListType(req: GetControlListTypeRequest): Promise { return await Security.getControlListType(req); } @@ -670,23 +494,17 @@ export class SDKService { } // FREEZE & UNFREEZE //////////////////////////////////////////// - public static async freezePartialTokens( - req: FreezePartialTokensRequest, - ): Promise { + public static async freezePartialTokens(req: FreezePartialTokensRequest): Promise { const response = await Security.freezePartialTokens(req); return response.payload; } - public static async unfreezePartialTokens( - req: UnfreezePartialTokensRequest, - ): Promise { + public static async unfreezePartialTokens(req: UnfreezePartialTokensRequest): Promise { const response = await Security.unfreezePartialTokens(req); return response.payload; } - public static async getFrozenTokens( - req: GetFrozenPartialTokensRequest, - ): Promise { + public static async getFrozenTokens(req: GetFrozenPartialTokensRequest): Promise { const response = await Security.getFrozenPartialTokens(req); return response; } @@ -702,9 +520,7 @@ export class SDKService { return response.payload; } - public static async getBalanceOf( - req: GetAccountBalanceRequest, - ): Promise { + public static async getBalanceOf(req: GetAccountBalanceRequest): Promise { return await Security.getBalanceOf(req); } @@ -714,40 +530,32 @@ export class SDKService { return response.payload; } - public static async getDividendsFor( - req: GetDividendsForRequest, - ): Promise { + public static async getDividendsFor(req: GetDividendsForRequest): Promise { return await Equity.getDividendsFor(req); } - public static async getDividends( - req: GetDividendsRequest, - ): Promise { + public static async getDividendAmountFor(req: GetDividendsForRequest): Promise { + return await Equity.getDividendAmountFor(req); + } + + public static async getDividends(req: GetDividendsRequest): Promise { return await Equity.getDividends(req); } - public static async getAllDividends( - req: GetAllDividendsRequest, - ): Promise { + public static async getAllDividends(req: GetAllDividendsRequest): Promise { return await Equity.getAllDividends(req); } - public static async getDividendHolders( - req: GetDividendHoldersRequest, - ): Promise { + public static async getDividendHolders(req: GetDividendHoldersRequest): Promise { return await Equity.getDividendHolders(req); } - public static async getTotalDividendHolders( - req: GetTotalDividendHoldersRequest, - ): Promise { + public static async getTotalDividendHolders(req: GetTotalDividendHoldersRequest): Promise { return await Equity.getTotalDividendHolders(req); } // SPLIT & REVERSE SPLIT //////////////////////////////////////////// - public static async setScheduledBalanceAdjustmentRequest( - req: SetScheduledBalanceAdjustmentRequest, - ): Promise { + public static async setScheduledBalanceAdjustmentRequest(req: SetScheduledBalanceAdjustmentRequest): Promise { const response = await Equity.setScheduledBalanceAdjustment(req); return response.payload; } @@ -765,16 +573,12 @@ export class SDKService { } // CONTROLLER //////////////////////////////////////////// - public static async controllerTransfer( - req: ForceTransferRequest, - ): Promise { + public static async controllerTransfer(req: ForceTransferRequest): Promise { const response = await Security.controllerTransfer(req); return response.payload; } - public static async controllerRedeem( - req: ForceRedeemRequest, - ): Promise { + public static async controllerRedeem(req: ForceRedeemRequest): Promise { const response = await Security.controllerRedeem(req); return response.payload; } @@ -800,47 +604,33 @@ export class SDKService { return response.payload; } - public static async getMaxSupply( - req: GetMaxSupplyRequest, - ): Promise { + public static async getMaxSupply(req: GetMaxSupplyRequest): Promise { return await Security.getMaxSupply(req); } // VOTING RIGHTS //////////////////////////////////////////// - public static async setVotingRights( - req: SetVotingRightsRequest, - ): Promise { + public static async setVotingRights(req: SetVotingRightsRequest): Promise { const response = await Equity.setVotingRights(req); return response.payload; } - public static async getAllVotingRights( - req: GetAllVotingRightsRequest, - ): Promise { + public static async getAllVotingRights(req: GetAllVotingRightsRequest): Promise { return await Equity.getAllVotingRights(req); } - public static async getVotingRightsFor( - req: GetVotingRightsForRequest, - ): Promise { + public static async getVotingRightsFor(req: GetVotingRightsForRequest): Promise { return await Equity.getVotingRightsFor(req); } - public static async getVotingRights( - req: GetVotingRightsRequest, - ): Promise { + public static async getVotingRights(req: GetVotingRightsRequest): Promise { return await Equity.getVotingRights(req); } - public static async getVotingHolders( - req: GetVotingHoldersRequest, - ): Promise { + public static async getVotingHolders(req: GetVotingHoldersRequest): Promise { return await Equity.getVotingHolders(req); } - public static async getTotalVotingHolders( - req: GetTotalVotingHoldersRequest, - ): Promise { + public static async getTotalVotingHolders(req: GetTotalVotingHoldersRequest): Promise { return await Equity.getTotalVotingHolders(req); } @@ -855,9 +645,7 @@ export class SDKService { return response.payload; } - public static async getLockedBalanceOf( - req: GetLockedBalanceRequest, - ): Promise { + public static async getLockedBalanceOf(req: GetLockedBalanceRequest): Promise { return await Security.getLockedBalanceOf(req); } @@ -869,118 +657,84 @@ export class SDKService { return await Security.getLock(req); } - public static async getHoldsId( - req: GetHoldsIdForByPartitionRequest, - ): Promise { + public static async getHoldsId(req: GetHoldsIdForByPartitionRequest): Promise { return await Security.getHoldsIdForByPartition(req); } - public static async getHoldDetails( - req: GetHoldForByPartitionRequest, - ): Promise { + public static async getHoldDetails(req: GetHoldForByPartitionRequest): Promise { return await Security.getHoldForByPartition(req); } - public static async createHoldFromByPartition( - req: CreateHoldFromByPartitionRequest, - ): Promise { + public static async createHoldFromByPartition(req: CreateHoldFromByPartitionRequest): Promise { const response = await Security.createHoldFromByPartition(req); return response.payload; } - public static async controllerCreateHoldByPartition( - req: CreateHoldFromByPartitionRequest, - ): Promise { + public static async controllerCreateHoldByPartition(req: CreateHoldFromByPartitionRequest): Promise { const response = await Security.controllerCreateHoldByPartition(req); return response.payload; } - public static async createHoldByPartition( - req: CreateHoldByPartitionRequest, - ): Promise { + public static async createHoldByPartition(req: CreateHoldByPartitionRequest): Promise { const response = await Security.createHoldByPartition(req); return response.payload; } - public static async reclaimHoldByPartition( - req: ReclaimHoldByPartitionRequest, - ): Promise { + public static async reclaimHoldByPartition(req: ReclaimHoldByPartitionRequest): Promise { const response = await Security.reclaimHoldByPartition(req); return response.payload; } - public static async releaseHoldByPartition( - req: ReleaseHoldByPartitionRequest, - ): Promise { + public static async releaseHoldByPartition(req: ReleaseHoldByPartitionRequest): Promise { const response = await Security.releaseHoldByPartition(req); return response.payload; } - public static async executeHoldByPartition( - req: ExecuteHoldByPartitionRequest, - ): Promise { + public static async executeHoldByPartition(req: ExecuteHoldByPartitionRequest): Promise { const response = await Security.executeHoldByPartition(req); return response.payload; } - public static async getHeldAmountFor( - req: GetHeldAmountForRequest, - ): Promise { + public static async getHeldAmountFor(req: GetHeldAmountForRequest): Promise { const response = await Security.getHeldAmountFor(req); return response; } // MANAGEMENT //////////////////////////////////////////// - public static async getConfigInfo( - req: GetConfigInfoRequest, - ): Promise { + public static async getConfigInfo(req: GetConfigInfoRequest): Promise { return await Management.getConfigInfo(req); } - public static async updateSecurityConfigVersion( - req: UpdateConfigVersionRequest, - ): Promise { + public static async updateSecurityConfigVersion(req: UpdateConfigVersionRequest): Promise { const response = await Management.updateConfigVersion(req); return response.payload; } - public static async updateSecurityConfig( - req: UpdateConfigRequest, - ): Promise { + public static async updateSecurityConfig(req: UpdateConfigRequest): Promise { const response = await Management.updateConfig(req); return response.payload; } - public static async updateSecurityResolver( - req: UpdateResolverRequest, - ): Promise { + public static async updateSecurityResolver(req: UpdateResolverRequest): Promise { const response = await Management.updateResolver(req); return response.payload; } // DID MANAGEMENT //////////////////////////////////////////// - public static async getRevocationRegistryAddress( - req: GetRevocationRegistryAddressRequest, - ): Promise { + public static async getRevocationRegistryAddress(req: GetRevocationRegistryAddressRequest): Promise { return await SsiManagement.getRevocationRegistryAddress(req); } - public static async setRevocationRegistryAddress( - req: SetRevocationRegistryAddressRequest, - ): Promise { + public static async setRevocationRegistryAddress(req: SetRevocationRegistryAddressRequest): Promise { const response = await SsiManagement.setRevocationRegistryAddress(req); return response.payload; } - public static async getIssuerListCount( - req: GetIssuerListCountRequest, - ): Promise { + public static async getIssuerListCount(req: GetIssuerListCountRequest): Promise { return await SsiManagement.getIssuerListCount(req); } - public static async getIssuerListMembers( - req: GetIssuerListMembersRequest, - ): Promise { + public static async getIssuerListMembers(req: GetIssuerListMembersRequest): Promise { return await SsiManagement.getIssuerListMembers(req); } @@ -1003,9 +757,7 @@ export class SDKService { return await Kyc.getKycFor(req); } - public static async getKYCAccountsData( - req: GetKycAccountsDataRequest, - ): Promise { + public static async getKYCAccountsData(req: GetKycAccountsDataRequest): Promise { return await Kyc.getKycAccountsData(req); } @@ -1019,31 +771,23 @@ export class SDKService { return response.payload; } - public static async isInternalKycActivated( - req: IsInternalKycActivatedRequest, - ): Promise { + public static async isInternalKycActivated(req: IsInternalKycActivatedRequest): Promise { const response = await Kyc.isInternalKycActivated(req); return response; } - public static async activateInternalKyc( - req: ActivateInternalKycRequest, - ): Promise { + public static async activateInternalKyc(req: ActivateInternalKycRequest): Promise { const response = await Kyc.activateInternalKyc(req); return response.payload; } - public static async deactivateInternalKyc( - req: DeactivateInternalKycRequest, - ): Promise { + public static async deactivateInternalKyc(req: DeactivateInternalKycRequest): Promise { const response = await Kyc.deactivateInternalKyc(req); return response.payload; } // CLEARING OPERATIONS //////////////////////////////////////////// - public static async getClearingsIdForByPartition( - request: GetClearingsIdForByPartitionRequest, - ): Promise { + public static async getClearingsIdForByPartition(request: GetClearingsIdForByPartitionRequest): Promise { const response = await Security.getClearingsIdForByPartition(request); return response; } @@ -1064,28 +808,21 @@ export class SDKService { public static async getClearingCreateHoldForByPartition( request: GetClearingCreateHoldForByPartitionRequest, ): Promise { - const response = - await Security.getClearingCreateHoldForByPartition(request); + const response = await Security.getClearingCreateHoldForByPartition(request); return response; } - public static async clearingTransferByPartition( - request: ClearingTransferByPartitionRequest, - ): Promise { + public static async clearingTransferByPartition(request: ClearingTransferByPartitionRequest): Promise { const response = await Security.clearingTransferByPartition(request); return response.payload; } - public static async clearingRedeemByPartition( - request: ClearingRedeemByPartitionRequest, - ): Promise { + public static async clearingRedeemByPartition(request: ClearingRedeemByPartitionRequest): Promise { const response = await Security.clearingRedeemByPartition(request); return response.payload; } - public static async clearingCreateHoldByPartition( - request: ClearingCreateHoldByPartitionRequest, - ): Promise { + public static async clearingCreateHoldByPartition(request: ClearingCreateHoldByPartitionRequest): Promise { const response = await Security.clearingCreateHoldByPartition(request); return response.payload; } @@ -1093,8 +830,7 @@ export class SDKService { public static async approveClearingOperationByPartition( request: ApproveClearingOperationByPartitionRequest, ): Promise { - const response = - await Security.approveClearingOperationByPartition(request); + const response = await Security.approveClearingOperationByPartition(request); return response.payload; } @@ -1108,80 +844,58 @@ export class SDKService { public static async reclaimClearingOperationByPartition( request: ReclaimClearingOperationByPartitionRequest, ): Promise { - const response = - await Security.reclaimClearingOperationByPartition(request); + const response = await Security.reclaimClearingOperationByPartition(request); return response.payload; } - public static async activateClearing( - request: ActivateClearingRequest, - ): Promise { + public static async activateClearing(request: ActivateClearingRequest): Promise { const response = await Security.activateClearing(request); return response.payload; } - public static async deactivateClearing( - request: DeactivateClearingRequest, - ): Promise { + public static async deactivateClearing(request: DeactivateClearingRequest): Promise { const response = await Security.deactivateClearing(request); return response.payload; } - public static async isClearingActivated( - request: IsClearingActivatedRequest, - ): Promise { + public static async isClearingActivated(request: IsClearingActivatedRequest): Promise { const response = await Security.isClearingActivated(request); return response; } - public static async getClearedAmountFor( - req: GetClearedAmountForRequest, - ): Promise { + public static async getClearedAmountFor(req: GetClearedAmountForRequest): Promise { const response = await Security.getClearedAmountFor(req); return response; } // EXTERNAL PAUSES ////////////////////////////////////// - public static async addExternalPause( - req: AddExternalPauseRequest, - ): Promise { + public static async addExternalPause(req: AddExternalPauseRequest): Promise { const response = await ExternalPausesManagement.addExternalPause(req); return response.payload; } - public static async removeExternalPause( - req: RemoveExternalPauseRequest, - ): Promise { + public static async removeExternalPause(req: RemoveExternalPauseRequest): Promise { const response = await ExternalPausesManagement.removeExternalPause(req); return response.payload; } - public static async updateExternalPauses( - req: UpdateExternalPausesRequest, - ): Promise { + public static async updateExternalPauses(req: UpdateExternalPausesRequest): Promise { const response = await ExternalPausesManagement.updateExternalPauses(req); return response.payload; } - public static async isExternalPause( - req: IsExternalPauseRequest, - ): Promise { + public static async isExternalPause(req: IsExternalPauseRequest): Promise { const response = await ExternalPausesManagement.isExternalPause(req); return response; } - public static async getExternalPausesCount( - req: GetExternalPausesCountRequest, - ): Promise { + public static async getExternalPausesCount(req: GetExternalPausesCountRequest): Promise { const response = await ExternalPausesManagement.getExternalPausesCount(req); return response; } - public static async getExternalPausesMembers( - req: GetExternalPausesMembersRequest, - ): Promise { - const response = - await ExternalPausesManagement.getExternalPausesMembers(req); + public static async getExternalPausesMembers(req: GetExternalPausesMembersRequest): Promise { + const response = await ExternalPausesManagement.getExternalPausesMembers(req); return response; } @@ -1190,9 +904,7 @@ export class SDKService { return response; } - public static async setPausedMock( - req: SetPausedMockRequest, - ): Promise { + public static async setPausedMock(req: SetPausedMockRequest): Promise { const response = await ExternalPausesManagement.setPausedMock(req); return response.payload; } @@ -1204,110 +916,72 @@ export class SDKService { // External Control public static async createExternalBlackListMock(): Promise { - const response = - await ExternalControlListsManagement.createExternalBlackListMock(); + const response = await ExternalControlListsManagement.createExternalBlackListMock(); return response; } public static async createExternalWhiteListMock(): Promise { - const response = - await ExternalControlListsManagement.createExternalWhiteListMock(); + const response = await ExternalControlListsManagement.createExternalWhiteListMock(); return response; } - public static async addExternalControlList( - req: AddExternalControlListRequest, - ): Promise { - const response = - await ExternalControlListsManagement.addExternalControlList(req); + public static async addExternalControlList(req: AddExternalControlListRequest): Promise { + const response = await ExternalControlListsManagement.addExternalControlList(req); return response.payload; } - public static async addToBlackListMock( - req: AddToBlackListMockRequest, - ): Promise { - const response = - await ExternalControlListsManagement.addToBlackListMock(req); + public static async addToBlackListMock(req: AddToBlackListMockRequest): Promise { + const response = await ExternalControlListsManagement.addToBlackListMock(req); return response.payload; } - public static async addToWhiteListMock( - req: AddToWhiteListMockRequest, - ): Promise { - const response = - await ExternalControlListsManagement.addToWhiteListMock(req); + public static async addToWhiteListMock(req: AddToWhiteListMockRequest): Promise { + const response = await ExternalControlListsManagement.addToWhiteListMock(req); return response.payload; } - public static async removeExternalControlList( - req: RemoveExternalControlListRequest, - ): Promise { - const response = - await ExternalControlListsManagement.removeExternalControlList(req); + public static async removeExternalControlList(req: RemoveExternalControlListRequest): Promise { + const response = await ExternalControlListsManagement.removeExternalControlList(req); return response.payload; } - public static async removeFromBlackListMock( - req: RemoveFromBlackListMockRequest, - ): Promise { - const response = - await ExternalControlListsManagement.removeFromBlackListMock(req); + public static async removeFromBlackListMock(req: RemoveFromBlackListMockRequest): Promise { + const response = await ExternalControlListsManagement.removeFromBlackListMock(req); return response.payload; } - public static async removeFromWhiteListMock( - req: RemoveFromWhiteListMockRequest, - ): Promise { - const response = - await ExternalControlListsManagement.removeFromWhiteListMock(req); + public static async removeFromWhiteListMock(req: RemoveFromWhiteListMockRequest): Promise { + const response = await ExternalControlListsManagement.removeFromWhiteListMock(req); return response.payload; } - public static async updateExternalControlLists( - req: UpdateExternalControlListsRequest, - ): Promise { - const response = - await ExternalControlListsManagement.updateExternalControlLists(req); + public static async updateExternalControlLists(req: UpdateExternalControlListsRequest): Promise { + const response = await ExternalControlListsManagement.updateExternalControlLists(req); return response.payload; } - public static async getExternalControlListsCount( - req: GetExternalControlListsCountRequest, - ): Promise { - const response = - await ExternalControlListsManagement.getExternalControlListsCount(req); + public static async getExternalControlListsCount(req: GetExternalControlListsCountRequest): Promise { + const response = await ExternalControlListsManagement.getExternalControlListsCount(req); return response; } - public static async getExternalControlListsMembers( - req: GetExternalControlListsMembersRequest, - ): Promise { - const response = - await ExternalControlListsManagement.getExternalControlListsMembers(req); + public static async getExternalControlListsMembers(req: GetExternalControlListsMembersRequest): Promise { + const response = await ExternalControlListsManagement.getExternalControlListsMembers(req); return response; } - public static async isExternalControlList( - req: IsExternalControlListRequest, - ): Promise { - const response = - await ExternalControlListsManagement.isExternalControlList(req); + public static async isExternalControlList(req: IsExternalControlListRequest): Promise { + const response = await ExternalControlListsManagement.isExternalControlList(req); return response; } - public static async isAuthorizedBlackListMock( - req: IsAuthorizedBlackListMockRequest, - ): Promise { - const response = - await ExternalControlListsManagement.isAuthorizedBlackListMock(req); + public static async isAuthorizedBlackListMock(req: IsAuthorizedBlackListMockRequest): Promise { + const response = await ExternalControlListsManagement.isAuthorizedBlackListMock(req); return response; } - public static async isAuthorizedWhiteListMock( - req: IsAuthorizedWhiteListMockRequest, - ): Promise { - const response = - await ExternalControlListsManagement.isAuthorizedWhiteListMock(req); + public static async isAuthorizedWhiteListMock(req: IsAuthorizedWhiteListMockRequest): Promise { + const response = await ExternalControlListsManagement.isAuthorizedWhiteListMock(req); return response; } @@ -1317,9 +991,7 @@ export class SDKService { return response; } - public static async addExternalKycList( - req: AddExternalKycListRequest, - ): Promise { + public static async addExternalKycList(req: AddExternalKycListRequest): Promise { const response = await ExternalKycListsManagement.addExternalKycList(req); return response.payload; } @@ -1329,65 +1001,50 @@ export class SDKService { return response.payload; } - public static async revokeKycMock( - req: RevokeKycMockRequest, - ): Promise { + public static async revokeKycMock(req: RevokeKycMockRequest): Promise { const response = await ExternalKycListsManagement.revokeKycMock(req); return response.payload; } - public static async removeExternalKycList( - req: RemoveExternalKycListRequest, - ): Promise { - const response = - await ExternalKycListsManagement.removeExternalKycList(req); + public static async removeExternalKycList(req: RemoveExternalKycListRequest): Promise { + const response = await ExternalKycListsManagement.removeExternalKycList(req); return response.payload; } - public static async updateExternalKycLists( - req: UpdateExternalKycListsRequest, - ): Promise { - const response = - await ExternalKycListsManagement.updateExternalKycLists(req); + public static async updateExternalKycLists(req: UpdateExternalKycListsRequest): Promise { + const response = await ExternalKycListsManagement.updateExternalKycLists(req); return response.payload; } - public static async getExternalKycListsCount( - req: GetExternalKycListsCountRequest, - ): Promise { - const response = - await ExternalKycListsManagement.getExternalKycListsCount(req); + public static async getExternalKycListsCount(req: GetExternalKycListsCountRequest): Promise { + const response = await ExternalKycListsManagement.getExternalKycListsCount(req); return response; } - public static async getExternalKycListsMembers( - req: GetExternalKycListsMembersRequest, - ): Promise { - const response = - await ExternalKycListsManagement.getExternalKycListsMembers(req); + public static async getExternalKycListsMembers(req: GetExternalKycListsMembersRequest): Promise { + const response = await ExternalKycListsManagement.getExternalKycListsMembers(req); return response; } - public static async getKycStatusMock( - req: GetKycStatusMockRequest, - ): Promise { + public static async getKycStatusMock(req: GetKycStatusMockRequest): Promise { const response = await ExternalKycListsManagement.getKycStatusMock(req); return response; } - public static async isExternalKycList( - req: IsExternalKycListRequest, - ): Promise { + public static async isExternalKycList(req: IsExternalKycListRequest): Promise { const response = await ExternalKycListsManagement.isExternalKycList(req); return response; } - public static async isExternallyKycGranted( - req: IsExternallyGrantedRequest, - ): Promise { + public static async isExternallyKycGranted(req: IsExternallyGrantedRequest): Promise { const response = await ExternalKycListsManagement.isExternallyGranted(req); return response; } + + public static async fullRedeemAtMaturity(req: FullRedeemAtMaturityRequest): Promise { + const response = await Bond.fullRedeemAtMaturity(req); + return response.payload; + } } export default SDKService; diff --git a/apps/ats/web/src/utils/SecurityRole.ts b/apps/ats/web/src/utils/SecurityRole.ts index 2a39ccf05..7b84ec20f 100644 --- a/apps/ats/web/src/utils/SecurityRole.ts +++ b/apps/ats/web/src/utils/SecurityRole.ts @@ -228,4 +228,6 @@ export enum SecurityRole { _CONTROL_LIST_MANAGER_ROLE = '0x0e625647b832ec7d4146c12550c31c065b71e0a698095568fd8320dd2aa72e75', _KYC_MANAGER_ROLE = '0x8ebae577938c1afa7fb3dc7b06459c79c86ffd2ac9805b6da92ee4cbbf080449', _INTERNAL_KYC_MANAGER_ROLE = '0x3916c5c9e68488134c2ee70660332559707c133d0a295a25971da4085441522e', + _TREX_OWNER_ROLE = '0x03ce2fdc316501dd97f5219e6ad908a3238f1e90f910aa17b627f801a6aafab7', + _PROCEED_RECIPIENT_MANAGER_ROLE = '0xebc53fe99fea28c7aa9476a714959af5b931f34a8a8734365ec63113198d512f', } diff --git a/apps/ats/web/src/utils/constants.ts b/apps/ats/web/src/utils/constants.ts index 9503ec475..39f6d60c0 100644 --- a/apps/ats/web/src/utils/constants.ts +++ b/apps/ats/web/src/utils/constants.ts @@ -220,9 +220,32 @@ export enum User { export const LOCALE = 'en-US'; export const COUPONS_FACTOR = 1000; -export const NOMINAL_VALUE_FACTOR = 100; +export const NOMINAL_VALUE_DECIMALS = 2; export const DATE_TIME_FORMAT = 'dd/MM/yyyy HH:mm:ss'; +// * Time periods (in seconds and milliseconds) +export const TIME_PERIODS_S = { + SECOND: 1, + MINUTE: 60, + HOUR: 60 * 60, + DAY: 24 * 60 * 60, + WEEK: 7 * 24 * 60 * 60, + MONTH: 30 * 24 * 60 * 60, + QUARTER: 90 * 24 * 60 * 60, + YEAR: 365 * 24 * 60 * 60, +}; + +export const TIME_PERIODS_MS = { + SECOND: TIME_PERIODS_S.SECOND * 1000, + MINUTE: TIME_PERIODS_S.MINUTE * 1000, + HOUR: TIME_PERIODS_S.HOUR * 1000, + DAY: TIME_PERIODS_S.DAY * 1000, + WEEK: TIME_PERIODS_S.WEEK * 1000, + MONTH: TIME_PERIODS_S.MONTH * 1000, + QUARTER: TIME_PERIODS_S.QUARTER * 1000, + YEAR: TIME_PERIODS_S.YEAR * 1000, +}; + export const DEFAULT_PARTITION = '0x0000000000000000000000000000000000000000000000000000000000000001'; diff --git a/apps/ats/web/src/utils/format.ts b/apps/ats/web/src/utils/format.ts index a5387f068..cbcadad21 100644 --- a/apps/ats/web/src/utils/format.ts +++ b/apps/ats/web/src/utils/format.ts @@ -207,7 +207,7 @@ import _capitalize from 'lodash/capitalize'; import _formatDate from 'date-fns/format'; import { TimeUnit } from './types'; import i18n from '../i18n'; -import { LOCALE } from './constants'; +import { LOCALE, TIME_PERIODS_S } from './constants'; export const formatAddressAccount = (address: string) => `${_capitalize( address.slice(0, 2), @@ -292,6 +292,57 @@ export const formatPeriod = ({ return `${amount} ${unit}`; }; +/** + * Formats a period in seconds to human-readable format + */ +export const formatCouponPeriod = (periodInSeconds: number): string => { + if (periodInSeconds >= TIME_PERIODS_S.YEAR) { + const years = Math.floor(periodInSeconds / TIME_PERIODS_S.YEAR); + return `${years} ${years === 1 ? 'Year' : 'Years'}`; + } + if (periodInSeconds >= TIME_PERIODS_S.QUARTER) { + const quarters = Math.floor(periodInSeconds / TIME_PERIODS_S.QUARTER); + return `${quarters} ${quarters === 1 ? 'Quarter' : 'Quarters'}`; + } + if (periodInSeconds >= TIME_PERIODS_S.MONTH) { + const months = Math.floor(periodInSeconds / TIME_PERIODS_S.MONTH); + return `${months} ${months === 1 ? 'Month' : 'Months'}`; + } + if (periodInSeconds >= TIME_PERIODS_S.WEEK) { + const weeks = Math.floor(periodInSeconds / TIME_PERIODS_S.WEEK); + return `${weeks} ${weeks === 1 ? 'Week' : 'Weeks'}`; + } + if (periodInSeconds >= TIME_PERIODS_S.DAY) { + const days = Math.floor(periodInSeconds / TIME_PERIODS_S.DAY); + return `${days} ${days === 1 ? 'Day' : 'Days'}`; + } + return `${periodInSeconds} Seconds`; +}; + +/** + * Validates if a period is within acceptable bounds + * Period is REQUIRED for all coupon operations + */ +export const validateCouponPeriod = ( + periodInSeconds: number, + maturityDate?: Date, +): string | true => { + // Period is required - cannot be null or undefined + if (!periodInSeconds || periodInSeconds < 0) { + return 'Coupon period is required and must be greater or equal to 0'; + } + + if (maturityDate) { + const timeToMaturity = Math.floor( + (maturityDate.getTime() - Date.now()) / 1000, + ); + if (periodInSeconds > timeToMaturity) { + return 'Period cannot exceed bond maturity date'; + } + } + return true; +}; + //TODO: remove? export const formatNumber = ( value: number | string | null, diff --git a/apps/ats/web/src/utils/rules.ts b/apps/ats/web/src/utils/rules.ts index a7782ffa0..94ad0f932 100644 --- a/apps/ats/web/src/utils/rules.ts +++ b/apps/ats/web/src/utils/rules.ts @@ -208,10 +208,10 @@ import isBefore from 'date-fns/isBefore'; import isToday from 'date-fns/isToday'; import isEqual from 'date-fns/isEqual'; import i18n from '../i18n'; -import { formatDate, toDate } from './format'; +import { formatDate, toDate, validateCouponPeriod } from './format'; -const t = (key: string, options?: object) => { - return i18n.t(`rules:${key}`, options || {}); +const t = (key: string, options?: Record) => { + return i18n.t(`rules:${key}`, options); }; export const maxLength = (value: number) => ({ @@ -321,3 +321,36 @@ export const isValidHederaId = (val: string) => { const maskRegex = /^[0-9]\.[0-9]\.[0-9]{1,7}$/; return maskRegex.test(val) || t('isValidHederaId'); }; + +export const isValidHex = (val: string) => { + const hexRegex = /^0x[0-9a-fA-F]*$/; + if (!hexRegex.test(val)) { + return t('isValidHex'); + } + + const hexPart = val.slice(2); + if (hexPart.length % 2 !== 0) { + return t('isValidHex'); + } + + return true; +}; + +export const isValidCouponPeriod = (val: string) => { + try { + // Period is required - cannot be empty or null + if (!val || val.trim() === '') { + return 'Coupon period is required'; + } + + const periodValue = parseInt(val); + if (isNaN(periodValue) || periodValue <= 0) { + return 'Coupon period must be a valid positive number'; + } + + const validation = validateCouponPeriod(periodValue); + return validation === true || validation; + } catch (error) { + return 'Invalid coupon period'; + } +}; diff --git a/apps/ats/web/src/views/CreateBond/Components/StepConfiguration.tsx b/apps/ats/web/src/views/CreateBond/Components/StepConfiguration.tsx index 7dd71c96b..d65d315b3 100644 --- a/apps/ats/web/src/views/CreateBond/Components/StepConfiguration.tsx +++ b/apps/ats/web/src/views/CreateBond/Components/StepConfiguration.tsx @@ -1,211 +1,8 @@ -/* - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ +// SPDX-License-Identifier: Apache-2.0 - 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. - -*/ - -import { useEffect } from 'react'; -import { HStack, Stack } from '@chakra-ui/react'; -import { useTranslation } from 'react-i18next'; +import { useEffect } from "react"; +import { HStack, Stack } from "@chakra-ui/react"; +import { useTranslation } from "react-i18next"; import { PhosphorIcon, Text, @@ -213,30 +10,29 @@ import { InputController, InputNumberController, Tooltip, -} from 'io-bricks-ui'; -import { CancelButton } from '../../../components/CancelButton'; -import { NextStepButton } from './NextStepButton'; -import { PreviousStepButton } from './PreviousStepButton'; -import { required, isAfterDate, min } from '../../../utils/rules'; -import { ICreateBondFormValues } from '../ICreateBondFormValues'; -import { useFormContext, useFormState } from 'react-hook-form'; -import { FormStepContainer } from '../../../components/FormStepContainer'; -import { formatNumber } from '../../../utils/format'; -import { Info } from '@phosphor-icons/react'; -import { addDays } from 'date-fns'; +} from "io-bricks-ui"; +import { CancelButton } from "../../../components/CancelButton"; +import { NextStepButton } from "./NextStepButton"; +import { PreviousStepButton } from "./PreviousStepButton"; +import { required, isAfterDate, min } from "../../../utils/rules"; +import { ICreateBondFormValues } from "../ICreateBondFormValues"; +import { useFormContext, useFormState } from "react-hook-form"; +import { FormStepContainer } from "../../../components/FormStepContainer"; +import { formatNumber } from "../../../utils/format"; +import { Info } from "@phosphor-icons/react"; +import { addDays } from "date-fns"; export const StepConfiguration = () => { - const { t } = useTranslation('security', { keyPrefix: 'createBond' }); - const { control, watch, setValue, getValues } = - useFormContext(); + const { t } = useTranslation("security", { keyPrefix: "createBond" }); + const { control, watch, setValue, getValues } = useFormContext(); const stepFormState = useFormState({ control }); const today = new Date(); - const startingDate = watch('startingDate'); - const nominalValue = watch('nominalValue'); - const numberOfUnits = watch('numberOfUnits'); - const totalAmount = watch('totalAmount'); - const decimals = getValues('decimals'); + const startingDate = watch("startingDate"); + const nominalValue = watch("nominalValue"); + const numberOfUnits = watch("numberOfUnits"); + const totalAmount = watch("totalAmount"); + const decimals = getValues("decimals"); useEffect(() => { let totalAmount = 0; @@ -244,24 +40,20 @@ export const StepConfiguration = () => { totalAmount = Number(nominalValue) * Number(numberOfUnits); } - setValue('totalAmount', formatNumber(totalAmount, {}, 2)); + setValue("totalAmount", formatNumber(totalAmount, {}, 18)); }, [nominalValue, numberOfUnits, setValue]); return ( - {t('stepConfiguration.title')} - - {t('stepConfiguration.subtitle')} - + {t("stepConfiguration.title")} + {t("stepConfiguration.subtitle")} - {t('stepConfiguration.mandatoryFields')} + {t("stepConfiguration.mandatoryFields")} - - {t('stepConfiguration.currency')} - + {t("stepConfiguration.currency")} { - - {t('stepConfiguration.numberOfUnits')}* - - + {t("stepConfiguration.numberOfUnits")}* + @@ -294,7 +81,7 @@ export const StepConfiguration = () => { }} decimalScale={decimals} fixedDecimalScale={true} - placeholder={t('stepConfiguration.numberOfUnitsPlaceHolder')} + placeholder={t("stepConfiguration.numberOfUnitsPlaceHolder")} backgroundColor="neutral.600" size="md" thousandSeparator="," @@ -303,13 +90,8 @@ export const StepConfiguration = () => { - - {t('stepConfiguration.nominalValue')}* - - + {t("stepConfiguration.nominalValue")}* + @@ -320,9 +102,8 @@ export const StepConfiguration = () => { required, min: min(0), }} - decimalScale={2} - fixedDecimalScale={true} - placeholder={t('stepConfiguration.nominalValuePlaceHolder')} + decimalScale={18} + placeholder={t("stepConfiguration.nominalValuePlaceHolder")} backgroundColor="neutral.600" size="md" thousandSeparator="," @@ -331,13 +112,8 @@ export const StepConfiguration = () => { - - {t('stepConfiguration.totalAmount')}* - - + {t("stepConfiguration.totalAmount")}* + @@ -354,13 +130,8 @@ export const StepConfiguration = () => { - - {t('stepConfiguration.startingDate')}* - - + {t("stepConfiguration.startingDate")}* + @@ -371,20 +142,15 @@ export const StepConfiguration = () => { rules={{ required, }} - placeholder={t('stepConfiguration.startingDatePlaceHolder')} + placeholder={t("stepConfiguration.startingDatePlaceHolder")} backgroundColor="neutral.600" size="md" /> - - {t('stepConfiguration.maturityDate')}* - - + {t("stepConfiguration.maturityDate")}* + @@ -396,18 +162,12 @@ export const StepConfiguration = () => { required, validate: isAfterDate(new Date(startingDate)), }} - placeholder={t('stepConfiguration.maturityDatePlaceHolder')} + placeholder={t("stepConfiguration.maturityDatePlaceHolder")} backgroundColor="neutral.600" size="md" /> - + diff --git a/packages/ats/contracts/scripts/contractsMethods.ts b/apps/ats/web/src/views/CreateBond/Components/StepProceedRecipients.tsx similarity index 66% rename from packages/ats/contracts/scripts/contractsMethods.ts rename to apps/ats/web/src/views/CreateBond/Components/StepProceedRecipients.tsx index 4e9aa87c4..9e6bb9d73 100644 --- a/packages/ats/contracts/scripts/contractsMethods.ts +++ b/apps/ats/web/src/views/CreateBond/Components/StepProceedRecipients.tsx @@ -203,239 +203,199 @@ */ -import { Client, ContractId } from '@hashgraph/sdk' +import { Flex, HStack, Stack } from '@chakra-ui/react'; +import { useTranslation } from 'react-i18next'; import { - ProxyAdmin__factory, - BusinessLogicResolver__factory, - IStaticFunctionSelectors__factory, - DiamondCutManager__factory, -} from '@typechain' -import { contractCall } from './contractsLifeCycle/utils' -import { FacetConfiguration } from './resolverDiamondCut' -import { GAS_LIMIT } from './constants' - -export async function getProxyImplementation( - proxyAdminAddress: ContractId, - client: Client, - proxyAddress: string -): Promise { - const params = [proxyAddress] - const result = await contractCall( - proxyAdminAddress, - 'getProxyImplementation', - params, - client, - 60000, - ProxyAdmin__factory.abi - ) - return result[0] + PhosphorIcon, + Text, + Table, + Button, + InputController, +} from 'io-bricks-ui'; +import { CancelButton } from '../../../components/CancelButton'; +import { NextStepButton } from './NextStepButton'; +import { PreviousStepButton } from './PreviousStepButton'; +import { ICreateBondFormValues } from '../ICreateBondFormValues'; +import { useFormContext, useFormState, useForm } from 'react-hook-form'; +import { FormStepContainer } from '../../../components/FormStepContainer'; +import { Trash } from '@phosphor-icons/react'; +import { createColumnHelper } from '@tanstack/table-core'; +import { isValidHederaId, required } from '../../../utils/rules'; + +interface IProceedRecipient { + address: string; + data?: string; } -export async function getOwner( - proxyAdminAddress: ContractId, - client: Client -): Promise { - const params: string[] = [] - const result = await contractCall( - proxyAdminAddress, - 'owner', - params, - client, - 60000, - ProxyAdmin__factory.abi - ) - return result[0] +interface ILocalProceedRecipientForm { + address: string; + data?: string; } -export interface BusinessLogicRegistryData { - businessLogicKey: string - businessLogicAddress: string -} - -export async function registerBusinessLogics( - businessLogicRegistryData: BusinessLogicRegistryData[], - proxyAddress: ContractId, - client: Client -) { - const params = [businessLogicRegistryData] - - await contractCall( - proxyAddress, - 'registerBusinessLogics', - params, - client, - 7800000, - BusinessLogicResolver__factory.abi - ) -} - -export async function createConfiguration( - configId: string, - facetIds: string[], - facetVersions: number[], - proxyAddress: ContractId, - client: Client -) { - const facetConfigurations: FacetConfiguration[] = [] - facetIds.forEach((id, index) => - facetConfigurations.push({ id, version: facetVersions[index] }) - ) - - const params = [configId, facetConfigurations] - - await contractCall( - proxyAddress, - 'createConfiguration', - params, - client, - GAS_LIMIT.businessLogicResolver.createConfiguration, - DiamondCutManager__factory.abi - ) -} - -export async function getConfigurationsLength( - proxyAddress: ContractId, - client: Client -) { - const params: string[] = [] - - return await contractCall( - proxyAddress, - 'getConfigurationsLength', - params, - client, - 70000, - DiamondCutManager__factory.abi - ) -} - -export async function getLatestVersionByConfiguration( - configId: string, - proxyAddress: ContractId, - client: Client -) { - const params = [configId] - - return await contractCall( - proxyAddress, - 'getLatestVersionByConfiguration', - params, - client, - 7800000, - DiamondCutManager__factory.abi - ) -} - -export async function getFacetsLengthByConfigurationIdAndVersion( - configId: string, - version: number, - proxyAddress: ContractId, - client: Client -) { - const params = [configId, version] - - return await contractCall( - proxyAddress, - 'getFacetsLengthByConfigurationIdAndVersion', - params, - client, - 70000, - DiamondCutManager__factory.abi - ) -} - -export async function getFacetsByConfigurationIdAndVersion( - configId: string, - version: number, - pageIndex: number, - pageLength: number, - proxyAddress: ContractId, - client: Client -) { - const params = [configId, version, pageIndex, pageLength] - - return await contractCall( - proxyAddress, - 'getFacetsByConfigurationIdAndVersion', - params, - client, - 7800000, - DiamondCutManager__factory.abi - ) -} - -export async function getFacetSelectorsLengthByConfigurationIdVersionAndFacetId( - configId: string, - version: number, - facet: string, - proxyAddress: ContractId, - client: Client -) { - const params = [configId, version, facet] - - return await contractCall( - proxyAddress, - 'getFacetSelectorsLengthByConfigurationIdVersionAndFacetId', - params, - client, - 70000, - DiamondCutManager__factory.abi - ) -} - -export async function getFacetSelectorsByConfigurationIdVersionAndFacetId( - configId: string, - version: number, - facet: string, - pageIndex: number, - pageLength: number, - proxyAddress: ContractId, - client: Client -) { - const params = [configId, version, facet, pageIndex, pageLength] - - return await contractCall( - proxyAddress, - 'getFacetSelectorsByConfigurationIdVersionAndFacetId', - params, - client, - 7800000, - DiamondCutManager__factory.abi - ) -} - -export async function getBusinessLogicKeys( - proxyAddress: ContractId, - client: Client -) { - const params = [0, 100] - - return await contractCall( - proxyAddress, - 'getBusinessLogicKeys', - params, - client, - 7800000, - BusinessLogicResolver__factory.abi - ) -} - -export async function getStaticResolverKey( - facetAddress: ContractId, - client: Client -) { - const params: string[] = [] - const result = await contractCall( - facetAddress, - 'getStaticResolverKey', - params, - client, - 60000, - IStaticFunctionSelectors__factory.abi - ) - return result[0] -} - -export function getSolidityAddress(facet: ContractId) { - return facet.toSolidityAddress() -} +export const StepProceedRecipients = () => { + const { t } = useTranslation('security', { keyPrefix: 'createBond' }); + const { control, watch, setValue } = useFormContext(); + const stepFormState = useFormState({ control }); + + const { + control: localControl, + handleSubmit: handleLocalSubmit, + reset: resetLocalForm, + formState: localFormState, + } = useForm({ + defaultValues: { + address: '', + data: '', + }, + mode: 'onChange', + }); + + const currentProceedRecipientsIds = watch('proceedRecipientsIds') || []; + const currentProceedRecipientsData = watch('proceedRecipientsData') || []; + + const proceedRecipients: IProceedRecipient[] = + currentProceedRecipientsIds.map((address, index) => ({ + address, + data: currentProceedRecipientsData[index] || '', + })); + + const handleAddProceedRecipient = handleLocalSubmit((data) => { + const newProceedRecipientsIds = [ + ...currentProceedRecipientsIds, + data.address.trim(), + ]; + const newProceedRecipientsData = [ + ...currentProceedRecipientsData, + data?.data?.trim() ?? '', + ]; + + setValue('proceedRecipientsIds', newProceedRecipientsIds); + setValue('proceedRecipientsData', newProceedRecipientsData); + + resetLocalForm(); + }); + + const handleRemoveProceedRecipient = (addressToRemove: string) => { + const indexToRemove = currentProceedRecipientsIds.indexOf(addressToRemove); + if (indexToRemove !== -1) { + const newProceedRecipientsIds = currentProceedRecipientsIds.filter( + (_, index) => index !== indexToRemove, + ); + const newProceedRecipientsData = currentProceedRecipientsData.filter( + (_, index) => index !== indexToRemove, + ); + + setValue('proceedRecipientsIds', newProceedRecipientsIds); + setValue('proceedRecipientsData', newProceedRecipientsData); + } + }; + + const columnsHelper = createColumnHelper(); + + const columns = [ + columnsHelper.accessor('address', { + header: t('stepProceedRecipients.address'), + enableSorting: false, + }), + columnsHelper.accessor('data', { + header: t('stepProceedRecipients.data'), + enableSorting: false, + }), + columnsHelper.display({ + id: 'actions', + header: t('stepProceedRecipients.actions'), + enableSorting: false, + cell(props) { + const { + row: { + original: { address }, + }, + } = props; + + return ( + + ); + }, + }), + ]; + + return ( + + + + {t('stepProceedRecipients.title')} + + + {t('stepProceedRecipients.subtitle')} + + + {t('stepProceedRecipients.mandatoryFields')} + + + + + {t('stepProceedRecipients.address')} + + + !value || + isValidHederaId(value) || + t('stepProceedRecipients.invalidHederaId'), + }} + /> + + + + {t('stepProceedRecipients.data')} + + + + + + + + The list is empty + + } + /> + + + + + + + ); +}; diff --git a/apps/ats/web/src/views/CreateBond/Components/StepReview.tsx b/apps/ats/web/src/views/CreateBond/Components/StepReview.tsx index 7a6b59505..a59a28908 100644 --- a/apps/ats/web/src/views/CreateBond/Components/StepReview.tsx +++ b/apps/ats/web/src/views/CreateBond/Components/StepReview.tsx @@ -1,310 +1,92 @@ -/* - 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. - -*/ - -import { - HStack, - SimpleGrid, - Stack, - VStack, - useDisclosure, -} from '@chakra-ui/react'; -import { useTranslation } from 'react-i18next'; -import { PreviousStepButton } from './PreviousStepButton'; -import { PhosphorIcon } from 'io-bricks-ui'; -import { useFormContext } from 'react-hook-form'; -import { - Button, - DetailReview, - DetailReviewProps, - InfoDivider, - PopUp, -} from 'io-bricks-ui'; -import { useCreateBond } from '../../../hooks/queries/useCreateBond'; -import { useWalletStore } from '../../../store/walletStore'; -import { CreateBondRequest } from '@hashgraph/asset-tokenization-sdk'; -import { ICreateBondFormValues } from '../ICreateBondFormValues'; -import { RouterManager } from '../../../router/RouterManager'; -import { RouteName } from '../../../router/RouteName'; -import { WarningCircle, Question } from '@phosphor-icons/react'; -import { transformCouponType } from '../CouponType'; -import { - dateToUnixTimestamp, - formatNumber, - numberToExponential, -} from '../../../utils/format'; -import { FormStepContainer } from '../../../components/FormStepContainer'; -import { COUPONS_FACTOR, NOMINAL_VALUE_FACTOR } from '../../../utils/constants'; -import { CountriesList } from '../../CreateSecurityCommons/CountriesList'; -import { - COUNTRY_LIST_ALLOWED, - COUNTRY_LIST_BLOCKED, -} from '../../../utils/countriesConfig'; +// SPDX-License-Identifier: Apache-2.0 + +import { HStack, SimpleGrid, Stack, VStack, useDisclosure } from "@chakra-ui/react"; +import { useTranslation } from "react-i18next"; +import { PreviousStepButton } from "./PreviousStepButton"; +import { PhosphorIcon, Table, Text } from "io-bricks-ui"; +import { useFormContext } from "react-hook-form"; +import { Button, DetailReview, DetailReviewProps, InfoDivider, PopUp } from "io-bricks-ui"; +import { useCreateBond } from "../../../hooks/queries/useCreateBond"; +import { useWalletStore } from "../../../store/walletStore"; +import { CreateBondRequest } from "@hashgraph/asset-tokenization-sdk"; +import { ICreateBondFormValues } from "../ICreateBondFormValues"; +import { RouterManager } from "../../../router/RouterManager"; +import { RouteName } from "../../../router/RouteName"; +import { WarningCircle, Question } from "@phosphor-icons/react"; +import { dateToUnixTimestamp, formatNumber, numberToExponential, textToHex } from "../../../utils/format"; +import { FormStepContainer } from "../../../components/FormStepContainer"; +import { CountriesList } from "../../CreateSecurityCommons/CountriesList"; +import { COUNTRY_LIST_ALLOWED, COUNTRY_LIST_BLOCKED } from "../../../utils/countriesConfig"; +import { createColumnHelper } from "@tanstack/table-core"; + +interface IProceedRecipient { + address: string; + data?: string; +} export const StepReview = () => { - const { t } = useTranslation('security', { keyPrefix: 'createBond' }); - const { t: tRegulation } = useTranslation('security', { - keyPrefix: 'regulation', + const { t } = useTranslation("security", { keyPrefix: "createBond" }); + const { t: tRegulation } = useTranslation("security", { + keyPrefix: "regulation", }); const { mutate: createBond, isLoading } = useCreateBond(); const { address } = useWalletStore(); - const { - isOpen: isOpenCancel, - onClose: onCloseCancel, - onOpen: onOpenCancel, - } = useDisclosure(); - const { - isOpen: isOpenCreate, - onClose: onCloseCreate, - onOpen: onOpenCreate, - } = useDisclosure(); + const { isOpen: isOpenCancel, onClose: onCloseCancel, onOpen: onOpenCancel } = useDisclosure(); + const { isOpen: isOpenCreate, onClose: onCloseCreate, onOpen: onOpenCreate } = useDisclosure(); const { getValues } = useFormContext(); - const name = getValues('name'); - const symbol = getValues('symbol'); - const decimals = getValues('decimals'); - const isin = getValues('isin'); - const currency = getValues('currency'); - const numberOfUnits = getValues('numberOfUnits'); - const nominalValue = getValues('nominalValue'); - const totalAmount = getValues('totalAmount'); - const startingDate = getValues('startingDate'); - const maturityDate = getValues('maturityDate'); - const couponType = getValues('couponType'); - let couponFrequency = getValues('couponFrequency'); - let couponRate = getValues('couponRate'); - let firstCouponDate = getValues('firstCouponDate'); - const lastCouponDate = getValues('lastCouponDate'); - const totalCoupons = getValues('totalCoupons'); - const isBlocklist = getValues('isBlocklist'); - const isControllable = getValues('isControllable'); - const isClearing = getValues('isClearing'); - const regulationType = getValues('regulationType'); - const regulationSubType = getValues('regulationSubType'); - const countriesListType = getValues('countriesListType'); - let countriesList = getValues('countriesList'); - const externalPausesList = getValues('externalPausesList'); - const externalControlList = getValues('externalControlList'); - const externalKYCList = getValues('externalKYCList'); - const internalKycActivated = getValues('internalKycActivated'); - const complianceId = getValues('complianceId'); - const identityRegistryId = getValues('identityRegistryId'); - - countriesList = countriesList.concat( - countriesListType === 2 ? COUNTRY_LIST_ALLOWED : COUNTRY_LIST_BLOCKED, - ); + const name = getValues("name"); + const symbol = getValues("symbol"); + const decimals = getValues("decimals"); + const isin = getValues("isin"); + const currency = getValues("currency"); + const numberOfUnits = getValues("numberOfUnits"); + const nominalValue = getValues("nominalValue"); + const nominalValueParts = nominalValue.toString().split("."); + const nominalValueDynamicDecimals = nominalValueParts.length > 1 ? nominalValueParts[1].length : 0; + const nominalValueRawValue = nominalValueParts.join(""); + const totalAmount = getValues("totalAmount"); + const startingDate = getValues("startingDate"); + const maturityDate = getValues("maturityDate"); + const isBlocklist = getValues("isBlocklist"); + const isControllable = getValues("isControllable"); + const isClearing = getValues("isClearing"); + const regulationType = getValues("regulationType"); + const regulationSubType = getValues("regulationSubType"); + const countriesListType = getValues("countriesListType"); + let countriesList = getValues("countriesList"); + const externalPausesList = getValues("externalPausesList"); + const externalControlList = getValues("externalControlList"); + const externalKYCList = getValues("externalKYCList"); + const internalKycActivated = getValues("internalKycActivated"); + const complianceId = getValues("complianceId"); + const identityRegistryId = getValues("identityRegistryId"); + const proceedRecipientsIds = getValues("proceedRecipientsIds"); + const proceedRecipientsData = getValues("proceedRecipientsData"); + + countriesList = countriesList.concat(countriesListType === 2 ? COUNTRY_LIST_ALLOWED : COUNTRY_LIST_BLOCKED); + + const proceedRecipientsTableData: IProceedRecipient[] = (proceedRecipientsIds || []).map((address, index) => ({ + address, + data: (proceedRecipientsData || [])[index] || "", + })); + + const columnsHelper = createColumnHelper(); + const columnsProceedRecipients = [ + columnsHelper.accessor("address", { + header: t("stepProceedRecipients.address"), + enableSorting: false, + }), + columnsHelper.accessor("data", { + header: t("stepProceedRecipients.data"), + enableSorting: false, + }), + ]; const submit = () => { - if (couponType === 2) { - couponRate = 0; - couponFrequency = '0'; - firstCouponDate = '0'; - } - const request = new CreateBondRequest({ name, symbol, @@ -318,41 +100,29 @@ export const StepReview = () => { isMultiPartition: false, diamondOwnerAccount: address, numberOfUnits: numberToExponential(numberOfUnits, decimals), - nominalValue: (nominalValue * NOMINAL_VALUE_FACTOR).toString(), + nominalValue: nominalValueRawValue, + nominalValueDecimals: nominalValueDynamicDecimals, startingDate: dateToUnixTimestamp(startingDate), maturityDate: dateToUnixTimestamp(maturityDate), - couponFrequency: ( - parseInt(couponFrequency) * - (30 * 24 * 60 * 60) - ).toString(), - couponRate: (couponRate * COUPONS_FACTOR).toString(), - firstCouponDate: - firstCouponDate != '0' - ? dateToUnixTimestamp(firstCouponDate) - : firstCouponDate, - currency: - '0x' + - currency.charCodeAt(0) + - currency.charCodeAt(1) + - currency.charCodeAt(2), + currency: "0x" + currency.charCodeAt(0) + currency.charCodeAt(1) + currency.charCodeAt(2), regulationType: regulationType, regulationSubType: regulationSubType, isCountryControlListWhiteList: countriesListType === 2, countries: countriesList.map((country) => country).toString(), - info: '', - configId: process.env.REACT_APP_BOND_CONFIG_ID ?? '', - configVersion: parseInt(process.env.REACT_APP_BOND_CONFIG_VERSION ?? '0'), + info: "", + configId: process.env.REACT_APP_BOND_CONFIG_ID ?? "", + configVersion: parseInt(process.env.REACT_APP_BOND_CONFIG_VERSION ?? "0"), ...(externalPausesList && externalPausesList.length > 0 && { - externalPauses: externalPausesList, + externalPausesIds: externalPausesList, }), ...(externalControlList && externalControlList.length > 0 && { - externalControlLists: externalControlList, + externalControlListsIds: externalControlList, }), ...(externalKYCList && externalKYCList.length > 0 && { - externalKycLists: externalKYCList, + externalKycListsIds: externalKYCList, }), internalKycActivated, ...(complianceId && { @@ -361,6 +131,12 @@ export const StepReview = () => { ...(identityRegistryId && { identityRegistryId: identityRegistryId, }), + ...(proceedRecipientsIds && { + proceedRecipientsIds: proceedRecipientsIds, + }), + ...(proceedRecipientsData && { + proceedRecipientsData: proceedRecipientsData.map((data) => textToHex(data)), + }), }); createBond(request); @@ -368,132 +144,87 @@ export const StepReview = () => { const tokenDetails: DetailReviewProps[] = [ { - title: t('stepTokenDetails.name'), + title: t("stepTokenDetails.name"), value: name, }, { - title: t('stepTokenDetails.symbol'), + title: t("stepTokenDetails.symbol"), value: symbol, }, { - title: t('stepTokenDetails.decimals'), + title: t("stepTokenDetails.decimals"), value: decimals, }, { - title: t('stepTokenDetails.isin'), + title: t("stepTokenDetails.isin"), value: isin, }, ]; const configurationDetails: DetailReviewProps[] = [ { - title: t('stepConfiguration.currency'), + title: t("stepConfiguration.currency"), value: currency, }, { - title: t('stepConfiguration.numberOfUnits'), + title: t("stepConfiguration.numberOfUnits"), value: formatNumber(numberOfUnits, {}, decimals), }, { - title: t('stepConfiguration.nominalValue'), - value: formatNumber(nominalValue, {}, 2), + title: t("stepConfiguration.nominalValue"), + value: formatNumber(nominalValue, {}, nominalValueDynamicDecimals), }, { - title: t('stepConfiguration.totalAmount'), + title: t("stepConfiguration.totalAmount"), value: totalAmount, }, { - title: t('stepConfiguration.startingDate'), + title: t("stepConfiguration.startingDate"), value: new Date(startingDate).toLocaleDateString(), }, { - title: t('stepConfiguration.maturityDate'), + title: t("stepConfiguration.maturityDate"), value: new Date(maturityDate).toLocaleDateString(), }, ]; const erc3643Details: DetailReviewProps[] = [ { - title: t('stepERC3643.complianceId'), - value: complianceId ?? '-', + title: t("stepERC3643.complianceId"), + value: complianceId ?? "-", }, { - title: t('stepERC3643.identityRegistryId'), - value: identityRegistryId ?? '-', + title: t("stepERC3643.identityRegistryId"), + value: identityRegistryId ?? "-", }, ]; const externalManagement: DetailReviewProps[] = [ { - title: t('stepExternalManagement.externalPause'), - value: externalPausesList - ? externalPausesList?.map((pause) => ' ' + pause).toString() - : '-', - }, - { - title: t('stepExternalManagement.externalControl'), - value: externalControlList - ? externalControlList?.map((control) => ' ' + control).toString() - : '-', + title: t("stepExternalManagement.externalPause"), + value: externalPausesList ? externalPausesList?.map((pause) => " " + pause).toString() : "-", }, { - title: t('stepExternalManagement.externalKYC'), - value: externalKYCList - ? externalKYCList?.map((control) => ' ' + control).toString() - : '-', + title: t("stepExternalManagement.externalControl"), + value: externalControlList ? externalControlList?.map((control) => " " + control).toString() : "-", }, - ]; - - const couponDetails: DetailReviewProps[] = [ { - title: t('stepCoupon.couponType'), - value: transformCouponType(couponType), + title: t("stepExternalManagement.externalKYC"), + value: externalKYCList ? externalKYCList?.map((control) => " " + control).toString() : "-", }, ]; - if (couponType === 1) { - couponDetails.push( - { - title: t('stepCoupon.couponRate'), - value: formatNumber(couponRate) + ' %', - }, - { - title: t('stepCoupon.couponFrequency'), - value: 'Every ' + couponFrequency + ' months', - }, - { - title: t('stepCoupon.firstCouponDate'), - value: new Date(firstCouponDate).toLocaleDateString(), - }, - { - title: t('stepCoupon.lastCouponDate'), - value: lastCouponDate, - }, - { - title: t('stepCoupon.totalCoupons'), - value: totalCoupons, - }, - ); - } const regulationDetails: DetailReviewProps[] = [ { - title: tRegulation('regulationTypeReview'), + title: tRegulation("regulationTypeReview"), value: tRegulation(`regulationType_${regulationType}`), }, { - title: tRegulation('regulationSubTypeReview'), + title: tRegulation("regulationSubTypeReview"), value: tRegulation(`regulationSubType_${regulationSubType}`), }, { - title: - countriesListType === 2 - ? tRegulation('allowedCountriesReview') - : tRegulation('blockedCountriesReview'), - value: countriesList - .map( - (country) => - ' ' + CountriesList[country as keyof typeof CountriesList], - ) - .toString(), + title: countriesListType === 2 ? tRegulation("allowedCountriesReview") : tRegulation("blockedCountriesReview"), + value: countriesList.map((country) => " " + CountriesList[country as keyof typeof CountriesList]).toString(), }, ]; @@ -501,82 +232,56 @@ export const StepReview = () => { - + {tokenDetails.map((props) => ( ))} - + {configurationDetails.map((props) => ( ))} - - - {couponDetails.map((props) => ( - - ))} - + + + {proceedRecipientsTableData.length > 0 && ( +
+ )} + {!proceedRecipientsTableData.length && -} + - + {erc3643Details.map((props) => ( ))} - + {externalManagement.map((props) => ( ))} - + {regulationDetails.map((props) => ( ))} - + - @@ -587,31 +292,31 @@ export const StepReview = () => { isOpen={isOpenCancel} onClose={onCloseCancel} icon={} - title={t('cancelSecurityPopUp.title')} - description={t('cancelSecurityPopUp.description')} - confirmText={t('cancelSecurityPopUp.confirmText')} + title={t("cancelSecurityPopUp.title")} + description={t("cancelSecurityPopUp.description")} + confirmText={t("cancelSecurityPopUp.confirmText")} onConfirm={() => { RouterManager.to(RouteName.Dashboard); onCloseCancel(); }} onCancel={onCloseCancel} - cancelText={t('cancelSecurityPopUp.cancelText')} - confirmButtonProps={{ status: 'danger' }} + cancelText={t("cancelSecurityPopUp.cancelText")} + confirmButtonProps={{ status: "danger" }} /> } - title={t('createSecurityPopUp.title')} - description={t('createSecurityPopUp.description')} - confirmText={t('createSecurityPopUp.confirmText')} + title={t("createSecurityPopUp.title")} + description={t("createSecurityPopUp.description")} + confirmText={t("createSecurityPopUp.confirmText")} onConfirm={() => { submit(); onCloseCreate(); }} onCancel={onCloseCreate} - cancelText={t('createSecurityPopUp.cancelText')} + cancelText={t("createSecurityPopUp.cancelText")} /> ); diff --git a/apps/ats/web/src/views/CreateBond/CreateBond.tsx b/apps/ats/web/src/views/CreateBond/CreateBond.tsx index 3e23b8051..a6f6e2b99 100644 --- a/apps/ats/web/src/views/CreateBond/CreateBond.tsx +++ b/apps/ats/web/src/views/CreateBond/CreateBond.tsx @@ -216,10 +216,10 @@ import { User } from '../../utils/constants'; import { useUserStore } from '../../store/userStore'; import { StepConfiguration } from './Components/StepConfiguration'; import { StepReview } from './Components/StepReview'; -import { StepCoupon } from './Components/StepCoupon'; import { StepRegulation } from '../CreateSecurityCommons/StepRegulation'; import { StepExternalManagement } from '../CreateSecurityCommons/StepExternalManagement'; import { StepERC3643 } from '../CreateSecurityCommons/StepERC3643'; +import { StepProceedRecipients } from './Components/StepProceedRecipients'; export const CreateBond = () => { const { t } = useTranslation('security', { keyPrefix: 'createBond' }); @@ -255,8 +255,8 @@ export const CreateBond = () => { content: , }, { - title: t('header.coupon'), - content: , + title: t('stepProceedRecipients.title'), + content: , }, { title: t('stepERC3643.title'), diff --git a/apps/ats/web/src/views/CreateBond/ICreateBondFormValues.ts b/apps/ats/web/src/views/CreateBond/ICreateBondFormValues.ts index 895d861e3..c9d0bfc75 100644 --- a/apps/ats/web/src/views/CreateBond/ICreateBondFormValues.ts +++ b/apps/ats/web/src/views/CreateBond/ICreateBondFormValues.ts @@ -215,15 +215,10 @@ export interface ICreateBondFormValues { currency: string; numberOfUnits: string; nominalValue: number; + nominalValueDecimals: number; totalAmount: string; startingDate: string; maturityDate: string; - couponType: number; - couponFrequency: string; - couponRate: number; - firstCouponDate: string; - lastCouponDate: string; - totalCoupons: number; regulationType: number; regulationSubType: number; countriesListType: number; @@ -234,4 +229,6 @@ export interface ICreateBondFormValues { internalKycActivated: boolean; complianceId?: string; identityRegistryId?: string; + proceedRecipientsIds?: string[]; + proceedRecipientsData?: string[]; } diff --git a/apps/ats/web/src/views/CreateBond/__tests__/__snapshots__/CreateBond.test.tsx.snap b/apps/ats/web/src/views/CreateBond/__tests__/__snapshots__/CreateBond.test.tsx.snap index bcbac2758..178a9f9be 100644 --- a/apps/ats/web/src/views/CreateBond/__tests__/__snapshots__/CreateBond.test.tsx.snap +++ b/apps/ats/web/src/views/CreateBond/__tests__/__snapshots__/CreateBond.test.tsx.snap @@ -173,7 +173,7 @@ exports[`CreateBond render correctly 1`] = ` class="chakra-step__title css-gryw16" data-status="incomplete" > - Coupon + Proceed Recipients
{ - const { t } = useTranslation('security', { keyPrefix: 'createEquity' }); + const { t } = useTranslation("security", { keyPrefix: "createEquity" }); - const { control, watch, setValue, getValues } = - useFormContext(); + const { control, watch, setValue, getValues } = useFormContext(); const stepFormState = useFormState({ control, }); - const nominalValue = watch('nominalValue'); - const numberOfShares = watch('numberOfShares'); - const totalAmount = watch('totalAmount'); - const decimals = getValues('decimals'); + const nominalValue = watch("nominalValue"); + const numberOfShares = watch("numberOfShares"); + const totalAmount = watch("totalAmount"); + const decimals = getValues("decimals"); useEffect(() => { let totalAmount = 0; if (!isNaN(Number(nominalValue)) && !isNaN(Number(numberOfShares))) { totalAmount = Number(nominalValue) * Number(numberOfShares); } - setValue('totalAmount', formatNumber(totalAmount, {}, 2)); + setValue("totalAmount", formatNumber(totalAmount, {}, 18)); }, [nominalValue, numberOfShares, setValue]); return ( - {t('stepNewSerie.title')} - {t('stepNewSerie.subtitle')} + {t("stepNewSerie.title")} + {t("stepNewSerie.subtitle")} - {t('stepNewSerie.mandatoryFields')} + {t("stepNewSerie.mandatoryFields")} - + - - {t('stepNewSerie.nominalValue')}* - - + {t("stepNewSerie.nominalValue")}* + @@ -286,9 +71,8 @@ export const StepNewSerie = () => { required, min: min(0), }} - decimalScale={2} - fixedDecimalScale={true} - placeholder={t('stepNewSerie.nominalValuePlaceHolder')} + decimalScale={18} + placeholder={t("stepNewSerie.nominalValuePlaceHolder")} backgroundColor="neutral.600" size="md" thousandSeparator="," @@ -296,7 +80,7 @@ export const StepNewSerie = () => { /> - {t('stepNewSerie.currency')} + {t("stepNewSerie.currency")} { - - {t('stepNewSerie.numberOfShares')}* - - + {t("stepNewSerie.numberOfShares")}* + @@ -338,13 +117,8 @@ export const StepNewSerie = () => { - - {t('stepNewSerie.totalAmount')}* - - + {t("stepNewSerie.totalAmount")}* + @@ -359,71 +133,37 @@ export const StepNewSerie = () => { isDisabled={true} /> - + - + - + - + - + - + - + - + - - {t('stepNewSerie.dividendType')}* - + {t("stepNewSerie.dividendType")}* - {t('stepNewSerie.dividendTypeTooltip')} - - } + label={{t("stepNewSerie.dividendTypeTooltip")}} placement="right" > @@ -437,26 +177,20 @@ export const StepNewSerie = () => { options={[ { label: DividendType.NONE, - value: '0', + value: "0", }, { label: DividendType.PREFERRED, - value: '1', + value: "1", }, { label: DividendType.COMMON, - value: '2', + value: "2", }, ]} /> - + diff --git a/apps/ats/web/src/views/CreateEquity/Components/StepReview.tsx b/apps/ats/web/src/views/CreateEquity/Components/StepReview.tsx index ce577d717..ad74f76e0 100644 --- a/apps/ats/web/src/views/CreateEquity/Components/StepReview.tsx +++ b/apps/ats/web/src/views/CreateEquity/Components/StepReview.tsx @@ -1,301 +1,73 @@ -/* - 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. - -*/ - -import { - HStack, - SimpleGrid, - Stack, - VStack, - useDisclosure, -} from '@chakra-ui/react'; -import { useTranslation } from 'react-i18next'; -import { PreviousStepButton } from './PreviousStepButton'; -import { - PhosphorIcon, - Text, - Button, - DetailReview, - DetailReviewProps, - InfoDivider, - PopUp, -} from 'io-bricks-ui'; -import { useFormContext } from 'react-hook-form'; -import { ICreateEquityFormValues } from '../ICreateEquityFormValues'; -import { useCreateEquity } from '../../../hooks/queries/useCreateEquity'; -import { useWalletStore } from '../../../store/walletStore'; -import { CreateEquityRequest } from '@hashgraph/asset-tokenization-sdk'; -import { transformDividendType } from '../DividendType'; -import { WarningCircle, Question } from '@phosphor-icons/react'; -import { RouterManager } from '../../../router/RouterManager'; -import { RouteName } from '../../../router/RouteName'; -import { numberToExponential } from '../../../utils/format'; -import { FormStepContainer } from '../../../components/FormStepContainer'; -import { NOMINAL_VALUE_FACTOR } from '../../../utils/constants'; -import { formatNumber } from '../../../utils/format'; -import { CountriesList } from '../../CreateSecurityCommons/CountriesList'; -import { - COUNTRY_LIST_ALLOWED, - COUNTRY_LIST_BLOCKED, -} from '../../../utils/countriesConfig'; +// SPDX-License-Identifier: Apache-2.0 + +import { HStack, SimpleGrid, Stack, VStack, useDisclosure } from "@chakra-ui/react"; +import { useTranslation } from "react-i18next"; +import { PreviousStepButton } from "./PreviousStepButton"; +import { PhosphorIcon, Text, Button, DetailReview, DetailReviewProps, InfoDivider, PopUp } from "io-bricks-ui"; +import { useFormContext } from "react-hook-form"; +import { ICreateEquityFormValues } from "../ICreateEquityFormValues"; +import { useCreateEquity } from "../../../hooks/queries/useCreateEquity"; +import { useWalletStore } from "../../../store/walletStore"; +import { CreateEquityRequest } from "@hashgraph/asset-tokenization-sdk"; +import { transformDividendType } from "../DividendType"; +import { WarningCircle, Question } from "@phosphor-icons/react"; +import { RouterManager } from "../../../router/RouterManager"; +import { RouteName } from "../../../router/RouteName"; +import { numberToExponential } from "../../../utils/format"; +import { FormStepContainer } from "../../../components/FormStepContainer"; +import { formatNumber } from "../../../utils/format"; +import { CountriesList } from "../../CreateSecurityCommons/CountriesList"; +import { COUNTRY_LIST_ALLOWED, COUNTRY_LIST_BLOCKED } from "../../../utils/countriesConfig"; export const StepReview = () => { - const { t } = useTranslation('security', { keyPrefix: 'createEquity' }); - const { t: tRegulation } = useTranslation('security', { - keyPrefix: 'regulation', + const { t } = useTranslation("security", { keyPrefix: "createEquity" }); + const { t: tRegulation } = useTranslation("security", { + keyPrefix: "regulation", }); const { getValues } = useFormContext(); const { mutate: createSecurity, isLoading } = useCreateEquity(); const { address } = useWalletStore(); - const { - isOpen: isOpenCancel, - onClose: onCloseCancel, - onOpen: onOpenCancel, - } = useDisclosure(); - const { - isOpen: isOpenCreate, - onClose: onCloseCreate, - onOpen: onOpenCreate, - } = useDisclosure(); - - const name = getValues('name'); - const symbol = getValues('symbol'); - const isin = getValues('isin'); - const decimals = getValues('decimals'); - const isControllable = getValues('isControllable'); - const isBlocklist = getValues('isBlocklist'); - const isClearing = getValues('isClearing'); - const nominalValue = getValues('nominalValue'); - const currency = getValues('currency'); - const numberOfShares = getValues('numberOfShares'); - const totalAmount = getValues('totalAmount'); + const { isOpen: isOpenCancel, onClose: onCloseCancel, onOpen: onOpenCancel } = useDisclosure(); + const { isOpen: isOpenCreate, onClose: onCloseCreate, onOpen: onOpenCreate } = useDisclosure(); + + const name = getValues("name"); + const symbol = getValues("symbol"); + const isin = getValues("isin"); + const decimals = getValues("decimals"); + const isControllable = getValues("isControllable"); + const isBlocklist = getValues("isBlocklist"); + const isClearing = getValues("isClearing"); + const nominalValue = getValues("nominalValue"); + const nominalValueParts = nominalValue.toString().split("."); + const nominalValueDynamicDecimals = nominalValueParts.length > 1 ? nominalValueParts[1].length : 0; + const nominalValueRawValue = nominalValueParts.join(""); + const currency = getValues("currency"); + const numberOfShares = getValues("numberOfShares"); + const totalAmount = getValues("totalAmount"); const rights = { - votingRights: getValues('isVotingRight'), - informationRights: getValues('isInformationRight'), - liquidationRights: getValues('isLiquidationRight'), - subscriptionRights: getValues('isSubscriptionRight'), - conversionRights: getValues('isConversionRight'), - redemptionRights: getValues('isRedemptionRight'), - putRights: getValues('isPutRight'), + votingRights: getValues("isVotingRight"), + informationRights: getValues("isInformationRight"), + liquidationRights: getValues("isLiquidationRight"), + subscriptionRights: getValues("isSubscriptionRight"), + conversionRights: getValues("isConversionRight"), + redemptionRights: getValues("isRedemptionRight"), + putRights: getValues("isPutRight"), }; - const dividendType = getValues('dividendType'); - const regulationType = getValues('regulationType'); - const regulationSubType = getValues('regulationSubType'); - const countriesListType = getValues('countriesListType'); - let countriesList: string[] = getValues('countriesList'); - const externalPausesList = getValues('externalPausesList'); - const externalControlList = getValues('externalControlList'); - const externalKYCList = getValues('externalKYCList'); - const internalKycActivated = getValues('internalKycActivated'); - const complianceId = getValues('complianceId'); - const identityRegistryId = getValues('identityRegistryId'); - - countriesList = countriesList.concat( - countriesListType === 2 ? COUNTRY_LIST_ALLOWED : COUNTRY_LIST_BLOCKED, - ); + const dividendType = getValues("dividendType"); + const regulationType = getValues("regulationType"); + const regulationSubType = getValues("regulationSubType"); + const countriesListType = getValues("countriesListType"); + let countriesList: string[] = getValues("countriesList"); + const externalPausesList = getValues("externalPausesList"); + const externalControlList = getValues("externalControlList"); + const externalKYCList = getValues("externalKYCList"); + const internalKycActivated = getValues("internalKycActivated"); + const complianceId = getValues("complianceId"); + const identityRegistryId = getValues("identityRegistryId"); + + countriesList = countriesList.concat(countriesListType === 2 ? COUNTRY_LIST_ALLOWED : COUNTRY_LIST_BLOCKED); const submit = () => { const request = new CreateEquityRequest({ @@ -318,33 +90,28 @@ export const StepReview = () => { redemptionRight: rights.redemptionRights, putRight: rights.putRights, dividendRight: dividendType, - currency: - '0x' + - currency.charCodeAt(0) + - currency.charCodeAt(1) + - currency.charCodeAt(2), + currency: "0x" + currency.charCodeAt(0) + currency.charCodeAt(1) + currency.charCodeAt(2), numberOfShares: numberToExponential(numberOfShares, decimals), - nominalValue: (nominalValue * NOMINAL_VALUE_FACTOR).toString(), + nominalValue: nominalValueRawValue, + nominalValueDecimals: nominalValueDynamicDecimals, regulationType: regulationType, regulationSubType: regulationSubType, isCountryControlListWhiteList: countriesListType === 2, countries: countriesList.map((country) => country).toString(), - info: '', - configId: process.env.REACT_APP_EQUITY_CONFIG_ID ?? '', - configVersion: parseInt( - process.env.REACT_APP_EQUITY_CONFIG_VERSION ?? '0', - ), + info: "", + configId: process.env.REACT_APP_EQUITY_CONFIG_ID ?? "", + configVersion: parseInt(process.env.REACT_APP_EQUITY_CONFIG_VERSION ?? "0"), ...(externalPausesList && externalPausesList.length > 0 && { - externalPauses: externalPausesList, + externalPausesIds: externalPausesList, }), ...(externalControlList && externalControlList.length > 0 && { - externalControlLists: externalControlList, + externalControlListsIds: externalControlList, }), ...(externalKYCList && externalKYCList.length > 0 && { - externalKycLists: externalKYCList, + externalKycListsIds: externalKYCList, }), internalKycActivated, ...(complianceId && { @@ -360,101 +127,87 @@ export const StepReview = () => { const tokenDetails: DetailReviewProps[] = [ { - title: t('stepTokenDetails.name'), + title: t("stepTokenDetails.name"), value: name, }, { - title: t('stepTokenDetails.symbol'), + title: t("stepTokenDetails.symbol"), value: symbol, }, { - title: t('stepTokenDetails.decimals'), + title: t("stepTokenDetails.decimals"), value: decimals, }, { - title: t('stepTokenDetails.isin'), + title: t("stepTokenDetails.isin"), value: isin, }, ]; const configurationNewSerieDetails: DetailReviewProps[] = [ { - title: t('stepNewSerie.nominalValue'), - value: formatNumber(nominalValue, {}, 2), + title: t("stepNewSerie.nominalValue"), + value: formatNumber(nominalValue, {}, nominalValueDynamicDecimals), }, { - title: t('stepNewSerie.currency'), + title: t("stepNewSerie.currency"), value: currency, }, { - title: t('stepNewSerie.numberOfShares'), + title: t("stepNewSerie.numberOfShares"), value: formatNumber(numberOfShares, {}, decimals), }, { - title: t('stepNewSerie.totalAmount'), + title: t("stepNewSerie.totalAmount"), value: totalAmount, }, ]; const configurationRightsDetails: DetailReviewProps[] = [ { - title: t('stepNewSerie.dividendType'), + title: t("stepNewSerie.dividendType"), value: transformDividendType(dividendType.toString()), }, ]; const erc3643Details: DetailReviewProps[] = [ { - title: t('stepERC3643.complianceId'), - value: complianceId ?? '-', + title: t("stepERC3643.complianceId"), + value: complianceId ?? "-", }, { - title: t('stepERC3643.identityRegistryId'), - value: identityRegistryId ?? '-', + title: t("stepERC3643.identityRegistryId"), + value: identityRegistryId ?? "-", }, ]; const externalManagement: DetailReviewProps[] = [ { - title: t('stepExternalManagement.externalPause'), - value: externalPausesList - ? externalPausesList?.map((pause) => ' ' + pause).toString() - : '-', + title: t("stepExternalManagement.externalPause"), + value: externalPausesList ? externalPausesList?.map((pause) => " " + pause).toString() : "-", }, { - title: t('stepExternalManagement.externalControl'), - value: externalControlList - ? externalControlList?.map((control) => ' ' + control).toString() - : '-', + title: t("stepExternalManagement.externalControl"), + value: externalControlList ? externalControlList?.map((control) => " " + control).toString() : "-", }, { - title: t('stepExternalManagement.externalKYC'), - value: externalKYCList - ? externalKYCList?.map((control) => ' ' + control).toString() - : '-', + title: t("stepExternalManagement.externalKYC"), + value: externalKYCList ? externalKYCList?.map((control) => " " + control).toString() : "-", }, ]; const regulationDetails: DetailReviewProps[] = [ { - title: tRegulation('regulationTypeReview'), + title: tRegulation("regulationTypeReview"), value: tRegulation(`regulationType_${regulationType}`), }, { - title: tRegulation('regulationSubTypeReview'), + title: tRegulation("regulationSubTypeReview"), value: tRegulation(`regulationSubType_${regulationSubType}`), }, { - title: - countriesListType === 2 - ? tRegulation('allowedCountriesReview') - : tRegulation('blockedCountriesReview'), - value: countriesList - .map( - (country) => - ' ' + CountriesList[country as keyof typeof CountriesList], - ) - .toString(), + title: countriesListType === 2 ? tRegulation("allowedCountriesReview") : tRegulation("blockedCountriesReview"), + value: countriesList.map((country) => " " + CountriesList[country as keyof typeof CountriesList]).toString(), }, ]; @@ -462,22 +215,14 @@ export const StepReview = () => { - + {tokenDetails.map((props) => ( ))} - + {configurationNewSerieDetails.map((props) => ( @@ -488,17 +233,12 @@ export const StepReview = () => { - {t('stepNewSerie.choosenRights')} + {t("stepNewSerie.choosenRights")} {Object.entries(rights) .filter(([_key, value]) => value) .map(([key]) => ( - + · {t(`stepNewSerie.${key}`)} ))} @@ -510,49 +250,34 @@ export const StepReview = () => { ))} - + {erc3643Details.map((props) => ( ))} - + {externalManagement.map((props) => ( ))} - + {regulationDetails.map((props) => ( ))} - + - @@ -562,31 +287,31 @@ export const StepReview = () => { isOpen={isOpenCancel} onClose={onCloseCancel} icon={} - title={t('cancelSecurityPopUp.title')} - description={t('cancelSecurityPopUp.description')} - confirmText={t('cancelSecurityPopUp.confirmText')} + title={t("cancelSecurityPopUp.title")} + description={t("cancelSecurityPopUp.description")} + confirmText={t("cancelSecurityPopUp.confirmText")} onConfirm={() => { RouterManager.to(RouteName.Dashboard); onCloseCancel(); }} onCancel={onCloseCancel} - cancelText={t('cancelSecurityPopUp.cancelText')} - confirmButtonProps={{ status: 'danger' }} + cancelText={t("cancelSecurityPopUp.cancelText")} + confirmButtonProps={{ status: "danger" }} /> } - title={t('createSecurityPopUp.title')} - description={t('createSecurityPopUp.description')} - confirmText={t('createSecurityPopUp.confirmText')} + title={t("createSecurityPopUp.title")} + description={t("createSecurityPopUp.description")} + confirmText={t("createSecurityPopUp.confirmText")} onConfirm={() => { submit(); onCloseCreate(); }} onCancel={onCloseCreate} - cancelText={t('createSecurityPopUp.cancelText')} + cancelText={t("createSecurityPopUp.cancelText")} /> ); diff --git a/apps/ats/web/src/views/CreateEquity/ICreateEquityFormValues.ts b/apps/ats/web/src/views/CreateEquity/ICreateEquityFormValues.ts index 8992db121..824ce25d5 100644 --- a/apps/ats/web/src/views/CreateEquity/ICreateEquityFormValues.ts +++ b/apps/ats/web/src/views/CreateEquity/ICreateEquityFormValues.ts @@ -213,6 +213,7 @@ export interface ICreateEquityFormValues { isApproval: boolean; isClearing: boolean; nominalValue: number; + nominalValueDecimals: number; currency: string; numberOfShares: string; totalAmount: string; diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/ClearingOperations/ClearingOperationCreate.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ClearingOperations/ClearingOperationCreate.tsx index c1f1d77c3..f2d358638 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/ClearingOperations/ClearingOperationCreate.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ClearingOperations/ClearingOperationCreate.tsx @@ -132,7 +132,7 @@ export const ClearingOperationsCreate = () => { amount: amount.toString(), clearingExpirationDate: dateToUnixTimestamp(expirationDate), holdExpirationDate: dateToUnixTimestamp(holdExpirationDate), - escrow: escrowAccount, + escrowId: escrowAccount, // TODO: check with SDK: sourceId, targetId, partitionId: DEFAULT_PARTITION, diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/ComplianceItem.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ComplianceItem.tsx new file mode 100644 index 000000000..fe522db76 --- /dev/null +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ComplianceItem.tsx @@ -0,0 +1,353 @@ +/* + 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. + +*/ + +import { + ComplianceRequest, + SetComplianceRequest, +} from '@hashgraph/asset-tokenization-sdk'; +import { useEffect, useState } from 'react'; +import { FieldValues, useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { Flex } from '@chakra-ui/react'; +import { + IconButton, + InputController, + PhosphorIcon, + PopUp, + Text, +} from 'io-bricks-ui'; +import { Pencil, X, Info, Check } from '@phosphor-icons/react'; +import { useRolesStore } from '../../../store/rolesStore'; +import { SecurityRole } from '../../../utils/SecurityRole'; +import { useParams } from 'react-router-dom'; +import { useUpdateCompliance } from '../../../hooks/mutations/useUpdateCompliance'; +import { useGetCompliance } from '../../../hooks/queries/useCompliance'; + +export const ComplianceItem = ({ securityId }: { securityId: string }) => { + const { id = '' } = useParams(); + const { roles: accountRoles } = useRolesStore(); + + const { t } = useTranslation('security', { + keyPrefix: 'details.bond.updateCompliance.toast', + }); + + const { control, reset, handleSubmit } = useForm({ + mode: 'onChange', + }); + + const [isEditMode, setIsEditMode] = useState(false); + const [showConfirmPopUp, setShowConfirmPopUp] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const { data: compliance } = useGetCompliance( + new ComplianceRequest({ + securityId: id!, + }), + { + enabled: !!id, + }, + ); + + const { mutate: updateComplianceMutation } = useUpdateCompliance(); + + useEffect(() => { + reset(); + }, [isEditMode, reset]); + + const onSubmit = (data: FieldValues) => { + setIsLoading(true); + + const request = new SetComplianceRequest({ + securityId, + compliance: data.compliance, + }); + + updateComplianceMutation(request, { + onSettled() { + setShowConfirmPopUp(false); + setIsLoading(false); + setIsEditMode(false); + }, + }); + }; + + return ( + + + {isEditMode && ( + <> + + + } + aria-label="save button" + size={'sm'} + onClick={() => { + setShowConfirmPopUp(true); + }} + /> + } + aria-label="cancel button" + size={'sm'} + onClick={() => setIsEditMode(false)} + /> + + + )} + {!isEditMode && ( + <> + {compliance} + {accountRoles.includes(SecurityRole._TREX_OWNER_ROLE) && + compliance !== '0.0.0' && ( + } + aria-label="edit button" + variant="secondary" + onClick={() => setIsEditMode(true)} + /> + )} + + )} + + + { + !isLoading && setShowConfirmPopUp(false); + }} + closeOnOverlayClick={!isLoading} + icon={} + title={t('title')} + description={t('subtitle')} + cancelText={t('cancelButtonText')} + confirmText={t('confirmButtonText')} + confirmButtonProps={{ + isLoading: isLoading, + }} + onConfirm={() => { + handleSubmit(onSubmit)(); + }} + onCancel={() => { + !isLoading && setShowConfirmPopUp(false); + }} + /> + + ); +}; diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/CouponsList.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/CouponsList.tsx index 2a88a69b3..4c1c5ad34 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/CouponsList.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/CouponsList.tsx @@ -7,8 +7,12 @@ import { useParams } from 'react-router-dom'; import { createColumnHelper } from '@tanstack/table-core'; import { Table, Text } from 'io-bricks-ui'; import { useTranslation } from 'react-i18next'; -import { COUPONS_FACTOR, DATE_TIME_FORMAT } from '../../../../utils/constants'; -import { formatDate } from '../../../../utils/format'; +import { DATE_TIME_FORMAT } from '../../../../utils/constants'; +import { + formatDate, + formatCouponPeriod, + formatNumberLocale, +} from '../../../../utils/format'; export const CouponsList = () => { const { id } = useParams(); @@ -46,7 +50,13 @@ export const CouponsList = () => { }), columnHelper.accessor('rate', { header: t('columns.rate'), - cell: (row) => `${parseInt(row.getValue()) / COUPONS_FACTOR}%`, + cell: (row) => + `${formatNumberLocale(row.getValue(), row.row.original.rateDecimals ?? 0)}%`, + enableSorting: false, + }), + columnHelper.accessor('period', { + header: t('columns.period'), + cell: (row) => formatCouponPeriod(row.getValue()), enableSorting: false, }), columnHelper.accessor('snapshotId', { diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/ProgramCoupon.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/ProgramCoupon.tsx index dd1a26132..6c8bb46a5 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/ProgramCoupon.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/ProgramCoupon.tsx @@ -208,6 +208,7 @@ import { CalendarInputController, InputNumberController, PhosphorIcon, + SelectController, Text, Tooltip, } from 'io-bricks-ui'; @@ -222,14 +223,18 @@ import { import { useParams } from 'react-router-dom'; import { useCoupons } from '../../../../hooks/queries/useCoupons'; import { useGetBondDetails } from '../../../../hooks/queries/useGetSecurityDetails'; -import { dateToUnixTimestamp } from '../../../../utils/format'; -import { COUPONS_FACTOR, DATE_TIME_FORMAT } from '../../../../utils/constants'; +import { + dateToUnixTimestamp, + validateCouponPeriod, +} from '../../../../utils/format'; +import { DATE_TIME_FORMAT, TIME_PERIODS_S } from '../../../../utils/constants'; import { isBeforeDate } from '../../../../utils/helpers'; interface ProgramCouponFormValues { rate: number; recordTimestamp: string; executionTimestamp: string; + period: string; } export const ProgramCoupon = () => { @@ -254,9 +259,10 @@ export const ProgramCoupon = () => { const submit: SubmitHandler = (params) => { const request = new SetCouponRequest({ securityId: id ?? '', - rate: (params.rate * COUPONS_FACTOR).toString(), + rate: params.rate.toString(), recordTimestamp: dateToUnixTimestamp(params.recordTimestamp), executionTimestamp: dateToUnixTimestamp(params.executionTimestamp), + period: params.period, }); createCoupon(request, { @@ -345,6 +351,50 @@ export const ProgramCoupon = () => { decimalSeparator="." /> + + + + {tForm('period.label')}* + + + + + + { + const validation = validateCouponPeriod(parseInt(value)); + return validation === true || validation; + }, + }} + placeholder={tForm('period.placeholder')} + options={[ + { + label: tForm('period.options.day'), + value: TIME_PERIODS_S.DAY.toString(), + }, + { + label: tForm('period.options.week'), + value: TIME_PERIODS_S.WEEK.toString(), + }, + { + label: tForm('period.options.month'), + value: TIME_PERIODS_S.MONTH.toString(), + }, + { + label: tForm('period.options.quarter'), + value: TIME_PERIODS_S.QUARTER.toString(), + }, + { + label: tForm('period.options.year'), + value: TIME_PERIODS_S.YEAR.toString(), + }, + ]} + /> + - {couponsFor && coupons && ( + {couponsFor && coupons && couponsAmountFor && ( )} diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/SeeCoupon.test.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/SeeCoupon.test.tsx index 3cc804421..1fd522159 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/SeeCoupon.test.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/SeeCoupon.test.tsx @@ -1,216 +1,357 @@ -/* - 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. - -*/ - -import { SeeCoupon } from '../SeeCoupon'; -import { render } from '../../../../../test-utils'; - -// TODO Improve tests when it is connected to SDK +// SPDX-License-Identifier: Apache-2.0 + +import { SeeCoupon } from "../SeeCoupon"; +import { render } from "../../../../../test-utils"; +import { screen, fireEvent, waitFor } from "@testing-library/react"; +import { useGetCoupons, useGetCouponsFor, useGetCouponsAmountFor } from "../../../../../hooks/queries/useCoupons"; + +jest.mock("../../../../../hooks/queries/useCoupons"); +jest.mock("react-router-dom", () => ({ + ...jest.requireActual("react-router-dom"), + useParams: () => ({ id: "0.0.12345" }), +})); + +const mockUseGetCouponsFor = useGetCouponsFor as jest.Mock; +const mockUseGetCoupons = useGetCoupons as jest.Mock; +const mockUseGetCouponsAmountFor = useGetCouponsAmountFor as jest.Mock; + +const mockRefetchCouponsFor = jest.fn(); +const mockRefetchCoupons = jest.fn(); +const mockRefetchCouponsAmountFor = jest.fn(); + +const defaultHookResponse = { + data: undefined, + refetch: jest.fn(), + isLoading: false, + isError: false, +}; + +const mockCouponsForData = { + tokenBalance: "10050", + decimals: "2", +}; + +const mockCouponsData = { + executionDate: new Date("2024-06-15T10:00:00Z"), +}; + +const mockCouponsAmountForData = { + numerator: "150", + denominator: "100", + recordDateReached: true, +}; + +const getFormInputsByName = () => { + const couponInput = document.querySelector('input[name="couponId"]') as HTMLInputElement; + const accountInput = document.querySelector('input[name="targetId"]') as HTMLInputElement; + return { couponInput, accountInput }; +}; + describe(`${SeeCoupon.name}`, () => { - test('should render correctly', () => { - const component = render(); + beforeEach(() => { + jest.clearAllMocks(); + + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchCouponsAmountFor, + }); + }); + test("should render correctly", () => { + const component = render(); expect(component.asFragment()).toMatchSnapshot(); }); + + test("should render form inputs", () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + expect(couponInput).toBeInTheDocument(); + expect(accountInput).toBeInTheDocument(); + }); + + test("should disable submit button when form is invalid", () => { + render(); + + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + + test("should enable submit button when form is valid", async () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + + fireEvent.change(couponInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).not.toBeDisabled(); + }); + }); + + test("should call refetch functions on form submit", async () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + + fireEvent.change(couponInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).not.toBeDisabled(); + }); + + const submitButton = screen.getByRole("button"); + fireEvent.click(submitButton); + + await waitFor(() => { + expect(mockRefetchCouponsFor).toHaveBeenCalled(); + expect(mockRefetchCoupons).toHaveBeenCalled(); + expect(mockRefetchCouponsAmountFor).toHaveBeenCalled(); + }); + }); + + test("should display coupon details when all data is loaded", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsAmountForData, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + // Verify balance from couponsFor.value + expect(screen.getByText("100.50")).toBeInTheDocument(); + + // Verify amount calculated as numerator/denominator (150/100 = 1.500 $) + expect(screen.getByText("1.500 $")).toBeInTheDocument(); + + // Verify recordDateReached from couponsAmountFor + expect(screen.getByText("Yes")).toBeInTheDocument(); + }); + }); + + test("should display 0 for amount when numerator is 0", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "0", + denominator: "100", + recordDateReached: true, + }, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + // Amount should be "0" when numerator is 0 + const zeroElements = screen.getAllByText("0"); + expect(zeroElements.length).toBeGreaterThanOrEqual(1); + }); + }); + + test("should display 0 for amount when denominator is 0", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "100", + denominator: "0", + recordDateReached: false, + }, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + // Amount should be "0" when denominator is 0 + const zeroElements = screen.getAllByText("0"); + expect(zeroElements.length).toBeGreaterThanOrEqual(1); + expect(screen.getByText("No")).toBeInTheDocument(); + }); + }); + + test("should display default values when couponsAmountFor fields are undefined", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: undefined, + denominator: undefined, + recordDateReached: undefined, + }, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + // Amount should be "0" when numerator/denominator are undefined + const zeroElements = screen.getAllByText("0"); + expect(zeroElements.length).toBeGreaterThanOrEqual(1); + + expect(screen.getByText("No")).toBeInTheDocument(); + }); + }); + + test("should display recordDateReached as No when it is false", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "500", + denominator: "100", + recordDateReached: false, + }, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + // Verify amount calculated as 500/100 = 5.000 + expect(screen.getByText("5.000 $")).toBeInTheDocument(); + expect(screen.getByText("No")).toBeInTheDocument(); + }); + }); + + test("should not display details when data is not loaded", () => { + render(); + + expect(screen.queryByText(/balance/i)).not.toBeInTheDocument(); + expect(screen.queryByText(/amount/i)).not.toBeInTheDocument(); + expect(screen.queryByText(/recordDateReached/i)).not.toBeInTheDocument(); + }); + + test("should validate couponId with min value of 0", async () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + + fireEvent.change(couponInput, { target: { value: "-1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + }); + + test("should validate targetId as valid Hedera ID", async () => { + render(); + + const { couponInput, accountInput } = getFormInputsByName(); + + fireEvent.change(couponInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "invalid-id" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + }); + + test("should calculate amount with 3 decimal places", async () => { + mockUseGetCouponsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsForData, + refetch: mockRefetchCouponsFor, + }); + + mockUseGetCoupons.mockReturnValue({ + ...defaultHookResponse, + data: mockCouponsData, + refetch: mockRefetchCoupons, + }); + + mockUseGetCouponsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "1", + denominator: "3", + recordDateReached: true, + }, + refetch: mockRefetchCouponsAmountFor, + }); + + render(); + + await waitFor(() => { + // 1/3 = 0.333... should be formatted to 0.333 $ + expect(screen.getByText("0.333 $")).toBeInTheDocument(); + }); + }); }); diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/__snapshots__/Coupons.test.tsx.snap b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/__snapshots__/Coupons.test.tsx.snap index fe3395674..864003792 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/__snapshots__/Coupons.test.tsx.snap +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Coupons/__tests__/__snapshots__/Coupons.test.tsx.snap @@ -161,6 +161,19 @@ exports[`Coupons should render correctly 1`] = `
+
+
+
+ Period +
+
+
@@ -234,6 +247,17 @@ exports[`Coupons should render correctly 1`] = ` /> + +
+
+
+
@@ -519,6 +543,127 @@ exports[`Coupons should render correctly 1`] = ` +
+
+

+ Coupon period* +

+
+ + + +
+
+
+ +
+
- {dividends && dividendsFor && ( + {dividends && dividendsFor && dividendsAmountFor && ( )} diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Dividends/__tests__/SeeDividend.test.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Dividends/__tests__/SeeDividend.test.tsx index f01e7ccff..3ac7f669c 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Dividends/__tests__/SeeDividend.test.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Dividends/__tests__/SeeDividend.test.tsx @@ -1,216 +1,407 @@ -/* - 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. - -*/ - -import { SeeDividend } from '../SeeDividend'; -import { render } from '../../../../../test-utils'; - -// TODO Improve tests when it is connected to SDK +// SPDX-License-Identifier: Apache-2.0 + +import { SeeDividend } from "../SeeDividend"; +import { render } from "../../../../../test-utils"; +import { screen, fireEvent, waitFor } from "@testing-library/react"; +import { + useGetDividends, + useGetDividendsFor, + useGetDividendsAmountFor, +} from "../../../../../hooks/queries/useDividends"; + +jest.mock("../../../../../hooks/queries/useDividends"); +jest.mock("react-router-dom", () => ({ + ...jest.requireActual("react-router-dom"), + useParams: () => ({ id: "0.0.12345" }), +})); + +const mockUseGetDividendsFor = useGetDividendsFor as jest.Mock; +const mockUseGetDividends = useGetDividends as jest.Mock; +const mockUseGetDividendsAmountFor = useGetDividendsAmountFor as jest.Mock; + +const mockRefetchDividendsFor = jest.fn(); +const mockRefetchDividends = jest.fn(); +const mockRefetchDividendsAmountFor = jest.fn(); + +const defaultHookResponse = { + data: undefined, + refetch: jest.fn(), + isLoading: false, + isError: false, +}; + +const mockDividendsForData = { + tokenBalance: "10000", + decimals: "2", +}; + +const mockDividendsData = { + executionDate: new Date("2024-06-15T10:00:00Z"), + amountPerUnitOfSecurity: "1.5", +}; + +const mockDividendsAmountForData = { + numerator: "150", + denominator: "100", + recordDateReached: true, +}; + +const getFormInputsByName = () => { + const dividendInput = document.querySelector('input[name="dividendId"]') as HTMLInputElement; + const accountInput = document.querySelector('input[name="targetId"]') as HTMLInputElement; + return { dividendInput, accountInput }; +}; + describe(`${SeeDividend.name}`, () => { - test('should render correctly', () => { - const component = render(); + beforeEach(() => { + jest.clearAllMocks(); + + mockUseGetDividendsFor.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchDividendsFor, + }); + + mockUseGetDividends.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchDividends, + }); + + mockUseGetDividendsAmountFor.mockReturnValue({ + ...defaultHookResponse, + refetch: mockRefetchDividendsAmountFor, + }); + }); + test("should render correctly", () => { + const component = render(); expect(component.asFragment()).toMatchSnapshot(); }); + + test("should render form inputs", () => { + render(); + + const { dividendInput, accountInput } = getFormInputsByName(); + expect(dividendInput).toBeInTheDocument(); + expect(accountInput).toBeInTheDocument(); + }); + + test("should disable submit button when form is invalid", () => { + render(); + + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + + test("should enable submit button when form is valid", async () => { + render(); + + const { dividendInput, accountInput } = getFormInputsByName(); + + fireEvent.change(dividendInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).not.toBeDisabled(); + }); + }); + + test("should call refetch functions on form submit", async () => { + render(); + + const { dividendInput, accountInput } = getFormInputsByName(); + + fireEvent.change(dividendInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).not.toBeDisabled(); + }); + + const submitButton = screen.getByRole("button"); + fireEvent.click(submitButton); + + await waitFor(() => { + expect(mockRefetchDividendsFor).toHaveBeenCalled(); + expect(mockRefetchDividends).toHaveBeenCalled(); + expect(mockRefetchDividendsAmountFor).toHaveBeenCalled(); + }); + }); + + test("should display dividend details when all data is loaded", async () => { + mockUseGetDividendsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsForData, + refetch: mockRefetchDividendsFor, + }); + + mockUseGetDividends.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsData, + refetch: mockRefetchDividends, + }); + + mockUseGetDividendsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsAmountForData, + refetch: mockRefetchDividendsAmountFor, + }); + + render(); + + await waitFor(() => { + // Verify balance from dividendsFor (tokenBalance: "10000", decimals: "2" -> 100.00) + expect(screen.getByText("100.00")).toBeInTheDocument(); + + // Verify amount calculated as numerator/denominator (150/100 = 1.500 $) + expect(screen.getByText("1.500 $")).toBeInTheDocument(); + + // Verify recordDateReached from dividendsAmountFor (displays "Yes") + expect(screen.getByText("Yes")).toBeInTheDocument(); + }); + }); + + test("should display recordDateReached as No when it is false", async () => { + mockUseGetDividendsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsForData, + refetch: mockRefetchDividendsFor, + }); + + mockUseGetDividends.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsData, + refetch: mockRefetchDividends, + }); + + mockUseGetDividendsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "500", + denominator: "100", + recordDateReached: false, + }, + refetch: mockRefetchDividendsAmountFor, + }); + + render(); + + await waitFor(() => { + // Verify amount calculated as 500/100 = 5.000 $ + expect(screen.getByText("5.000 $")).toBeInTheDocument(); + expect(screen.getByText("No")).toBeInTheDocument(); + }); + }); + + test("should display 0 for amount when numerator is 0", async () => { + mockUseGetDividendsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsForData, + refetch: mockRefetchDividendsFor, + }); + + mockUseGetDividends.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsData, + refetch: mockRefetchDividends, + }); + + mockUseGetDividendsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "0", + denominator: "100", + recordDateReached: true, + }, + refetch: mockRefetchDividendsAmountFor, + }); + + render(); + + await waitFor(() => { + // Amount should be "0" when numerator is 0 + const zeroElements = screen.getAllByText("0"); + expect(zeroElements.length).toBeGreaterThanOrEqual(1); + }); + }); + + test("should display 0 for amount when denominator is 0", async () => { + mockUseGetDividendsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsForData, + refetch: mockRefetchDividendsFor, + }); + + mockUseGetDividends.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsData, + refetch: mockRefetchDividends, + }); + + mockUseGetDividendsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "100", + denominator: "0", + recordDateReached: false, + }, + refetch: mockRefetchDividendsAmountFor, + }); + + render(); + + await waitFor(() => { + // Amount should be "0" when denominator is 0 + const zeroElements = screen.getAllByText("0"); + expect(zeroElements.length).toBeGreaterThanOrEqual(1); + expect(screen.getByText("No")).toBeInTheDocument(); + }); + }); + + test("should not display details when data is not loaded", () => { + render(); + + expect(screen.queryByText(/balance/i)).not.toBeInTheDocument(); + expect(screen.queryByText(/amount/i)).not.toBeInTheDocument(); + expect(screen.queryByText(/recordDateReached/i)).not.toBeInTheDocument(); + }); + + test("should not display details when dividendsFor is missing", () => { + mockUseGetDividends.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsData, + refetch: mockRefetchDividends, + }); + + mockUseGetDividendsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsAmountForData, + refetch: mockRefetchDividendsAmountFor, + }); + + render(); + + // Details should not be visible without dividendsFor + expect(screen.queryByText("1.500 $")).not.toBeInTheDocument(); + }); + + test("should not display details when dividends is missing", () => { + mockUseGetDividendsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsForData, + refetch: mockRefetchDividendsFor, + }); + + mockUseGetDividendsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsAmountForData, + refetch: mockRefetchDividendsAmountFor, + }); + + render(); + + // Details should not be visible without dividends + expect(screen.queryByText("1.500 $")).not.toBeInTheDocument(); + }); + + test("should not display details when dividendsAmountFor is missing", () => { + mockUseGetDividendsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsForData, + refetch: mockRefetchDividendsFor, + }); + + mockUseGetDividends.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsData, + refetch: mockRefetchDividends, + }); + + render(); + + // Details should not be visible without dividendsAmountFor + expect(screen.queryByText("1.500 $")).not.toBeInTheDocument(); + }); + + test("should validate dividendId with min value of 0", async () => { + render(); + + const { dividendInput, accountInput } = getFormInputsByName(); + + fireEvent.change(dividendInput, { target: { value: "-1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + }); + + test("should validate targetId as valid Hedera ID", async () => { + render(); + + const { dividendInput, accountInput } = getFormInputsByName(); + + fireEvent.change(dividendInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "invalid-id" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).toBeDisabled(); + }); + }); + + test("should show loading state when fetching data", async () => { + render(); + + const { dividendInput, accountInput } = getFormInputsByName(); + + fireEvent.change(dividendInput, { target: { value: "1" } }); + fireEvent.change(accountInput, { target: { value: "0.0.12345" } }); + + await waitFor(() => { + const submitButton = screen.getByRole("button"); + expect(submitButton).not.toBeDisabled(); + }); + + const submitButton = screen.getByRole("button"); + fireEvent.click(submitButton); + + // Button should show loading state after click + await waitFor(() => { + expect(submitButton).toHaveAttribute("data-loading"); + }); + }); + + test("should calculate amount with 3 decimal places", async () => { + mockUseGetDividendsFor.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsForData, + refetch: mockRefetchDividendsFor, + }); + + mockUseGetDividends.mockReturnValue({ + ...defaultHookResponse, + data: mockDividendsData, + refetch: mockRefetchDividends, + }); + + mockUseGetDividendsAmountFor.mockReturnValue({ + ...defaultHookResponse, + data: { + numerator: "1", + denominator: "3", + recordDateReached: true, + }, + refetch: mockRefetchDividendsAmountFor, + }); + + render(); + + await waitFor(() => { + // 1/3 = 0.333... should be formatted to 0.333 $ + expect(screen.getByText("0.333 $")).toBeInTheDocument(); + }); + }); }); diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Hold/HoldCreate.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Hold/HoldCreate.tsx index f33726cd3..fa2f2d046 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/Hold/HoldCreate.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/Hold/HoldCreate.tsx @@ -88,7 +88,7 @@ export const HoldCreate = () => { const baseRequest = { amount: amount.toString(), - escrow: escrowAccount.toString(), + escrowId: escrowAccount.toString(), expirationDate: dateToUnixTimestamp(expirationDate), partitionId: DEFAULT_PARTITION, securityId, diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/IdentityRegistryItem.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/IdentityRegistryItem.tsx new file mode 100644 index 000000000..d9baaff24 --- /dev/null +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/IdentityRegistryItem.tsx @@ -0,0 +1,358 @@ +/* + 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. + +*/ + +import { + IdentityRegistryRequest, + SetIdentityRegistryRequest, +} from '@hashgraph/asset-tokenization-sdk'; +import { useEffect, useState } from 'react'; +import { FieldValues, useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { Flex } from '@chakra-ui/react'; +import { + IconButton, + InputController, + PhosphorIcon, + PopUp, + Text, +} from 'io-bricks-ui'; +import { Pencil, X, Info, Check } from '@phosphor-icons/react'; +import { useRolesStore } from '../../../store/rolesStore'; +import { SecurityRole } from '../../../utils/SecurityRole'; +import { useParams } from 'react-router-dom'; +import { useGetIdentityRegistry } from '../../../hooks/queries/useIdentityRegistry'; +import { useUpdateIdentityRegistry } from '../../../hooks/mutations/useUpdateIdentityRegistry'; + +export const IdentityRegistryItem = ({ + securityId, +}: { + securityId: string; +}) => { + const { id = '' } = useParams(); + const { roles: accountRoles } = useRolesStore(); + + const { t } = useTranslation('security', { + keyPrefix: 'details.bond.updateIdentityRegistry.toast', + }); + + const { control, reset, handleSubmit } = useForm({ + mode: 'onChange', + }); + + const [isEditMode, setIsEditMode] = useState(false); + const [showConfirmPopUp, setShowConfirmPopUp] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const { data: identityRegistry } = useGetIdentityRegistry( + new IdentityRegistryRequest({ + securityId: id!, + }), + { + enabled: !!id, + }, + ); + + const { mutate: updateIdentityRegistryMutation } = + useUpdateIdentityRegistry(); + + useEffect(() => { + reset(); + }, [isEditMode, reset]); + + const onSubmit = (data: FieldValues) => { + setIsLoading(true); + + const request = new SetIdentityRegistryRequest({ + securityId, + identityRegistry: data.identityRegistry, + }); + + updateIdentityRegistryMutation(request, { + onSettled() { + setShowConfirmPopUp(false); + setIsLoading(false); + setIsEditMode(false); + }, + }); + }; + + return ( + + + {isEditMode && ( + <> + + + } + aria-label="save button" + size={'sm'} + onClick={() => { + setShowConfirmPopUp(true); + }} + /> + } + aria-label="cancel button" + size={'sm'} + onClick={() => setIsEditMode(false)} + /> + + + )} + {!isEditMode && ( + <> + {identityRegistry} + {accountRoles.includes(SecurityRole._TREX_OWNER_ROLE) && + identityRegistry !== '0.0.0' && ( + } + aria-label="edit button" + variant="secondary" + onClick={() => setIsEditMode(true)} + /> + )} + + )} + + + { + !isLoading && setShowConfirmPopUp(false); + }} + closeOnOverlayClick={!isLoading} + icon={} + title={t('title')} + description={t('subtitle')} + cancelText={t('cancelButtonText')} + confirmText={t('confirmButtonText')} + confirmButtonProps={{ + isLoading: isLoading, + }} + onConfirm={() => { + handleSubmit(onSubmit)(); + }} + onCancel={() => { + !isLoading && setShowConfirmPopUp(false); + }} + /> + + ); +}; diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/KYC/KYCModal.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/KYC/KYCModal.tsx index b7119ae85..e37d898ed 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/KYC/KYCModal.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/KYC/KYCModal.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React from "react"; import { HStack, Modal, @@ -10,33 +10,33 @@ import { ModalOverlay, ModalProps, VStack, -} from '@chakra-ui/react'; -import { Button, InputController, PhosphorIcon, Text } from 'io-bricks-ui'; -import { useForm } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { useGrantKYC } from '../../../../hooks/mutations/useKYC'; -import { GrantKycRequest } from '@hashgraph/asset-tokenization-sdk'; -import { useParams } from 'react-router-dom'; -import { FileArchive } from '@phosphor-icons/react'; -import { useRef, useState } from 'react'; -import { isValidHederaId, required } from '../../../../utils/rules'; +} from "@chakra-ui/react"; +import { Button, InputController, PhosphorIcon, Text } from "io-bricks-ui"; +import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; +import { useGrantKYC } from "../../../../hooks/mutations/useKYC"; +import { GrantKycRequest } from "@hashgraph/asset-tokenization-sdk"; +import { useParams } from "react-router-dom"; +import { FileArchive } from "@phosphor-icons/react"; +import { useRef, useState } from "react"; +import { isValidHederaId, required } from "../../../../utils/rules"; interface FormValues { accountId: string; vcFile: string; } -interface KYCModalProps extends Omit {} +interface KYCModalProps extends Omit {} export const KYCModal = ({ isOpen, onClose }: KYCModalProps) => { const fileInputRef = useRef(null); - const [fileName, setFileName] = useState(''); + const [fileName, setFileName] = useState(""); const [isLoading, setIsLoading] = useState(false); - const { id: securityId = '' } = useParams(); + const { id: securityId = "" } = useParams(); - const { t: tCreate } = useTranslation('security', { - keyPrefix: 'details.kyc.create', + const { t: tCreate } = useTranslation("security", { + keyPrefix: "details.kyc.create", }); const { @@ -47,7 +47,7 @@ export const KYCModal = ({ isOpen, onClose }: KYCModalProps) => { reset, watch, } = useForm({ - mode: 'onChange', + mode: "onChange", }); const { mutate } = useGrantKYC(); @@ -59,10 +59,10 @@ export const KYCModal = ({ isOpen, onClose }: KYCModalProps) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => { - if (typeof reader.result === 'string') { - const base64Data = reader.result.split(',')[1]; + if (typeof reader.result === "string") { + const base64Data = reader.result.split(",")[1]; if (base64Data) { - setValue('vcFile', base64Data, { shouldValidate: true }); + setValue("vcFile", base64Data, { shouldValidate: true }); } } }; @@ -88,62 +88,57 @@ export const KYCModal = ({ isOpen, onClose }: KYCModalProps) => { }); }; - const isDisable = !isValid || !watch('vcFile'); + const isDisable = !isValid || !watch("vcFile"); return ( { - setFileName(''); + setFileName(""); reset(); onClose(); }} > - - {tCreate('title')} + + {tCreate("title")} - + - {fileName} + {fileName} - diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/AddProceedRecipientModal.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/AddProceedRecipientModal.tsx new file mode 100644 index 000000000..b615ea225 --- /dev/null +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/AddProceedRecipientModal.tsx @@ -0,0 +1,128 @@ +import { + HStack, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + ModalProps, + VStack, +} from '@chakra-ui/react'; +import { Button, InputController } from 'io-bricks-ui'; +import { useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { useParams } from 'react-router-dom'; +import { isValidHederaId, required } from '../../../../utils/rules'; +import { useAddProceedRecipient } from '../../../../hooks/mutations/useProceedRecipients'; +import { AddProceedRecipientRequest } from '@hashgraph/asset-tokenization-sdk'; +import { textToHex } from '../../../../utils/format'; + +interface FormValues { + address: string; + data?: string; +} + +interface AddProceedRecipientModalProps extends Omit {} + +export const AddProceedRecipientModal = ({ + isOpen, + onClose, +}: AddProceedRecipientModalProps) => { + const { id: securityId = '' } = useParams(); + + const { t: tCreate } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients.create', + }); + + const { + control, + formState: { isValid }, + handleSubmit, + reset, + } = useForm({ + mode: 'onChange', + }); + + const { + mutate: addProceedRecipientMutation, + isPending: isPendingAddProceedRecipient, + } = useAddProceedRecipient(); + + const onSubmit = (values: FormValues) => { + const request = new AddProceedRecipientRequest({ + securityId, + proceedRecipientId: values.address, + data: values.data ? textToHex(values.data) : '', + }); + + addProceedRecipientMutation(request, { + onSettled() { + onClose(); + }, + onSuccess() { + reset(); + }, + }); + }; + + return ( + { + reset(); + onClose(); + }} + > + + + {tCreate('title')} + + + + + + + + + + + + + + + + ); +}; diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/ProceedRecipients.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/ProceedRecipients.tsx new file mode 100644 index 000000000..5609255a9 --- /dev/null +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/ProceedRecipients.tsx @@ -0,0 +1,210 @@ +import { Flex, HStack, Stack, useDisclosure } from '@chakra-ui/react'; +import { Button, PhosphorIcon, PopUp, Table, Text } from 'io-bricks-ui'; +import { useMemo, useState } from 'react'; +import { SecurityRole } from '../../../../utils/SecurityRole'; +import { useRolesStore } from '../../../../store/rolesStore'; +import { useTranslation } from 'react-i18next'; +import { useParams } from 'react-router-dom'; +import { createColumnHelper } from '@tanstack/table-core'; +import { Pencil, Trash } from '@phosphor-icons/react'; +import { AddProceedRecipientModal } from './AddProceedRecipientModal'; +import { + GetProceedRecipientsCountRequest, + RemoveProceedRecipientRequest, +} from '@hashgraph/asset-tokenization-sdk'; +import { + ProceedRecipientDataViewModelResponse, + useGetProceedRecipientList, +} from '../../../../hooks/queries/useProceedRecipients'; +import { UpdateProceedRecipientModal } from './UpdateProceedRecipientModal'; +import { useRemoveProceedRecipient } from '../../../../hooks/mutations/useProceedRecipients'; +import { hexToText } from '../../../../utils/format'; + +export const ProceedRecipients = () => { + const { id: securityId = '' } = useParams(); + + const { roles: accountRoles } = useRolesStore(); + + const { t: tProceedRecipients } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients', + }); + const { t: tTable } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients.table', + }); + const { t: tRemove } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients.remove', + }); + + const [proceedRecipientIdSelected, setProceedRecipientIdSelected] = + useState(''); + + const { isOpen, onClose, onOpen } = useDisclosure(); + const { + isOpen: isOpenUpdate, + onClose: onCloseUpdate, + onOpen: onOpenUpdate, + } = useDisclosure(); + const { + isOpen: isOpenRemoveProceedRecipientModal, + onClose: onCloseRemoveProceedRecipientModal, + onOpen: onOpenRemoveProceedRecipientModal, + } = useDisclosure(); + + const hasProceedRecipientManagerRole = useMemo( + () => + accountRoles.findIndex( + (rol) => rol === SecurityRole._PROCEED_RECIPIENT_MANAGER_ROLE, + ) !== -1, + [accountRoles], + ); + + const { data: proceedRecipients, isLoading: isLoadingProceedRecipients } = + useGetProceedRecipientList( + new GetProceedRecipientsCountRequest({ + securityId, + }), + ); + + const { + mutate: removeProceedRecipientMutation, + isPending: isPendingRemoveProceedRecipient, + } = useRemoveProceedRecipient(); + + const columnsHelper = + createColumnHelper(); + + const columns = [ + columnsHelper.accessor('address', { + header: tTable('fields.address'), + enableSorting: false, + }), + columnsHelper.accessor('data', { + header: tTable('fields.data'), + enableSorting: false, + cell({ + row: { + original: { data }, + }, + }) { + return data ? hexToText(data) : '-'; + }, + }), + ...(hasProceedRecipientManagerRole + ? [ + columnsHelper.display({ + id: 'remove', + header: tTable('fields.actions'), + size: 5, + enableSorting: false, + cell(props) { + const { + row: { + original: { address }, + }, + } = props; + + return ( + + + + + ); + }, + }), + ] + : []), + ]; + + return ( + <> + + + + {tProceedRecipients('title')} + + {hasProceedRecipientManagerRole && ( + + )} + + + No proceed recipients + + } + /> + + + + } + title={tRemove('confirmPopUp.title')} + description={tRemove('confirmPopUp.description')} + confirmText={tRemove('confirmPopUp.confirmText')} + onConfirm={() => { + const request = new RemoveProceedRecipientRequest({ + securityId, + proceedRecipientId: proceedRecipientIdSelected, + }); + + removeProceedRecipientMutation(request, { + onSuccess() { + onCloseRemoveProceedRecipientModal(); + }, + }); + }} + onCancel={onCloseRemoveProceedRecipientModal} + cancelText={tRemove('confirmPopUp.cancelText')} + confirmButtonProps={{ + isLoading: isPendingRemoveProceedRecipient, + }} + /> + + ); +}; diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/RemoveProceedRecipientModal.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/RemoveProceedRecipientModal.tsx new file mode 100644 index 000000000..c67a85901 --- /dev/null +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/RemoveProceedRecipientModal.tsx @@ -0,0 +1,128 @@ +import { + HStack, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + ModalProps, + VStack, +} from '@chakra-ui/react'; +import { Button, InputController } from 'io-bricks-ui'; +import { useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { useParams } from 'react-router-dom'; +import { isValidHederaId, required } from '../../../../utils/rules'; +import { useAddProceedRecipient } from '../../../../hooks/mutations/useProceedRecipients'; +import { AddProceedRecipientRequest } from '@hashgraph/asset-tokenization-sdk'; + +interface FormValues { + address: string; + data?: string; +} + +interface AddProceedRecipientModalProps extends Omit {} + +export const AddProceedRecipientModal = ({ + isOpen, + onClose, +}: AddProceedRecipientModalProps) => { + const { id: securityId = '' } = useParams(); + + const { t: tCreate } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients.create', + }); + + const { + control, + formState: { isValid }, + handleSubmit, + reset, + } = useForm({ + mode: 'onChange', + }); + + const { + mutate: addProceedRecipientMutation, + isPending: isPendingAddProceedRecipient, + } = useAddProceedRecipient(); + + const onSubmit = (values: FormValues) => { + const request = new AddProceedRecipientRequest({ + securityId, + proceedRecipientId: values.address, + data: values.data ?? '', + }); + + console.log('request', request); + + addProceedRecipientMutation(request, { + onSettled() { + onClose(); + }, + onSuccess() { + reset(); + }, + }); + }; + + return ( + { + reset(); + onClose(); + }} + > + + + {tCreate('title')} + + + + + + + + + + + + + + + + ); +}; diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/UpdateProceedRecipientModal.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/UpdateProceedRecipientModal.tsx new file mode 100644 index 000000000..09b75bcc5 --- /dev/null +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/ProceedRecipients/UpdateProceedRecipientModal.tsx @@ -0,0 +1,130 @@ +import { + HStack, + Modal, + ModalBody, + ModalCloseButton, + ModalContent, + ModalFooter, + ModalHeader, + ModalOverlay, + ModalProps, + VStack, +} from '@chakra-ui/react'; +import { Button, Input, InputController } from 'io-bricks-ui'; +import { useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { useParams } from 'react-router-dom'; +import { useUpdateProceedRecipient } from '../../../../hooks/mutations/useProceedRecipients'; +import { UpdateProceedRecipientDataRequest } from '@hashgraph/asset-tokenization-sdk'; +import { textToHex } from '../../../../utils/format'; + +interface FormValues { + address: string; + data?: string; +} + +interface UpdateProceedRecipientModalProps + extends Omit { + proceedRecipientId: string; +} + +export const UpdateProceedRecipientModal = ({ + isOpen, + onClose, + proceedRecipientId, +}: UpdateProceedRecipientModalProps) => { + const { id: securityId = '' } = useParams(); + + const { t: tUpdate } = useTranslation('security', { + keyPrefix: 'details.proceedRecipients.update', + }); + + const { + control, + formState: { isValid }, + handleSubmit, + reset, + } = useForm({ + mode: 'onChange', + defaultValues: { + address: proceedRecipientId, + }, + }); + + const { + mutate: updateProceedRecipientMutation, + isPending: isPendingUpdateProceedRecipient, + } = useUpdateProceedRecipient(); + + const onSubmit = (values: FormValues) => { + const request = new UpdateProceedRecipientDataRequest({ + securityId, + proceedRecipientId, + data: values.data ? textToHex(values.data) : '', + }); + + updateProceedRecipientMutation(request, { + onSettled() { + onClose(); + }, + onSuccess() { + reset(); + }, + }); + }; + + return ( + { + reset(); + onClose(); + }} + > + + + {tUpdate('title')} + + + + + + + + + + + + + + + + ); +}; diff --git a/apps/ats/web/src/views/DigitalSecurityDetails/Components/RoleManagement/HandleRoles.tsx b/apps/ats/web/src/views/DigitalSecurityDetails/Components/RoleManagement/HandleRoles.tsx index ec422766f..e64b2a468 100644 --- a/apps/ats/web/src/views/DigitalSecurityDetails/Components/RoleManagement/HandleRoles.tsx +++ b/apps/ats/web/src/views/DigitalSecurityDetails/Components/RoleManagement/HandleRoles.tsx @@ -205,7 +205,7 @@ import { Button, HStack, VStack } from '@chakra-ui/react'; import { useTranslation } from 'react-i18next'; -import { CheckboxGroupController, Text } from 'io-bricks-ui'; +import { Checkbox, CheckboxGroupController, Text } from 'io-bricks-ui'; import { required } from '../../../../utils/rules'; import { SubmitHandler, useForm } from 'react-hook-form'; import { ApplyRolesRequest } from '@hashgraph/asset-tokenization-sdk'; @@ -241,13 +241,17 @@ export const HandleRoles = ({ const { id = '' } = useParams(); const { mutate: applyRoles, isLoading: isLoadingApply } = useApplyRoles(); - const { handleSubmit: onHandleSubmit, control: controlRoles } = - useForm({ - mode: 'onSubmit', - defaultValues: { - roles: currentRoles, - }, - }); + const { + handleSubmit: onHandleSubmit, + control: controlRoles, + watch, + setValue, + } = useForm({ + mode: 'onSubmit', + defaultValues: { + roles: currentRoles, + }, + }); const onSubmitRoles: SubmitHandler = ( params: EditRolesFormValues, @@ -269,6 +273,29 @@ export const HandleRoles = ({ applyRoles(request); }; + const roleListAvailable = rolesList.filter((role) => { + if (!securityDetails) return role; + + return role.allowedSecurities.includes( + securityDetails.type as TSecurityType, + ); + }); + + const handleSelectAllRoles = () => { + if (allRolesSelected) { + setValue( + 'roles', + currentRoles.length === roleListAvailable.length ? [] : currentRoles, + ); + return; + } + + const allRoleValues = roleListAvailable.map((role) => role.label); + setValue('roles', allRoleValues); + }; + + const allRolesSelected = watch('roles').length === roleListAvailable.length; + return ( {t('rolesDefinitions')} - { - if (!securityDetails) return role; - - return role.allowedSecurities.includes( - securityDetails.type as TSecurityType, - ); - }) - .map((role) => ({ + + + + {t('selectAllRoles')} + + ({ value: role.label, label: tRoles(role.label), }))} - rules={{ required }} - variant="roles" - gap={4} - /> + rules={{ required }} + variant="roles" + gap={4} + /> + - + ); diff --git a/apps/ats/web/src/views/DigitalSecurityForceRedeem/__tests__/DigitalSecurityForceRedeem.test.tsx b/apps/ats/web/src/views/DigitalSecurityForceRedeem/__tests__/DigitalSecurityForceRedeem.test.tsx index 8a50bd9ba..b1c5f81d7 100644 --- a/apps/ats/web/src/views/DigitalSecurityForceRedeem/__tests__/DigitalSecurityForceRedeem.test.tsx +++ b/apps/ats/web/src/views/DigitalSecurityForceRedeem/__tests__/DigitalSecurityForceRedeem.test.tsx @@ -1,240 +1,175 @@ -/* - 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. - -*/ - -import { DigitalSecurityForceRedeem } from '../DigitalSecurityForceRedeem'; -import { render } from '../../../test-utils'; +//SPDX-License-Identifier: Apache-2.0 + +import { DigitalSecurityForceRedeem } from "../DigitalSecurityForceRedeem"; +import { render } from "../../../test-utils"; +import { screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; + +const SOURCE_PLACEHOLDER = "Enter the account"; +const AMOUNT_PLACEHOLDER = "Enter the amount to redeem"; describe(`${DigitalSecurityForceRedeem.name}`, () => { const factoryComponent = () => { return render(); }; - test('render correctly', () => { + test("render correctly", () => { const component = factoryComponent(); expect(component.asFragment()).toMatchSnapshot(); }); - test('should show Goback button', () => { + test("should show Goback button", () => { const component = factoryComponent(); - const breadcrumbs = component.getByTestId('go-back-button'); + const breadcrumbs = component.getByTestId("go-back-button"); expect(breadcrumbs).toBeInTheDocument(); }); - test('should show breadcrumbs', () => { + test("should show breadcrumbs", () => { const component = factoryComponent(); - const breadcrumbs = component.getByTestId('breadcrumb-desktop'); + const breadcrumbs = component.getByTestId("breadcrumb-desktop"); expect(breadcrumbs).toBeInTheDocument(); }); - test('should form be rendered properly', () => { + test("should form be rendered properly", () => { const component = factoryComponent(); - const form = component.getByTestId('force-redeem-form'); + const form = component.getByTestId("force-redeem-form"); expect(form).toBeInTheDocument(); }); + + test("should render fullRedeem checkbox", () => { + factoryComponent(); + + const checkbox = screen.getByRole("checkbox"); + expect(checkbox).toBeInTheDocument(); + expect(checkbox).not.toBeChecked(); + }); + + test("should redeem button be disabled when form is empty", () => { + factoryComponent(); + + const redeemButton = screen.getByTestId("redeem-security-button"); + expect(redeemButton).toBeDisabled(); + }); + + test("should redeem button be disabled when only source is filled", async () => { + factoryComponent(); + + const sourceInput = screen.getByPlaceholderText(SOURCE_PLACEHOLDER); + await userEvent.type(sourceInput, "0x1234567890abcdef"); + + const redeemButton = screen.getByTestId("redeem-security-button"); + expect(redeemButton).toBeDisabled(); + }); + + test("should redeem button be enabled when source and amount are filled", async () => { + factoryComponent(); + + const sourceInput = screen.getByPlaceholderText(SOURCE_PLACEHOLDER); + await userEvent.type(sourceInput, "0x1234567890abcdef"); + + const amountInput = screen.getByPlaceholderText(AMOUNT_PLACEHOLDER); + await userEvent.type(amountInput, "100"); + + await waitFor(() => { + const redeemButton = screen.getByTestId("redeem-security-button"); + expect(redeemButton).toBeEnabled(); + }); + }); + + test("should redeem button be enabled when source is filled and fullRedeem is checked", async () => { + factoryComponent(); + + const sourceInput = screen.getByPlaceholderText(SOURCE_PLACEHOLDER); + await userEvent.type(sourceInput, "0x1234567890abcdef"); + + const checkbox = screen.getByRole("checkbox"); + await userEvent.click(checkbox); + + await waitFor(() => { + const redeemButton = screen.getByTestId("redeem-security-button"); + expect(redeemButton).toBeEnabled(); + }); + }); + + test("should disable amount input when fullRedeem is checked", async () => { + factoryComponent(); + + const amountInput = screen.getByPlaceholderText(AMOUNT_PLACEHOLDER); + expect(amountInput).toBeEnabled(); + + const checkbox = screen.getByRole("checkbox"); + await userEvent.click(checkbox); + + await waitFor(() => { + expect(amountInput).toBeDisabled(); + }); + }); + + test("should enable amount input when fullRedeem is unchecked", async () => { + factoryComponent(); + + const checkbox = screen.getByRole("checkbox"); + await userEvent.click(checkbox); + + const amountInput = screen.getByPlaceholderText(AMOUNT_PLACEHOLDER); + await waitFor(() => { + expect(amountInput).toBeDisabled(); + }); + + await userEvent.click(checkbox); + await waitFor(() => { + expect(amountInput).toBeEnabled(); + }); + }); + + test("should redeem button be disabled when fullRedeem is checked but source is empty", async () => { + factoryComponent(); + + const checkbox = screen.getByRole("checkbox"); + await userEvent.click(checkbox); + + const redeemButton = screen.getByTestId("redeem-security-button"); + expect(redeemButton).toBeDisabled(); + }); + + test("should clear amount when fullRedeem is checked and unchecked", async () => { + factoryComponent(); + + const amountInput = screen.getByPlaceholderText(AMOUNT_PLACEHOLDER); + await userEvent.type(amountInput, "100"); + + expect(amountInput).toHaveValue("100"); + + const checkbox = screen.getByRole("checkbox"); + await userEvent.click(checkbox); + await userEvent.click(checkbox); + + await waitFor(() => { + expect(amountInput).toHaveValue(""); + }); + }); + + test("should keep source value when toggling fullRedeem checkbox", async () => { + factoryComponent(); + + const sourceInput = screen.getByPlaceholderText(SOURCE_PLACEHOLDER); + await userEvent.type(sourceInput, "0x1234567890abcdef"); + + const checkbox = screen.getByRole("checkbox"); + await userEvent.click(checkbox); + + await waitFor(() => { + expect(sourceInput).toHaveValue("0x1234567890abcdef"); + }); + + await userEvent.click(checkbox); + + await waitFor(() => { + expect(sourceInput).toHaveValue("0x1234567890abcdef"); + }); + }); }); diff --git a/apps/ats/web/src/views/DigitalSecurityForceRedeem/__tests__/__snapshots__/DigitalSecurityForceRedeem.test.tsx.snap b/apps/ats/web/src/views/DigitalSecurityForceRedeem/__tests__/__snapshots__/DigitalSecurityForceRedeem.test.tsx.snap index 1ae30c3ac..9d1969286 100644 --- a/apps/ats/web/src/views/DigitalSecurityForceRedeem/__tests__/__snapshots__/DigitalSecurityForceRedeem.test.tsx.snap +++ b/apps/ats/web/src/views/DigitalSecurityForceRedeem/__tests__/__snapshots__/DigitalSecurityForceRedeem.test.tsx.snap @@ -152,6 +152,34 @@ exports[`DigitalSecurityForceRedeem render correctly 1`] = ` +
+ +
diff --git a/apps/ats/web/src/views/DigitalSecurityRedeem/DigitalSecurityRedeem.tsx b/apps/ats/web/src/views/DigitalSecurityRedeem/DigitalSecurityRedeem.tsx index 46fbefac1..15767be34 100644 --- a/apps/ats/web/src/views/DigitalSecurityRedeem/DigitalSecurityRedeem.tsx +++ b/apps/ats/web/src/views/DigitalSecurityRedeem/DigitalSecurityRedeem.tsx @@ -1,250 +1,47 @@ -/* - 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. - -*/ - -import { HStack, Stack, VStack } from '@chakra-ui/react'; -import { History } from '../../components/History'; -import { useTranslation } from 'react-i18next'; -import { Text, InputNumberController, Button } from 'io-bricks-ui'; -import { SubmitHandler, useForm } from 'react-hook-form'; -import { required, min } from '../../utils/rules'; -import { CancelButton } from '../../components/CancelButton'; -import { useParams } from 'react-router'; -import { useRedeemSecurity } from '../../hooks/queries/useRedeemSecurity'; -import { RedeemRequest } from '@hashgraph/asset-tokenization-sdk'; -import { DetailsBalancePanel } from '../../components/DetailsBalancePanel'; -import { useDetailsBalancePanel } from '../../hooks/useDetailsBalancePanel'; -import { useWalletStore } from '../../store/walletStore'; -import { useSecurityStore } from '../../store/securityStore'; +//SPDX-License-Identifier: Apache-2.0 + +import { HStack, Stack, VStack } from "@chakra-ui/react"; +import { History } from "../../components/History"; +import { useTranslation } from "react-i18next"; +import { Text, InputNumberController, Button } from "io-bricks-ui"; +import { SubmitHandler, useForm } from "react-hook-form"; +import { required, min } from "../../utils/rules"; +import { CancelButton } from "../../components/CancelButton"; +import { useParams } from "react-router"; +import { useRedeemSecurity } from "../../hooks/queries/useRedeemSecurity"; +import { RedeemRequest } from "@hashgraph/asset-tokenization-sdk"; +import { DetailsBalancePanel } from "../../components/DetailsBalancePanel"; +import { useDetailsBalancePanel } from "../../hooks/useDetailsBalancePanel"; +import { useWalletStore } from "../../store/walletStore"; +import { useSecurityStore } from "../../store/securityStore"; interface RedeemFormValues { amount: number; } export const DigitalSecurityRedeem = () => { - const { t: tHeader } = useTranslation('security', { - keyPrefix: 'redeem.header', + const { t: tHeader } = useTranslation("security", { + keyPrefix: "redeem.header", }); - const { t: tForm } = useTranslation('security', { - keyPrefix: 'redeem.input', + const { t: tForm } = useTranslation("security", { + keyPrefix: "redeem.input", }); - const { t } = useTranslation('security', { keyPrefix: 'redeem' }); - const { t: tGlobal } = useTranslation('globals'); - const { control, formState, handleSubmit, reset } = useForm( - { - mode: 'all', - }, - ); - const { t: TButton } = useTranslation('security', { - keyPrefix: 'redeem.button', + const { t } = useTranslation("security", { keyPrefix: "redeem" }); + const { t: tGlobal } = useTranslation("globals"); + const { control, formState, handleSubmit, reset } = useForm({ + mode: "all", }); - const { id = '' } = useParams(); + const { t: TButton } = useTranslation("security", { + keyPrefix: "redeem.button", + }); + const { id = "" } = useParams(); const { details } = useSecurityStore(); const { address: walletAddress } = useWalletStore(); - const { currentAvailableBalance, isCurrentAvailableBalanceLoading, update } = - useDetailsBalancePanel(id, walletAddress); + const { currentAvailableBalance, isCurrentAvailableBalanceLoading, update } = useDetailsBalancePanel( + id, + walletAddress, + ); const { mutate: redeemSecurity, isLoading } = useRedeemSecurity({ onSettled: () => update(), @@ -264,15 +61,8 @@ export const DigitalSecurityRedeem = () => { return ( <> - - + + { as="form" onSubmit={handleSubmit(submit)} > - {t('title')} + {t("title")} - {t('subtitle')} + {t("subtitle")} - {tGlobal('mandatoryFields')} + {tGlobal("mandatoryFields")} { }} size="md" allowNegative={false} - label={tForm('amount.label')} - placeholder={tForm('amount.placeholder')} + label={tForm("amount.label")} + placeholder={tForm("amount.placeholder")} decimalScale={details?.decimals} fixedDecimalScale={true} thousandSeparator="," decimalSeparator="." /> - + - + ); diff --git a/apps/ats/web/vite.config.ts b/apps/ats/web/vite.config.ts index bbf1917d3..fc0497e1e 100644 --- a/apps/ats/web/vite.config.ts +++ b/apps/ats/web/vite.config.ts @@ -1,303 +1,70 @@ -/* - 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. - -*/ +// SPDX-License-Identifier: Apache-2.0 import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'; // yarn add --dev @esbuild-plugins/node-modules-polyfill -import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'; +import { NodeModulesPolyfillPlugin } from '@esbuild-plugins/node-modules-polyfill'; // Temporarily disabled // You don't need to add this to deps, it's included by @esbuild-plugins/node-modules-polyfill -import rollupNodePolyFill from 'rollup-plugin-node-polyfills'; import commonjs from '@rollup/plugin-commonjs'; import react from '@vitejs/plugin-react'; import tsconfigPaths from 'vite-tsconfig-paths'; import EnvironmentPlugin from 'vite-plugin-environment'; import pluginRewriteAll from 'vite-plugin-rewrite-all'; +import { nodePolyfills } from 'vite-plugin-node-polyfills'; export default { plugins: [ react(), EnvironmentPlugin('all'), pluginRewriteAll(), - { - name: 'singleHMR', - handleHotUpdate({ modules }) { - modules.map((m) => { - m.importedModules = new Set(); - m.importers = new Set(); - }); - return modules; - }, - }, tsconfigPaths(), - { - name: 'fix-node-globals-polyfill', - setup(build) { - build.onResolve({ filter: /util\.js/ }, ({ path }) => ({ path })); + nodePolyfills({ + protocolImports: true, + globals: { + Buffer: true, + global: true, + process: true, }, - }, + overrides: { + fs: 'memfs', + }, + include: [ + 'buffer', + 'process', + 'util', + 'stream', + 'crypto', + 'os', + 'vm', + 'path', + ], + exclude: ['http', 'https', 'url', 'querystring', 'path', 'fs'], + }), ], + define: { + ...(process.env.NODE_ENV === 'development' ? { global: 'globalThis' } : {}), + }, resolve: { alias: { - // This Rollup aliases are extracted from @esbuild-plugins/node-modules-polyfill, - // see https://github.com/remorses/esbuild-plugins/blob/master/node-modules-polyfill/src/polyfills.ts - // process and buffer are excluded because already managed - // by node-globals-polyfill - util: 'util', - sys: 'util', - events: 'rollup-plugin-node-polyfills/polyfills/events', - stream: 'rollup-plugin-node-polyfills/polyfills/stream', - path: 'rollup-plugin-node-polyfills/polyfills/path', - querystring: 'rollup-plugin-node-polyfills/polyfills/qs', - punycode: 'rollup-plugin-node-polyfills/polyfills/punycode', - url: 'rollup-plugin-node-polyfills/polyfills/url', - string_decoder: - 'rollup-plugin-node-polyfills/polyfills/string-decoder.js', - http: 'rollup-plugin-node-polyfills/polyfills/http', - https: 'rollup-plugin-node-polyfills/polyfills/http', - os: 'rollup-plugin-node-polyfills/polyfills/os', - assert: 'rollup-plugin-node-polyfills/polyfills/assert', - constants: 'rollup-plugin-node-polyfills/polyfills/constants', - _stream_duplex: - 'rollup-plugin-node-polyfills/polyfills/readable-stream/duplex', - _stream_passthrough: - 'rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough', - _stream_readable: - 'rollup-plugin-node-polyfills/polyfills/readable-stream/readable', - _stream_writable: - 'rollup-plugin-node-polyfills/polyfills/readable-stream/writable', - _stream_transform: - 'rollup-plugin-node-polyfills/polyfills/readable-stream/transform', - timers: 'rollup-plugin-node-polyfills/polyfills/timers', - console: 'rollup-plugin-node-polyfills/polyfills/console', - vm: 'rollup-plugin-node-polyfills/polyfills/vm', - zlib: 'rollup-plugin-node-polyfills/polyfills/zlib', - tty: 'rollup-plugin-node-polyfills/polyfills/tty', - domain: 'rollup-plugin-node-polyfills/polyfills/domain', - buffer: 'rollup-plugin-node-polyfills/polyfills/buffer-es6', - process: 'rollup-plugin-node-polyfills/polyfills/process-es6', - // Winston and logging related modules - provide mock implementations for browser winston: '/src/winston-mock.js', - 'winston-daily-rotate-file': - 'rollup-plugin-node-polyfills/polyfills/empty.js', - 'winston-transport': 'rollup-plugin-node-polyfills/polyfills/empty.js', + 'winston-daily-rotate-file': '/src/winston-mock.js', + 'winston-transport': '/src/winston-mock.js', }, - dedupe: ['@emotion/react'], + dedupe: ['react', 'react-dom', '@emotion/react', '@emotion/styled'], }, optimizeDeps: { include: [ '@hashgraph/asset-tokenization-contracts', '@hashgraph/asset-tokenization-sdk', + '@chakra-ui/react', + '@emotion/react', + '@emotion/styled', + 'framer-motion', ], exclude: ['winston', 'winston-daily-rotate-file', 'winston-transport'], esbuildOptions: { - /********* New line inserted ***********/ - // inject: ['./vite-polyfills/setImmediate.js'], - // Node.js global to browser globalThis define: { global: 'globalThis', }, - // Enable esbuild polyfill plugins plugins: [ NodeGlobalsPolyfillPlugin({ process: true, @@ -309,14 +76,9 @@ export default { }, build: { rollupOptions: { - external: ['winston', 'winston-daily-rotate-file', 'winston-transport'], plugins: [ - // Enable rollup polyfills plugin - // used during production bundling - rollupNodePolyFill(), - // Handle CommonJS modules commonjs({ - include: ['**/node_modules/**', '**/packages/ats/contracts/**'], + include: ['**/packages/ats/contracts/**'], }), ], }, diff --git a/apps/mass-payout/README.md b/apps/mass-payout/README.md deleted file mode 100644 index 184e164af..000000000 --- a/apps/mass-payout/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Mass Payout Application - -## Status: Placeholder - -This workspace is currently a placeholder for the future mass payout web application. It has been created as part of the monorepo structure to reserve the workspace namespace and ensure proper workspace configuration. - -## Future Development - -This application will contain: - -- Web interface for mass payout operations -- User dashboard for payment management -- Integration with mass payout package components -- Administrative tools for batch processing - -## Current Structure - -``` -apps/mass-payout/ -├── package.json # Basic workspace configuration -└── README.md # This file -``` - -## Development - -Currently, this workspace contains only placeholder scripts. All commands will output placeholder messages: - -```bash -npm run build # Placeholder build command -npm run test # Placeholder test command -npm run dev # Placeholder dev command -npm run start # Placeholder start command -``` - -## Technology Stack - -When implemented, this application will likely use: - -- React with TypeScript -- Vite for build tooling -- Integration with the mass payout package -- Hedera SDK integration - -## Contributing - -This workspace is not yet ready for development. Please refer to the main project documentation for contribution guidelines. diff --git a/apps/mass-payout/backend/.env.example b/apps/mass-payout/backend/.env.example new file mode 100644 index 000000000..0e8bd4323 --- /dev/null +++ b/apps/mass-payout/backend/.env.example @@ -0,0 +1,20 @@ +NODE_ENV=local +APP_ENV=local +LOG_LEVEL=log +PORT=3000 +POSTGRESQL_HOST=localhost +POSTGRESQL_PORT=5432 +POSTGRESQL_USER=postgres +POSTGRESQL_PASSWORD=postgres +POSTGRESQL_DB=postgres +BATCH_SIZE=100 + +# Mainnet +#BLOCKCHAIN_MIRROR_NODE_URL=https://mainnet-public.mirrornode.hedera.com +#BLOCKCHAIN_CONTRACT_ID=0.0.456858 +# Testnet +BLOCKCHAIN_MIRROR_NODE_URL=https://testnet.mirrornode.hedera.com +BLOCKCHAIN_CONTRACT_ID=0.0.429274 +BLOCKCHAIN_TOKEN_DECIMALS=6 +BLOCKCHAIN_LISTENER_POLL_TIMEOUT=10000 +BLOCKCHAIN_LISTENER_START_TIMESTAMP=2025-08-26T00:00:00.000Z \ No newline at end of file diff --git a/apps/mass-payout/backend/.env.test b/apps/mass-payout/backend/.env.test new file mode 100644 index 000000000..89e5e6045 --- /dev/null +++ b/apps/mass-payout/backend/.env.test @@ -0,0 +1,10 @@ +APP_ENV=local +LOG_LEVEL=log +PORT=3000 +HEDERA_USDC_ADDRESS=0.0.123456 + +BLOCKCHAIN_MIRROR_NODE_URL=https://testnet.mirrornode.hedera.com +BLOCKCHAIN_CONTRACT_ID=0.0.429274 +BLOCKCHAIN_TOKEN_DECIMALS=6 +BLOCKCHAIN_LISTENER_POLL_TIMEOUT=10000 +BLOCKCHAIN_LISTENER_START_TIMESTAMP=2025-08-26T00:00:00.000Z \ No newline at end of file diff --git a/apps/mass-payout/backend/.prettierrc b/apps/mass-payout/backend/.prettierrc new file mode 100644 index 000000000..c69378499 --- /dev/null +++ b/apps/mass-payout/backend/.prettierrc @@ -0,0 +1,7 @@ +{ + "singleQuote": false, + "semi": false, + "printWidth": 120, + "tabWidth": 2, + "endOfLine": "lf" +} \ No newline at end of file diff --git a/apps/mass-payout/backend/Dockerfile b/apps/mass-payout/backend/Dockerfile new file mode 100644 index 000000000..9ee843354 --- /dev/null +++ b/apps/mass-payout/backend/Dockerfile @@ -0,0 +1,10 @@ +FROM node:22.17.0 +RUN DEBIAN_FRONTEND=noninteractive apt update -y && apt dist-upgrade -y && apt clean +RUN mkdir /app +COPY . /app +WORKDIR /app +RUN npm install +ENV PATH=/app/node_modules/.bin:$PATH +RUN npm run build +EXPOSE 3000 +CMD ["npm", "run", "start:prod"] \ No newline at end of file diff --git a/apps/mass-payout/backend/README.md b/apps/mass-payout/backend/README.md new file mode 100644 index 000000000..0ba38b063 --- /dev/null +++ b/apps/mass-payout/backend/README.md @@ -0,0 +1,83 @@ +# Scheduler Payment Distribution service + +## Table of Contents + +- [Installation](#installation) +- [Running the app](#running-the-app) +- [Test](#test) + +## Installation + +install node version `22.17.0` + +Create a `.env` file with the following command: + +```bash + cp .env.example .env +``` + +Install dependencies with the following command: + +```bash + npm install +``` + +Start the postgres database with the docker-compose file: + +```bash +docker-compose up -d +``` + +## Running the app + +```bash +# development +$ npm run start + +# watch mode +$ npm run start:dev + +# production mode +$ npm run start:prod +``` + +## Test + +```bash +# all tests +$ npm run test + +# unit tests +$ npm run test:unit + +# e2e tests +$ npm run test:e2e + +# test coverage +$ npm run test:cov +``` + +# IDE configuration + +## VSCode + +1. Install both [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) plugins. +2. Open VSCode's preferences: command + shift + p -> search for 'open user settings (JSON)' +3. Copy these parameters: + +```json +"editor.formatOnPaste": true, +"editor.defaultFormatter": "esbenp.prettier-vscode", +"editor.codeActionsOnSave": { +"source.organizeImports": true +} +``` + +## IntelliJ + +1. Open settings +2. Navigate to Languages & Frameworks > Javascript > Prettier +3. Check both 'Automatic Prettier configuration' & 'Run on save' +4. Navigate to Tools > Actions on Save +5. Check 'Optimize imports' diff --git a/apps/mass-payout/backend/babel.config.mjs b/apps/mass-payout/backend/babel.config.mjs new file mode 100644 index 000000000..ec74c3744 --- /dev/null +++ b/apps/mass-payout/backend/babel.config.mjs @@ -0,0 +1,13 @@ +export default { + presets: [ + [ + "@babel/preset-env", + { + targets: { + node: "current", + }, + modules: "commonjs", + }, + ], + ], +} diff --git a/apps/mass-payout/backend/docker-compose.yml b/apps/mass-payout/backend/docker-compose.yml new file mode 100644 index 000000000..9f620ca48 --- /dev/null +++ b/apps/mass-payout/backend/docker-compose.yml @@ -0,0 +1,9 @@ +services: + db: + image: postgres:latest + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + ports: + - "5432:5432" diff --git a/apps/mass-payout/backend/eslint.config.mjs b/apps/mass-payout/backend/eslint.config.mjs new file mode 100644 index 000000000..7f746a04b --- /dev/null +++ b/apps/mass-payout/backend/eslint.config.mjs @@ -0,0 +1,337 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { fixupConfigRules, fixupPluginRules } from "@eslint/compat" +import typescriptEslint from "@typescript-eslint/eslint-plugin" +import unusedImports from "eslint-plugin-unused-imports" +import stylisticTs from "@stylistic/eslint-plugin-ts" +import globals from "globals" +import tsParser from "@typescript-eslint/parser" +import path from "node:path" +import { fileURLToPath } from "node:url" +import js from "@eslint/js" +import { FlatCompat } from "@eslint/eslintrc" + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}) + +function legacyPlugin(name, alias = name) { + const plugin = compat.plugins(name)[0]?.plugins?.[alias] + + if (!plugin) { + throw new Error(`Unable to resolve plugin ${name} and/or alias ${alias}`) + } + + return fixupPluginRules(plugin) +} + +export default [ + { + ignores: ["**/.eslintrc.js", "src/migrations/*", "load-tests/*", "babel.config.mjs"], + }, + ...fixupConfigRules(compat.extends("eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier")), + { + plugins: { + "@typescript-eslint": fixupPluginRules(typescriptEslint), + "@stylistic/ts": stylisticTs, + "unused-imports": unusedImports, + import: legacyPlugin("eslint-plugin-import", "import"), + }, + languageOptions: { + globals: { + ...globals.node, + ...globals.jest, + }, + parser: tsParser, + ecmaVersion: 5, + sourceType: "module", + parserOptions: { + project: "tsconfig.json", + tsconfigRootDir: ".", + }, + }, + settings: { + typescript: true, + node: true, + "import/resolver": { + typescript: { + alwaysTryTypes: true, + project: ".", + }, + }, + }, + rules: { + camelcase: "error", + "no-multiple-empty-lines": [ + "error", + { + max: 1, + }, + ], + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": "warn", + "@stylistic/ts/semi": ["error", "never"], + "max-len": [ + "error", + { + code: 120, + ignorePattern: "^import .*", + }, + ], + "@stylistic/ts/quotes": ["error", "double"], + "@stylistic/ts/lines-between-class-members": [ + "error", + "always", + { + exceptAfterSingleLine: true, + }, + ], + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-explicit-any": "off", + "import/no-restricted-paths": [ + "error", + { + zones: [ + { + target: "src/domain/**", + from: "src/application/**", + message: "Domain cannot import from application layer", + }, + { + target: "src/domain/**", + from: "src/infrastructure/**", + message: "Domain cannot import from infrastructure layer", + }, + { + target: "src/application/**", + from: "src/infrastructure/**", + message: "Application cannot import from infrastructure layer", + }, + ], + }, + ], + }, + }, + { + files: ["**/*.spec.ts", "**/*.test.ts", "**/test/**/*.ts", "**/e2e/**/*.ts"], + languageOptions: { + globals: { + describe: "readonly", + it: "readonly", + test: "readonly", + expect: "readonly", + beforeAll: "readonly", + beforeEach: "readonly", + afterAll: "readonly", + afterEach: "readonly", + jest: "readonly", + }, + }, + }, +] diff --git a/apps/mass-payout/backend/jest.config.js b/apps/mass-payout/backend/jest.config.js new file mode 100644 index 000000000..88dda0b3e --- /dev/null +++ b/apps/mass-payout/backend/jest.config.js @@ -0,0 +1,260 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +const TestType = { + UNIT: "unit", + INTEGRATION: "integration", + E2E: "e2e", +} + +const MAX_WORKERS = process.env.MAX_WORKERS || 4 + +const config = { + moduleFileExtensions: ["js", "json", "ts"], + moduleNameMapper: { + "@domain(.*)$": "/src/domain/$1", + "@application(.*)$": "/src/application/$1", + "@infrastructure(.*)$": "/src/infrastructure/$1", + "@config(.*)$": "/src/config/$1", + "@shared(.*)$": "/src/shared/$1", + "@test(.*)$": "/test/$1", + }, + rootDir: ".", + testRegex: ".*\\.spec\\.ts$", + transform: { + "^.+\\.ts$": "ts-jest", + "^.+\\.js$": "babel-jest", + }, + transformIgnorePatterns: [ + "node_modules/(?!(did-jwt|@terminal3|@hashgraph/asset-tokenization-sdk|@scure|@noble|multiformats|chalk)/)", + ], + collectCoverageFrom: [ + "src/**/*.{js,ts}", + "!src/config/**", + "!src/shared/infrastructure/rest/controller/**", + "!src/main.ts", + "!src/app.module.ts", + ], + coverageDirectory: "/coverage", + testEnvironment: "node", + moduleDirectories: ["node_modules", ""], +} + +function getConfigProjectBy(testType) { + return { + ...config, + displayName: testType.toString(), + testRegex: `test/${testType.toString()}/.*\\.spec\\.ts`, + } +} + +module.exports = { + maxWorkers: MAX_WORKERS, + projects: [ + getConfigProjectBy(TestType.UNIT), + getConfigProjectBy(TestType.E2E), + getConfigProjectBy(TestType.INTEGRATION), + ], + verbose: false, +} diff --git a/apps/mass-payout/backend/nest-cli.json b/apps/mass-payout/backend/nest-cli.json new file mode 100644 index 000000000..d685b716c --- /dev/null +++ b/apps/mass-payout/backend/nest-cli.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://json.schemastore.org/nest-cli", + "collection": "@nestjs/schematics", + "sourceRoot": "src", + "compilerOptions": { + "deleteOutDir": true, + "assets": ["**/*.proto"], + "watchAssets": true + } +} diff --git a/apps/mass-payout/backend/package.json b/apps/mass-payout/backend/package.json new file mode 100644 index 000000000..f2eacf6cb --- /dev/null +++ b/apps/mass-payout/backend/package.json @@ -0,0 +1,87 @@ +{ + "name": "@mass-payout/backend", + "version": "1.0.0", + "description": "Scheduler Payment Distribution Service", + "author": "", + "private": true, + "license": "Apache-2.0", + "scripts": { + "setup": "npm install", + "build": "nest build", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "start": "NODE_ENV=local nest start", + "start:local": "docker-compose up -d --no-recreate; NODE_ENV=local nest start", + "start:dev": "NODE_ENV=local nest start --watch", + "start:debug": "NODE_ENV=local nest start --debug --watch", + "start:prod": "node dist/src/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --cache", + "lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:unit": "jest --selectProjects unit", + "test:integration": "jest --selectProjects integration", + "test:e2e": "jest --selectProjects e2e", + "clean": "rimraf dist", + "clean:deps": "rimraf node_modules" + }, + "dependencies": { + "@faker-js/faker": "9.8.0", + "@hashgraph/asset-tokenization-sdk": "1.15.2", + "@hashgraph/sdk": "2.66.0", + "@nestjs/cli": "10.3.2", + "@nestjs/common": "10.3.3", + "@nestjs/config": "3.2.0", + "@nestjs/core": "10.3.3", + "@nestjs/platform-express": "10.3.3", + "@nestjs/schedule": "^6.0.0", + "@nestjs/swagger": "^7.4.2", + "@nestjs/typeorm": "11.0.0", + "@mass-payout/sdk": "file:../../packages/mass-payout/sdk", + "bn.js": "5.2.1", + "class-transformer": "0.5.1", + "class-validator": "0.14.2", + "joi": "17.12.2", + "pg": "8.16.0", + "reflect-metadata": "0.2.2", + "rxjs": "7.8", + "swagger-ui-express": "^5.0.1", + "typeorm": "0.3.24" + }, + "devDependencies": { + "@babel/preset-env": "7.28.3", + "@eslint/compat": "1.1.0", + "@eslint/eslintrc": "3.1.0", + "@eslint/js": "8.57.1", + "@golevelup/ts-jest": "0.4.0", + "@hashgraph/hedera-custodians-integration": "^1.4.1", + "@nestjs/schematics": "10.1.1", + "@nestjs/testing": "10.3.3", + "@stylistic/eslint-plugin-ts": "2.6.2", + "@types/express": "4.17.21", + "@types/hast": "3.0.4", + "@types/jest": "29.5.12", + "@types/json-schema": "7.0.15", + "@types/node": "20.11.24", + "@types/supertest": "6.0.2", + "@typescript-eslint/eslint-plugin": "8.0.1", + "@typescript-eslint/parser": "8.0.1", + "eslint": "8.57.0", + "eslint-config-prettier": "9.1.0", + "eslint-import-resolver-typescript": "3.6.1", + "eslint-plugin-import": "2.29.1", + "eslint-plugin-prettier": "5.1.3", + "globals": "15.6.0", + "jest": "29.7.0", + "prettier": "3.2.5", + "source-map-support": "0.5.21", + "supertest": "7.0.0", + "testcontainers": "10.7.2", + "ts-jest": "29.1.2", + "ts-node": "10.9.2", + "tsconfig-paths": "4.2.0", + "typed-emitter": "^2.1.0", + "typescript": "5.3.3" + } +} diff --git a/apps/mass-payout/backend/src/app.module-components.ts b/apps/mass-payout/backend/src/app.module-components.ts new file mode 100644 index 000000000..4090087fb --- /dev/null +++ b/apps/mass-payout/backend/src/app.module-components.ts @@ -0,0 +1,362 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { CancelDistributionUseCase } from "@application/use-cases/cancel-distribution.use-case" +import { DisableAssetSyncUseCase } from "@application/use-cases/disable-asset-sync.use-case" +import { EnableAssetSyncUseCase } from "@application/use-cases/enable-asset-sync.use-case" +import { ExecutePayoutUseCase } from "@application/use-cases/execute-payout.use-case" +import { GetAssetDistributionsUseCase } from "@application/use-cases/get-asset-distributions.use-case" +import { GetAssetUseCase } from "@application/use-cases/get-asset.use-case" +import { GetAssetsUseCase } from "@application/use-cases/get-assets.use-case" +import { GetBasicAssetInformationUseCase } from "@application/use-cases/get-basic-asset-information.use-case" +import { GetBlockchainEventListenerConfigUseCase } from "@application/use-cases/get-blockchain-event-listener-config.use-case" +import { GetDistributionHoldersUseCase } from "@application/use-cases/get-distribution-holders.use-case" +import { GetDistributionHolderCountUseCase } from "@application/use-cases/get-distribution-holder-count.use-case" +import { GetDistributionUseCase } from "@application/use-cases/get-distribution.use-case" +import { GetDistributionsUseCase } from "@application/use-cases/get-distributions.use-case" +import { ImportAssetUseCase } from "@application/use-cases/import-asset.use-case" +import { PauseAssetUseCase } from "@application/use-cases/pause-asset.use-case" +import { ProcessBlockchainEventsUseCase } from "@application/use-cases/process-blockchain-events.use-case" +import { ProcessScheduledPayoutsUseCase } from "@application/use-cases/process-scheduled-payouts.use-case" +import { StartBlockchainPollingUseCase } from "@application/use-cases/start-blockchain-polling.use-case" +import { StopBlockchainPollingUseCase } from "@application/use-cases/stop-blockchain-polling.use-case" +import { UnpauseAssetUseCase } from "@application/use-cases/unpause-asset.use-case" +import { UpdateAssetUseCase } from "@application/use-cases/update-asset.use-case" +import { UpsertBlockchainEventListenerConfigUseCase } from "@application/use-cases/upsert-blockchain-event-listener-config.use-case" +import { CreateHoldersDomainService } from "@domain/services/create-holders.domain-service" +import { DisableAssetSyncDomainService } from "@domain/services/disable-asset-sync.domain-service" +import { EnableAssetSyncDomainService } from "@domain/services/enable-asset-sync.domain-service" +import { ExecuteCorporateActionDistributionDomainService } from "@domain/services/execute-corporate-action-distribution.domain-service" +import { ExecutePayoutDistributionDomainService } from "@domain/services/execute-payout-distribution.domain-service" +import { ImportAssetDomainService } from "@domain/services/import-asset.domain-service" +import { PauseAssetDomainService } from "@domain/services/pause-asset.domain-service" +import { SyncFromOnChainDomainService } from "@domain/services/sync-from-onchain.domain-service" +import { UnpauseAssetDomainService } from "@domain/services/unpause-asset.domain-service" +import { UpdateAssetDomainService } from "@domain/services/update-asset.domain-service" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" +import { ValidateAssetPauseStateDomainService } from "@domain/services/validate-asset-pause-state.domain-service" +import { AssetTokenizationStudioSdkService } from "@infrastructure/adapters/asset-tokenization-studio-sdk.service" +import { BlockchainPollingService } from "@infrastructure/adapters/blockchain/blockchain-polling.service" +import { HederaBlockchainListenerService } from "@infrastructure/adapters/blockchain/listener/hedera-blockchain-listener.service" +import { HederaServiceImpl } from "@infrastructure/adapters/hedera.service" +import { LifeCycleCashFlowSdkService } from "@infrastructure/adapters/life-cycle-cash-flow-sdk.service" +import { OnChainDistributionRepository } from "@infrastructure/adapters/on-chain-distribution.repository" +import { AssetTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-asset.repository" +import { BatchPayoutTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-batch-payout.repository" +import { BlockchainEventListenerConfigTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-blockchain-event-listener-config.repository" +import { DistributionTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-distribution.repository" +import { HolderTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-holder.repository" +import { MassPayoutCronService } from "@infrastructure/cron/mass-payout-cron.service" +import { AssetController } from "@infrastructure/rest/asset/asset.controller" +import { BlockchainController } from "@infrastructure/rest/blockchain/blockchain.controller" +import { DistributionController } from "@infrastructure/rest/distribution/distribution.controller" +import { Provider, Type } from "@nestjs/common" +import { RetryFailedHoldersUseCase } from "@application/use-cases/retry-failed-holders.use-case" +import { RetryFailedHoldersDomainService } from "@domain/services/retry-failed-holders.domain-service" + +const USE_CASES: Provider[] = [ + ImportAssetUseCase, + UpdateAssetUseCase, + ProcessScheduledPayoutsUseCase, + PauseAssetUseCase, + UnpauseAssetUseCase, + GetAssetUseCase, + GetAssetsUseCase, + GetBasicAssetInformationUseCase, + GetDistributionsUseCase, + GetDistributionUseCase, + GetAssetDistributionsUseCase, + GetDistributionHoldersUseCase, + GetDistributionHolderCountUseCase, + ExecutePayoutUseCase, + CancelDistributionUseCase, + ProcessBlockchainEventsUseCase, + GetBlockchainEventListenerConfigUseCase, + UpsertBlockchainEventListenerConfigUseCase, + DisableAssetSyncUseCase, + EnableAssetSyncUseCase, + StartBlockchainPollingUseCase, + StopBlockchainPollingUseCase, + RetryFailedHoldersUseCase, +] + +const REPOSITORIES: Provider[] = [ + { + provide: "AssetRepository", + useClass: AssetTypeOrmRepository, + }, + { + provide: "DistributionRepository", + useClass: DistributionTypeOrmRepository, + }, + { + provide: "HolderRepository", + useClass: HolderTypeOrmRepository, + }, + { + provide: "BatchPayoutRepository", + useClass: BatchPayoutTypeOrmRepository, + }, + { + provide: "OnChainDistributionRepositoryPort", + useClass: OnChainDistributionRepository, + }, + { + provide: "BlockchainEventListenerConfigRepository", + useClass: BlockchainEventListenerConfigTypeOrmRepository, + }, +] + +const SERVICES: Provider[] = [ + ImportAssetDomainService, + UpdateAssetDomainService, + { + provide: "UpdateBatchPayoutStatusDomainService", + useClass: UpdateBatchPayoutStatusDomainService, + }, + SyncFromOnChainDomainService, + MassPayoutCronService, + ExecuteCorporateActionDistributionDomainService, + ExecutePayoutDistributionDomainService, + CreateHoldersDomainService, + PauseAssetDomainService, + UnpauseAssetDomainService, + ValidateAssetPauseStateDomainService, + DisableAssetSyncDomainService, + EnableAssetSyncDomainService, + RetryFailedHoldersDomainService, + { + provide: "UpdateDistributionStatusDomainService", + useClass: UpdateDistributionStatusDomainService, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useClass: LifeCycleCashFlowSdkService, + }, + { + provide: "AssetTokenizationStudioService", + useClass: AssetTokenizationStudioSdkService, + }, + { + provide: "LifeCycleCashFlowPort", + useClass: LifeCycleCashFlowSdkService, + }, + { + provide: "BlockchainPollingPort", + useClass: BlockchainPollingService, + }, + { + provide: "BlockchainEventListenerService", + useClass: HederaBlockchainListenerService, + }, + { + provide: "HederaService", + useClass: HederaServiceImpl, + }, +] + +export const CONTROLLERS: Type[] = [AssetController, DistributionController, BlockchainController] + +export const PROVIDERS: Provider[] = [...USE_CASES, ...SERVICES, ...REPOSITORIES] diff --git a/apps/mass-payout/backend/src/app.module.ts b/apps/mass-payout/backend/src/app.module.ts new file mode 100644 index 000000000..f2328a98c --- /dev/null +++ b/apps/mass-payout/backend/src/app.module.ts @@ -0,0 +1,226 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Module } from "@nestjs/common" +import { ConfigurationModule } from "@config/configuration.module" +import { PostgresModule } from "@config/postgres.module" +import { AssetTokenizationStudioSdkModule } from "@config/asset-tokenization-studio-sdk.module" +import { LifeCycleCashFlowSdkModule } from "@config/life-cycle-cash-flow-sdk.module" +import { MassPayoutSDK } from "@mass-payout/sdk" +import { CONTROLLERS, PROVIDERS } from "./app.module-components" +import { ScheduleModule } from "@nestjs/schedule" + +@Module({ + imports: [ + MassPayoutSDK, + ConfigurationModule.forRoot(), + PostgresModule.forRoot(), + AssetTokenizationStudioSdkModule, + LifeCycleCashFlowSdkModule, + ScheduleModule.forRoot(), + ], + controllers: CONTROLLERS, + providers: PROVIDERS, +}) +export class AppModule {} diff --git a/apps/mass-payout/backend/src/application/use-cases/cancel-distribution.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/cancel-distribution.use-case.ts new file mode 100644 index 000000000..d0ffdce90 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/cancel-distribution.use-case.ts @@ -0,0 +1,232 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { IsNotEmpty } from "class-validator" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { Inject, Injectable } from "@nestjs/common" +import { DistributionNotFoundError } from "@domain/errors/distribution.error" +import { Distribution } from "@domain/model/distribution" + +export class CancelDistributionCommand { + @IsNotEmpty() + distributionId: string +} + +@Injectable() +export class CancelDistributionUseCase { + constructor( + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + ) {} + + async execute(command: CancelDistributionCommand): Promise { + const distribution: Distribution = await this.distributionRepository.getDistribution(command.distributionId) + if (!distribution) { + throw new DistributionNotFoundError(command.distributionId) + } + distribution.cancel() + + await this.distributionRepository.updateDistribution(distribution) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/disable-asset-sync.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/disable-asset-sync.use-case.ts new file mode 100644 index 000000000..b95b0743c --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/disable-asset-sync.use-case.ts @@ -0,0 +1,216 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { DisableAssetSyncDomainService } from "@domain/services/disable-asset-sync.domain-service" +import { Injectable } from "@nestjs/common" + +@Injectable() +export class DisableAssetSyncUseCase { + constructor(private readonly disableAssetSyncDomainService: DisableAssetSyncDomainService) {} + + async execute(assetId: string): Promise { + return this.disableAssetSyncDomainService.execute(assetId) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/enable-asset-sync.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/enable-asset-sync.use-case.ts new file mode 100644 index 000000000..e84319f1c --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/enable-asset-sync.use-case.ts @@ -0,0 +1,216 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { EnableAssetSyncDomainService } from "@domain/services/enable-asset-sync.domain-service" +import { Injectable } from "@nestjs/common" + +@Injectable() +export class EnableAssetSyncUseCase { + constructor(private readonly enableAssetSyncDomainService: EnableAssetSyncDomainService) {} + + async execute(assetId: string): Promise { + return this.enableAssetSyncDomainService.execute(assetId) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/execute-payout.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/execute-payout.use-case.ts new file mode 100644 index 000000000..6534c6bb9 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/execute-payout.use-case.ts @@ -0,0 +1,274 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetNotFoundError } from "@domain/errors/asset.error" +import { InvalidPayoutSubtypeError } from "@domain/errors/payout.error" +import { AmountType, Distribution, PayoutSubtype, Recurrency } from "@domain/model/distribution" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { ExecutePayoutDistributionDomainService } from "@domain/services/execute-payout-distribution.domain-service" +import { Inject, Injectable } from "@nestjs/common" + +export interface ExecutePayoutCommand { + assetId: string + subtype: PayoutSubtype + executeAt?: Date + recurrency?: Recurrency + amount: string + amountType: AmountType + concept?: string +} +@Injectable() +export class ExecutePayoutUseCase { + constructor( + @Inject("AssetRepository") + private readonly assetRepository: AssetRepository, + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + private readonly executePayoutDistributionDomainService: ExecutePayoutDistributionDomainService, + ) {} + + async execute(command: ExecutePayoutCommand): Promise { + const { assetId, subtype, executeAt, amount, amountType, recurrency, concept } = command + const asset = await this.assetRepository.getAsset(assetId) + if (!asset) { + throw new AssetNotFoundError(`Asset with id ${assetId} not found`) + } + let distribution: Distribution + switch (subtype) { + case PayoutSubtype.IMMEDIATE: { + distribution = Distribution.createImmediate(asset, amount, amountType, undefined, undefined, concept) + await this.distributionRepository.saveDistribution(distribution) + await this.executePayoutDistributionDomainService.execute(distribution) + break + } + case PayoutSubtype.ONE_OFF: { + distribution = Distribution.createOneOff(asset, executeAt, amount, amountType, undefined, undefined, concept) + await this.distributionRepository.saveDistribution(distribution) + break + } + case PayoutSubtype.RECURRING: { + distribution = Distribution.createRecurring( + asset, + executeAt, + recurrency, + amount, + amountType, + undefined, + undefined, + concept, + ) + await this.distributionRepository.saveDistribution(distribution) + break + } + case PayoutSubtype.AUTOMATED: { + distribution = Distribution.createAutomated(asset, amount, amountType, concept) + await this.distributionRepository.saveDistribution(distribution) + break + } + default: + throw new InvalidPayoutSubtypeError(`Unsupported payout subtype: ${subtype}`) + } + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-asset-distributions.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-asset-distributions.use-case.ts new file mode 100644 index 000000000..c66cd00aa --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-asset-distributions.use-case.ts @@ -0,0 +1,220 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Distribution } from "@domain/model/distribution" +import { Page, PageOptions } from "@domain/model/page" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class GetAssetDistributionsUseCase { + constructor( + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + ) {} + + async execute(assetId: string, pageOptions: PageOptions = PageOptions.DEFAULT): Promise> { + return this.distributionRepository.getDistributionsByAssetId(assetId, pageOptions) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-asset.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-asset.use-case.ts new file mode 100644 index 000000000..ea4220274 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-asset.use-case.ts @@ -0,0 +1,223 @@ +/* + * 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 representations, 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable, Inject } from "@nestjs/common" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { Asset } from "@domain/model/asset" +import { AssetNotFoundError } from "@domain/errors/asset.error" + +@Injectable() +export class GetAssetUseCase { + constructor(@Inject("AssetRepository") private readonly assetRepository: AssetRepository) {} + + async execute(assetId: string): Promise { + const asset = await this.assetRepository.getAsset(assetId) + + if (!asset) { + throw new AssetNotFoundError(assetId) + } + + return asset + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-assets.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-assets.use-case.ts new file mode 100644 index 000000000..9096ea8e5 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-assets.use-case.ts @@ -0,0 +1,217 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { Page, PageOptions } from "@domain/model/page" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class GetAssetsUseCase { + constructor(@Inject("AssetRepository") private readonly assetRepository: AssetRepository) {} + + async execute(pageOptions: PageOptions = PageOptions.DEFAULT): Promise> { + return this.assetRepository.getAssets(pageOptions) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-basic-asset-information.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-basic-asset-information.use-case.ts new file mode 100644 index 000000000..4b827a753 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-basic-asset-information.use-case.ts @@ -0,0 +1,232 @@ +/* + * 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 representations, 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Inject, Injectable } from "@nestjs/common" +import { AssetType } from "@domain/model/asset-type.enum" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" + +@Injectable() +export class GetBasicAssetInformationUseCase { + constructor( + @Inject("AssetTokenizationStudioService") + private readonly assetTokenizationStudioService: AssetTokenizationStudioService, + ) {} + + async execute(hederaTokenAddress: string): Promise<{ + hederaTokenAddress: string + name: string + symbol: string + assetType: AssetType + maturityDate?: Date + }> { + const assetInfo = await this.assetTokenizationStudioService.getAssetInfo(hederaTokenAddress) + return { + hederaTokenAddress: assetInfo.hederaTokenAddress, + name: assetInfo.name, + symbol: assetInfo.symbol, + assetType: assetInfo.assetType, + maturityDate: assetInfo.maturityDate, + } + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-blockchain-event-listener-config.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-blockchain-event-listener-config.use-case.ts new file mode 100644 index 000000000..30510c854 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-blockchain-event-listener-config.use-case.ts @@ -0,0 +1,241 @@ +/* + * 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 representations, 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigKeys } from "@config/config-keys" +import { BlockchainEventListenerConfig } from "@domain/model/blockchain-listener" +import { BlockchainEventListenerConfigRepository } from "@domain/ports/blockchain-event-config-repository.port" +import { Inject, Injectable, Logger } from "@nestjs/common" +import { ConfigService } from "@nestjs/config" + +@Injectable() +export class GetBlockchainEventListenerConfigUseCase { + private readonly logger = new Logger(GetBlockchainEventListenerConfigUseCase.name) + + constructor( + @Inject("BlockchainEventListenerConfigRepository") + private readonly configRepository: BlockchainEventListenerConfigRepository, + private readonly configService: ConfigService, + ) {} + + async execute(): Promise { + const defaultConfig = this.getDefault() + const config = await this.configRepository.getConfig() + if (!config) return defaultConfig + const mergedConfig = { + ...defaultConfig, + ...config, + } as BlockchainEventListenerConfig + return mergedConfig + } + + getDefault(): BlockchainEventListenerConfig { + const config = new BlockchainEventListenerConfig() + config.mirrorNodeUrl = this.configService.get(ConfigKeys.BLOCKCHAIN_MIRROR_NODE_URL) + config.contractId = this.configService.get(ConfigKeys.BLOCKCHAIN_CONTRACT_ID) + config.tokenDecimals = this.configService.get(ConfigKeys.BLOCKCHAIN_TOKEN_DECIMALS) + const blockchainListenerStartTimestamp = this.configService.get(ConfigKeys.BLOCKCHAIN_LISTENER_START_TIMESTAMP) + config.startTimestamp = (new Date(blockchainListenerStartTimestamp).getTime() / 1000).toFixed(3) + return config + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-distribution-holder-count.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-distribution-holder-count.use-case.ts new file mode 100644 index 000000000..6b7704389 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-distribution-holder-count.use-case.ts @@ -0,0 +1,227 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { Inject, Injectable } from "@nestjs/common" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { DistributionNotFoundError } from "@domain/errors/distribution.error" + +@Injectable() +export class GetDistributionHolderCountUseCase { + constructor( + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + @Inject("HolderRepository") + private readonly holderRepository: HolderRepository, + ) {} + + async execute(distributionId: string): Promise { + const distribution = await this.distributionRepository.getDistribution(distributionId) + if (!distribution) { + throw new DistributionNotFoundError(distributionId) + } + + return await this.holderRepository.countHoldersByDistributionId(distributionId) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-distribution-holders.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-distribution-holders.use-case.ts new file mode 100644 index 000000000..b3c712bdc --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-distribution-holders.use-case.ts @@ -0,0 +1,223 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Holder } from "@domain/model/holder" +import { Page, PageOptions } from "@domain/model/page" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { Inject, Injectable } from "@nestjs/common" +import { GetDistributionUseCase } from "./get-distribution.use-case" + +@Injectable() +export class GetDistributionHoldersUseCase { + constructor( + private readonly getDistributionUseCase: GetDistributionUseCase, + @Inject("HolderRepository") + private readonly holderRepository: HolderRepository, + ) {} + + async execute(distributionId: string, pageOptions: PageOptions): Promise> { + await this.getDistributionUseCase.execute(distributionId) + return this.holderRepository.getHoldersByDistributionId(distributionId, pageOptions) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-distribution.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-distribution.use-case.ts new file mode 100644 index 000000000..e7406b885 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-distribution.use-case.ts @@ -0,0 +1,223 @@ +/* + * 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 representations, 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable, Inject } from "@nestjs/common" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { Distribution } from "@domain/model/distribution" +import { DistributionNotFoundError } from "@domain/errors/distribution.error" + +@Injectable() +export class GetDistributionUseCase { + constructor(@Inject("DistributionRepository") private readonly distributionRepository: DistributionRepository) {} + + async execute(distributionId: string): Promise { + const distribution = await this.distributionRepository.getDistribution(distributionId) + + if (!distribution) { + throw new DistributionNotFoundError(distributionId) + } + + return distribution + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/get-distributions.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/get-distributions.use-case.ts new file mode 100644 index 000000000..738665d67 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/get-distributions.use-case.ts @@ -0,0 +1,219 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { PageOptions } from "@domain/model/page" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class GetDistributionsUseCase { + constructor( + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + ) {} + + async execute(pageOptions: PageOptions) { + return this.distributionRepository.getDistributions(pageOptions) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/import-asset.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/import-asset.use-case.ts new file mode 100644 index 000000000..c12799079 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/import-asset.use-case.ts @@ -0,0 +1,216 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { ImportAssetDomainService } from "@domain/services/import-asset.domain-service" +import { Injectable } from "@nestjs/common" + +@Injectable() +export class ImportAssetUseCase { + constructor(private readonly importAssetDomainService: ImportAssetDomainService) {} + + async execute(hederaTokenAddress: string): Promise { + return this.importAssetDomainService.importAsset(hederaTokenAddress) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/pause-asset.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/pause-asset.use-case.ts new file mode 100644 index 000000000..352322e24 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/pause-asset.use-case.ts @@ -0,0 +1,216 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable } from "@nestjs/common" +import { PauseAssetDomainService } from "@domain/services/pause-asset.domain-service" +import { Asset } from "@domain/model/asset" + +@Injectable() +export class PauseAssetUseCase { + constructor(private readonly pauseAssetDomainService: PauseAssetDomainService) {} + + async execute(assetId: string): Promise { + return this.pauseAssetDomainService.pause(assetId) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/process-blockchain-events.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/process-blockchain-events.use-case.ts new file mode 100644 index 000000000..35808260f --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/process-blockchain-events.use-case.ts @@ -0,0 +1,276 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BlockchainEvent, TransferEvent } from "@domain/model/blockchain-listener" +import { Distribution } from "@domain/model/distribution" +import { BlockchainEventListenerService } from "@domain/ports/blockchain-event-listener.service" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { ExecutePayoutDistributionDomainService } from "@domain/services/execute-payout-distribution.domain-service" +import { Inject, Injectable, Logger } from "@nestjs/common" +import chalk from "chalk" + +@Injectable() +export class ProcessBlockchainEventsUseCase { + private readonly logger = new Logger(ProcessBlockchainEventsUseCase.name) + + constructor( + @Inject("BlockchainEventListenerService") + private readonly blockchainEventListener: BlockchainEventListenerService, + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + private readonly executePayoutDistributionDomainService: ExecutePayoutDistributionDomainService, + ) {} + + async execute(): Promise { + const events: BlockchainEvent[] = await this.blockchainEventListener.fetchNewEvents() + let lastTimestampEvent: string = "0" + for (const event of events) { + if (Number(lastTimestampEvent) < Number(event.timestamp)) { + lastTimestampEvent = event.timestamp + } + if (!this.isTransferEvent(event)) { + this.logger.verbose(`Skipping non-transfer event: ${chalk.yellow(JSON.stringify(event.to))}`) + continue + } + const distributions = await this.getDistributions((event as TransferEvent).to) + if (!distributions.length) { + this.logger.verbose(`Skipping event with no distributions: ${chalk.yellow(JSON.stringify(event.to))}`) + continue + } + this.logger.verbose(`${chalk.yellow(JSON.stringify(event, null, 2))}`) + this.logger.verbose( + `Found ${distributions.length} distributions for event to: ${chalk.green(JSON.stringify(event.to))}`, + ) + for (const distribution of distributions) { + this.logger.debug( + `Processing distribution with id: ${chalk.green(JSON.stringify(distribution.id))} to: ${chalk.green( + JSON.stringify(event.to), + )} from: ${chalk.green(JSON.stringify(event.from))}`, + ) + await this.executeDistribution(distribution) + } + } + await this.blockchainEventListener.updateStartTimestamp(lastTimestampEvent) + this.logger.verbose(`Processed ${events.length} blockchain events`) + } + + private async getDistributions(address: string): Promise { + return await this.distributionRepository.getScheduledAutomatedDistributionsByEvmAddress(address) + } + + private async executeDistribution(distribution: Distribution): Promise { + try { + await this.executePayoutDistributionDomainService.execute(distribution) + } catch (error) { + this.logger.error( + `Error calling automatic payout for distribution: "${distribution.id}" with error: ${error.message}`, + error.stack, + ) + } + } + + private isTransferEvent(event: BlockchainEvent): boolean { + return event.name === "Transfer" && (event as TransferEvent).value > 0 + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/process-scheduled-payouts.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/process-scheduled-payouts.use-case.ts new file mode 100644 index 000000000..03b2d57d1 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/process-scheduled-payouts.use-case.ts @@ -0,0 +1,257 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Inject, Injectable } from "@nestjs/common" +import { Distribution, DistributionStatus, DistributionType } from "@domain/model/distribution" +import { ExecuteCorporateActionDistributionDomainService } from "@domain/services/execute-corporate-action-distribution.domain-service" +import { SyncFromOnChainDomainService } from "@domain/services/sync-from-onchain.domain-service" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { ExecutePayoutDistributionDomainService } from "@domain/services/execute-payout-distribution.domain-service" + +@Injectable() +export class ProcessScheduledPayoutsUseCase { + constructor( + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + private readonly syncFromOnChainDomainService: SyncFromOnChainDomainService, + private readonly executeCorporateActionDistributionDomainService: ExecuteCorporateActionDistributionDomainService, + private readonly executePayoutDistributionDomainService: ExecutePayoutDistributionDomainService, + ) {} + + async execute(): Promise { + await this.syncFromOnChainDomainService.execute() + + const { startOfDay, endOfDay } = this.getTodayDateRange() + const distributionsDueToday = await this.distributionRepository.findByExecutionDateRange( + startOfDay, + endOfDay, + DistributionStatus.SCHEDULED, + ) + + await this.processDistributions(distributionsDueToday) + } + + private getTodayDateRange(): { startOfDay: Date; endOfDay: Date } { + const startOfDay = new Date() + startOfDay.setHours(0, 0, 0, 0) + + const endOfDay = new Date(startOfDay) + endOfDay.setHours(23, 59, 59, 999) + + return { startOfDay, endOfDay } + } + + private async processDistributions(distributions: Distribution[]): Promise { + for (const distribution of distributions) { + switch (distribution.details.type) { + case DistributionType.PAYOUT: + await this.executePayoutDistributionDomainService.execute(distribution) + break + case DistributionType.CORPORATE_ACTION: + await this.executeCorporateActionDistributionDomainService.execute(distribution) + break + } + } + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/retry-failed-holders.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/retry-failed-holders.use-case.ts new file mode 100644 index 000000000..7152ab7c7 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/retry-failed-holders.use-case.ts @@ -0,0 +1,221 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { IsNotEmpty } from "class-validator" +import { Injectable } from "@nestjs/common" +import { RetryFailedHoldersDomainService } from "@domain/services/retry-failed-holders.domain-service" + +export class RetryFailedHoldersCommand { + @IsNotEmpty() + distributionId: string +} + +@Injectable() +export class RetryFailedHoldersUseCase { + constructor(private readonly retryFailedHolderDomainService: RetryFailedHoldersDomainService) {} + + async execute(command: RetryFailedHoldersCommand): Promise { + await this.retryFailedHolderDomainService.execute(command.distributionId) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/start-blockchain-polling.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/start-blockchain-polling.use-case.ts new file mode 100644 index 000000000..d4e7dd62d --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/start-blockchain-polling.use-case.ts @@ -0,0 +1,218 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BlockchainPollingPort } from "@domain/ports/blockchain-polling.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class StartBlockchainPollingUseCase { + constructor( + @Inject("BlockchainPollingPort") + private readonly blockchainPollingService: BlockchainPollingPort, + ) {} + + async execute(): Promise { + this.blockchainPollingService.start() + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/stop-blockchain-polling.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/stop-blockchain-polling.use-case.ts new file mode 100644 index 000000000..d64660fd3 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/stop-blockchain-polling.use-case.ts @@ -0,0 +1,218 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BlockchainPollingPort } from "@domain/ports/blockchain-polling.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class StopBlockchainPollingUseCase { + constructor( + @Inject("BlockchainPollingPort") + private readonly blockchainPollingService: BlockchainPollingPort, + ) {} + + async execute(): Promise { + this.blockchainPollingService.stop() + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/unpause-asset.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/unpause-asset.use-case.ts new file mode 100644 index 000000000..2bfaf2d63 --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/unpause-asset.use-case.ts @@ -0,0 +1,216 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable } from "@nestjs/common" +import { UnpauseAssetDomainService } from "@domain/services/unpause-asset.domain-service" +import { Asset } from "@domain/model/asset" + +@Injectable() +export class UnpauseAssetUseCase { + constructor(private readonly unpauseAssetDomainService: UnpauseAssetDomainService) {} + + async execute(assetId: string): Promise { + return this.unpauseAssetDomainService.unpause(assetId) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/update-asset.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/update-asset.use-case.ts new file mode 100644 index 000000000..62dbd4d1b --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/update-asset.use-case.ts @@ -0,0 +1,216 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable } from "@nestjs/common" +import { UpdateAssetDomainService } from "@domain/services/update-asset.domain-service" +import { Asset } from "@domain/model/asset" + +@Injectable() +export class UpdateAssetUseCase { + constructor(private readonly updateAssetDomainService: UpdateAssetDomainService) {} + + async execute(id: string, name: string): Promise { + return this.updateAssetDomainService.updateAsset(id, name) + } +} diff --git a/apps/mass-payout/backend/src/application/use-cases/upsert-blockchain-event-listener-config.use-case.ts b/apps/mass-payout/backend/src/application/use-cases/upsert-blockchain-event-listener-config.use-case.ts new file mode 100644 index 000000000..d4f69351c --- /dev/null +++ b/apps/mass-payout/backend/src/application/use-cases/upsert-blockchain-event-listener-config.use-case.ts @@ -0,0 +1,221 @@ +/* + * 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 representations, 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BlockchainEventListenerConfig } from "@domain/model/blockchain-listener" +import { BlockchainEventListenerConfigRepository } from "@domain/ports/blockchain-event-config-repository.port" +import { Inject, Injectable } from "@nestjs/common" +import { GetBlockchainEventListenerConfigUseCase } from "./get-blockchain-event-listener-config.use-case" + +@Injectable() +export class UpsertBlockchainEventListenerConfigUseCase { + constructor( + @Inject("BlockchainEventListenerConfigRepository") + private readonly configRepository: BlockchainEventListenerConfigRepository, + private readonly getConfigUseCase: GetBlockchainEventListenerConfigUseCase, + ) {} + + async execute(updatedConfig: BlockchainEventListenerConfig): Promise { + return await this.configRepository.save(updatedConfig) + } +} diff --git a/apps/mass-payout/backend/src/config/asset-tokenization-studio-sdk.module.ts b/apps/mass-payout/backend/src/config/asset-tokenization-studio-sdk.module.ts new file mode 100644 index 000000000..3b0e76005 --- /dev/null +++ b/apps/mass-payout/backend/src/config/asset-tokenization-studio-sdk.module.ts @@ -0,0 +1,290 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Logger, Module, OnModuleInit, Provider } from "@nestjs/common" +import { ConnectRequest, InitializationRequest, Network, SupportedWallets } from "@hashgraph/asset-tokenization-sdk" +import { AssetTokenizationStudioSdkService } from "@infrastructure/adapters/asset-tokenization-studio-sdk.service" +import { ConfigModule, ConfigService } from "@nestjs/config" +import { ConfigKeys } from "./config-keys" + +export const ATS_NETWORK_INIT = Symbol("ATS_NETWORK_INIT") + +@Module({ + imports: [ConfigModule], + providers: [ + AssetTokenizationStudioSdkService, + { + provide: "AssetTokenizationStudioService", + useExisting: AssetTokenizationStudioSdkService, + }, + networkInitProvider(), + ], + exports: ["AssetTokenizationStudioService"], +}) +export class AssetTokenizationStudioSdkModule implements OnModuleInit { + private readonly logger = new Logger(AssetTokenizationStudioSdkModule.name) + + async onModuleInit() { + this.logger.log("ATS SDK Module initialized successfully") + } +} + +function networkInitProvider(): Provider { + return { + provide: ATS_NETWORK_INIT, + inject: [ConfigService], + useFactory: async (config: ConfigService) => { + const logger = new Logger(ATS_NETWORK_INIT.toString()) + + try { + const network = config.get(ConfigKeys.ATS_NETWORK, "testnet") + const mirrorNodeUrl = config.get( + ConfigKeys.ATS_MIRROR_URL, + "https://testnet.mirrornode.hedera.com/api/v1/", + ) + const rpcNodeUrl = config.get(ConfigKeys.ATS_RPC_URL, "https://testnet.hashio.io/api") + const factoryAddress = config.get(ConfigKeys.ATS_FACTORY_ADDRESS, "0.0.6224505") + const resolverAddress = config.get(ConfigKeys.ATS_RESOLVER_ADDRESS, "0.0.6224426") + + const mirrorNode = { name: "testMirrorNode", baseUrl: mirrorNodeUrl } + const rpcNode = { name: "testRpcNode", baseUrl: rpcNodeUrl } + + await Network.init( + new InitializationRequest({ + network, + configuration: { factoryAddress, resolverAddress }, + mirrorNode, + rpcNode, + }), + ) + + await Network.connect( + new ConnectRequest({ + network, + wallet: SupportedWallets.DFNS, + mirrorNode, + rpcNode, + custodialWalletSettings: { + authorizationToken: config.get(ConfigKeys.DFNS_SERVICE_ACCOUNT_AUTHORIZATION_TOKEN)!, + credentialId: config.get(ConfigKeys.DFNS_SERVICE_ACCOUNT_CREDENTIAL_ID)!, + serviceAccountPrivateKey: config.get(ConfigKeys.DFNS_SERVICE_ACCOUNT_PRIVATE_KEY_PATH)!, + urlApplicationOrigin: config.get(ConfigKeys.DFNS_APP_ORIGIN)!, + applicationId: config.get(ConfigKeys.DFNS_APP_ID)!, + baseUrl: config.get(ConfigKeys.DFNS_BASE_URL)!, + walletId: config.get(ConfigKeys.DFNS_WALLET_ID)!, + hederaAccountId: config.get(ConfigKeys.DFNS_HEDERA_ACCOUNT_ID)!, + publicKey: config.get(ConfigKeys.DFNS_WALLET_PUBLIC_KEY)!, + }, + }), + ) + + return true + } catch (error) { + logger.error("Failed to initialize ATS SDK Network") + logger.error(error.message) + throw new Error(`ATS SDK initialization failed: ${error.message}`) + } + }, + } +} diff --git a/apps/mass-payout/backend/src/config/config-keys.ts b/apps/mass-payout/backend/src/config/config-keys.ts new file mode 100644 index 000000000..63c79703e --- /dev/null +++ b/apps/mass-payout/backend/src/config/config-keys.ts @@ -0,0 +1,240 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export enum ConfigKeys { + APP_ENV = "APP_ENV", + PORT = "PORT", + POSTGRESQL_HOST = "POSTGRESQL_HOST", + POSTGRESQL_PORT = "POSTGRESQL_PORT", + POSTGRESQL_USER = "POSTGRESQL_USER", + POSTGRESQL_PASSWORD = "POSTGRESQL_PASSWORD", + POSTGRESQL_DB = "POSTGRESQL_DB", + HEDERA_USDC_ADDRESS = "HEDERA_USDC_ADDRESS", + BATCH_SIZE = "BATCH_SIZE", + NETWORK = "NETWORK", + MIRROR_URL = "MIRROR_URL", + RPC_URL = "RPC_URL", + ENABLE_EVENTS = "ENABLE_EVENTS", + ATS_NETWORK = "ATS_NETWORK", + ATS_MIRROR_URL = "ATS_MIRROR_URL", + ATS_RPC_URL = "ATS_RPC_URL", + ATS_FACTORY_ADDRESS = "ATS_FACTORY_ADDRESS", + ATS_RESOLVER_ADDRESS = "ATS_RESOLVER_ADDRESS", + ATS_ENABLE_EVENTS = "ATS_ENABLE_EVENTS", + DFNS_SERVICE_ACCOUNT_AUTHORIZATION_TOKEN = "DFNS_SERVICE_ACCOUNT_AUTHORIZATION_TOKEN", + DFNS_SERVICE_ACCOUNT_CREDENTIAL_ID = "DFNS_SERVICE_ACCOUNT_CREDENTIAL_ID", + DFNS_SERVICE_ACCOUNT_PRIVATE_KEY_PATH = "DFNS_SERVICE_ACCOUNT_PRIVATE_KEY_PATH", + DFNS_APP_ORIGIN = "DFNS_APP_ORIGIN", + DFNS_APP_ID = "DFNS_APP_ID", + DFNS_BASE_URL = "DFNS_BASE_URL", + DFNS_WALLET_ID = "DFNS_WALLET_ID", + DFNS_HEDERA_ACCOUNT_ID = "DFNS_HEDERA_ACCOUNT_ID", + DFNS_WALLET_PUBLIC_KEY = "DFNS_WALLET_PUBLIC_KEY", + + BLOCKCHAIN_MIRROR_NODE_URL = "BLOCKCHAIN_MIRROR_NODE_URL", + BLOCKCHAIN_CONTRACT_ID = "BLOCKCHAIN_CONTRACT_ID", + BLOCKCHAIN_TOKEN_DECIMALS = "BLOCKCHAIN_TOKEN_DECIMALS", + BLOCKCHAIN_LISTENER_POLL_TIMEOUT = "BLOCKCHAIN_LISTENER_POLL_TIMEOUT", + BLOCKCHAIN_LISTENER_START_TIMESTAMP = "BLOCKCHAIN_LISTENER_START_TIMESTAMP", +} diff --git a/apps/mass-payout/backend/src/config/configuration.module.ts b/apps/mass-payout/backend/src/config/configuration.module.ts new file mode 100644 index 000000000..c17e8fb3b --- /dev/null +++ b/apps/mass-payout/backend/src/config/configuration.module.ts @@ -0,0 +1,230 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigModule } from "@nestjs/config" +import { DynamicModule, Module } from "@nestjs/common" +import { ConfigKeys } from "@config/config-keys" +import Joi from "joi" + +@Module({}) +export class ConfigurationModule { + private static DEFAULT_ENV_FILE = "/.env" + + static forRoot(envFile?: string): DynamicModule { + return { + module: ConfigurationModule, + imports: [ + ConfigModule.forRoot({ + envFilePath: process.cwd() + (envFile ?? ConfigurationModule.DEFAULT_ENV_FILE), + validationSchema: Joi.object({ + [ConfigKeys.APP_ENV]: Joi.string().required(), + [ConfigKeys.PORT]: Joi.number().required(), + }), + isGlobal: true, + }), + ], + exports: [ConfigModule], + } + } +} diff --git a/apps/mass-payout/backend/src/config/life-cycle-cash-flow-sdk.module.ts b/apps/mass-payout/backend/src/config/life-cycle-cash-flow-sdk.module.ts new file mode 100644 index 000000000..bc67f4407 --- /dev/null +++ b/apps/mass-payout/backend/src/config/life-cycle-cash-flow-sdk.module.ts @@ -0,0 +1,285 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Logger, Module, OnModuleInit, Provider } from "@nestjs/common" +import { ConnectRequest, InitializationRequest, MassPayoutSDK, Network, SupportedWallets } from "@mass-payout/sdk" +import { LifeCycleCashFlowSdkService } from "@infrastructure/adapters/life-cycle-cash-flow-sdk.service" +import { ConfigModule, ConfigService } from "@nestjs/config" +import { ConfigKeys } from "./config-keys" +import { AssetTokenizationStudioSdkModule } from "@config/asset-tokenization-studio-sdk.module" +import { HederaServiceImpl } from "@infrastructure/adapters/hedera.service" + +export const NETWORK_INIT = Symbol("NETWORK_INIT") + +@Module({ + imports: [ConfigModule, MassPayoutSDK, AssetTokenizationStudioSdkModule], + providers: [ + { + provide: "HederaService", + useClass: HederaServiceImpl, + }, + LifeCycleCashFlowSdkService, + networkInitProvider(), + ], + exports: [LifeCycleCashFlowSdkService], +}) +export class LifeCycleCashFlowSdkModule implements OnModuleInit { + private readonly logger = new Logger(LifeCycleCashFlowSdkModule.name) + + async onModuleInit() { + this.logger.log("SDK Module initialized successfully") + } +} + +function networkInitProvider(): Provider { + return { + provide: NETWORK_INIT, + inject: [ConfigService, Network, LifeCycleCashFlowSdkService], + useFactory: async (config: ConfigService, network: Network) => { + const logger = new Logger(NETWORK_INIT.toString()) + + try { + const environment = config.get(ConfigKeys.NETWORK, "testnet") + const mirrorNodeUrl = config.get(ConfigKeys.MIRROR_URL, "https://testnet.mirrornode.hedera.com/api/v1/") + const rpcNodeUrl = config.get(ConfigKeys.RPC_URL, "https://testnet.hashio.io/api") + + const mirrorNode = { name: "testMirrorNode", baseUrl: mirrorNodeUrl } + const rpcNode = { name: "testRpcNode", baseUrl: rpcNodeUrl } + await network.init( + new InitializationRequest({ + network: environment, + mirrorNode, + rpcNode, + }), + ) + + await network.connect( + new ConnectRequest({ + network: environment, + wallet: SupportedWallets.DFNS, + mirrorNode, + rpcNode, + custodialWalletSettings: { + authorizationToken: config.get(ConfigKeys.DFNS_SERVICE_ACCOUNT_AUTHORIZATION_TOKEN)!, + credentialId: config.get(ConfigKeys.DFNS_SERVICE_ACCOUNT_CREDENTIAL_ID)!, + serviceAccountPrivateKey: config.get(ConfigKeys.DFNS_SERVICE_ACCOUNT_PRIVATE_KEY_PATH)!, + urlApplicationOrigin: config.get(ConfigKeys.DFNS_APP_ORIGIN)!, + applicationId: config.get(ConfigKeys.DFNS_APP_ID)!, + baseUrl: config.get(ConfigKeys.DFNS_BASE_URL)!, + walletId: config.get(ConfigKeys.DFNS_WALLET_ID)!, + hederaAccountId: config.get(ConfigKeys.DFNS_HEDERA_ACCOUNT_ID)!, + publicKey: config.get(ConfigKeys.DFNS_WALLET_PUBLIC_KEY)!, + }, + }), + ) + + return true + } catch (error) { + logger.error("Failed to initialize SDK Network") + logger.error(error.message) + throw new Error(`SDK initialization failed: ${error.message}`) + } + }, + } +} diff --git a/apps/mass-payout/backend/src/config/postgres.module.ts b/apps/mass-payout/backend/src/config/postgres.module.ts new file mode 100644 index 000000000..f4eefcf98 --- /dev/null +++ b/apps/mass-payout/backend/src/config/postgres.module.ts @@ -0,0 +1,264 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigKeys } from "@config/config-keys" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { BatchPayoutPersistence } from "@infrastructure/adapters/repositories/model/batch-payout.persistence" +import { BlockchainEventListenerConfigPersistence } from "@infrastructure/adapters/repositories/model/blockchain-event-listener-config.persistence" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { HolderPersistence } from "@infrastructure/adapters/repositories/model/holder.persistence" +import { DynamicModule, Module } from "@nestjs/common" +import { ConfigService } from "@nestjs/config" +import { TypeOrmModule, TypeOrmModuleOptions } from "@nestjs/typeorm" +import { EntityClassOrSchema } from "@nestjs/typeorm/dist/interfaces/entity-class-or-schema.type" + +export const ENTITIES: EntityClassOrSchema[] = [ + AssetPersistence, + DistributionPersistence, + HolderPersistence, + BatchPayoutPersistence, + BlockchainEventListenerConfigPersistence, +] +const ORM_TYPE: string = "postgres" + +@Module({}) +export class PostgresModule { + static forRoot(typeOrmOptions?: TypeOrmModuleOptions, entities: EntityClassOrSchema[] = ENTITIES): DynamicModule { + return { + module: PostgresModule, + imports: [ + TypeOrmModule.forRootAsync({ + inject: [ConfigService], + useFactory: (configService: ConfigService): TypeOrmModuleOptions => { + return { + ...this.getDefaultPostgreSqlConfig(configService), + ...typeOrmOptions, + } as TypeOrmModuleOptions + }, + }), + TypeOrmModule.forFeature(entities), + ], + exports: [TypeOrmModule], + } + } + + static getDefaultPostgreSqlConfig(configService: ConfigService): TypeOrmModuleOptions { + return { + type: ORM_TYPE, + host: configService.get(ConfigKeys.POSTGRESQL_HOST), + port: configService.get(ConfigKeys.POSTGRESQL_PORT), + username: configService.get(ConfigKeys.POSTGRESQL_USER), + password: configService.get(ConfigKeys.POSTGRESQL_PASSWORD), + database: configService.get(ConfigKeys.POSTGRESQL_DB), + // FIXME: As long as we do NOT use formal migrations, we use this + // config for TypeORM to create the tables automatically + // - Dev : synchronize = true , migrationsRun = false + // - Prod : synchronize = false , migrationsRun = true + synchronize: true, + migrationsRun: false, + //migrations: ["dist/src/migrations/*{.ts,.js}"], + autoLoadEntities: true, + } as TypeOrmModuleOptions + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/asset.error.ts b/apps/mass-payout/backend/src/domain/errors/asset.error.ts new file mode 100644 index 000000000..334932efb --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/asset.error.ts @@ -0,0 +1,261 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { InvalidDataError } from "@domain/errors/shared/invalid-data.error" +import { ConflictError } from "@domain/errors/shared/conflict-error" +import { DomainError } from "@domain/errors/shared/domain.error" + +export class AssetNameMissingError extends InvalidDataError { + constructor() { + super("Asset name is required") + } +} + +export class AssetHederaTokenAddressInvalidError extends InvalidDataError { + constructor() { + super("hederaTokenAddress must be in the format 0.0.X") + } +} + +export class AssetEvmTokenAddressInvalidError extends InvalidDataError { + constructor() { + super("evmTokenAddress must be a valid Ethereum address") + } +} + +export class AssetLifeCycleCashFlowHederaAddressInvalidError extends InvalidDataError { + constructor() { + super("hederaLifeCycleCashFlowAddress must be in the format 0.0.X") + } +} + +export class AssetLifeCycleCashFlowEvmAddressInvalidError extends InvalidDataError { + constructor() { + super("evmLifeCycleCashFlowAddress must be a valid Ethereum address") + } +} + +export class AssetNameAlreadyExistsError extends ConflictError { + constructor(name: string) { + super(`Asset with name ${name} already exists`) + } +} + +export class AssetHederaTokenAddressAlreadyExistsError extends ConflictError { + constructor(hederaTokenAddress: string) { + super(`Asset with hederaTokenAddress ${hederaTokenAddress} already exists`) + } +} + +export class AssetNotFoundError extends DomainError { + constructor(id: string) { + super(`Asset with ID ${id} not found`) + } +} + +export class AssetPausedError extends ConflictError { + constructor(assetName: string, hederaTokenAddress: string) { + super(`Asset '${assetName}' (${hederaTokenAddress}) is currently paused and cannot be used for distributions`) + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/batch-payout.error.ts b/apps/mass-payout/backend/src/domain/errors/batch-payout.error.ts new file mode 100644 index 000000000..7e4ea56f2 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/batch-payout.error.ts @@ -0,0 +1,229 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { InvalidDataError } from "@domain/errors/shared/invalid-data.error" + +export class BatchPayoutDistributionIdMissingError extends InvalidDataError { + constructor() { + super("distributionId is required") + } +} + +export class BatchPayoutHederaTransactionIdInvalidError extends InvalidDataError { + constructor() { + super("hederaTransactionId must have the format ..@.") + } +} + +export class BatchPayoutHederaTransactionHashInvalidError extends InvalidDataError { + constructor() { + super("hederaTransactionHash must be a valid Hedera transaction hash (0x followed by 96 hex characters)") + } +} + +export class BatchPayoutHoldersNumberInvalidError extends InvalidDataError { + constructor() { + super("holdersNumber must be a positive integer") + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/blockchain-event-error.ts b/apps/mass-payout/backend/src/domain/errors/blockchain-event-error.ts new file mode 100644 index 000000000..2b3c24076 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/blockchain-event-error.ts @@ -0,0 +1,219 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { DomainError } from "@domain/errors/shared/domain.error" +import { BlockchainEventListenerConfig } from "@domain/model/blockchain-listener" +import { InvalidDataError } from "./shared/invalid-data.error" + +export class BlockchainEventListenerConfigNotFoundError extends DomainError { + constructor() { + super("Config not found") + } +} + +export class BlockchainEventListenerConfigNotValidError extends InvalidDataError { + constructor(config: BlockchainEventListenerConfig) { + super(`Invalid Config: ${JSON.stringify(config)}`) + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/distribution.error.ts b/apps/mass-payout/backend/src/domain/errors/distribution.error.ts new file mode 100644 index 000000000..ddf119b23 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/distribution.error.ts @@ -0,0 +1,268 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { InvalidDataError } from "@domain/errors/shared/invalid-data.error" +import { DomainError } from "@domain/errors/shared/domain.error" +import { DistributionStatus } from "@domain/model/distribution" +import { ConflictError } from "@domain/errors/shared/conflict-error" + +export class DistributionAssetIdMissingError extends InvalidDataError { + constructor() { + super("assetId is required") + } +} + +export class DistributionCorporateActionIDMissingError extends InvalidDataError { + constructor() { + super("corporateActionID is required") + } +} + +export class DistributionExecutionDateMissingError extends InvalidDataError { + constructor() { + super("executionDate is required") + } +} + +export class DistributionExecutionDateInPastError extends InvalidDataError { + constructor() { + super("executionDate must be in the future") + } +} + +export class DistributionRecurrencyMissingError extends InvalidDataError { + constructor() { + super("recurrency is required") + } +} + +export class DistributionSnapshotIDMissingError extends InvalidDataError { + constructor() { + super("Distribution snapshot ID is missing") + } +} + +export class DistributionNotFoundError extends DomainError { + constructor(distributionId: string) { + super(`Distribution with id ${distributionId} not found`) + } +} + +export class DistributionNotPayoutError extends ConflictError { + constructor(distributionId: string) { + super(`Distribution ${distributionId} is not a payout distribution`) + } +} + +export class DistributionNotCorporateActionError extends ConflictError { + constructor(distributionId: string) { + super(`Distribution ${distributionId} is not a corporate action distribution`) + } +} + +export class DistributionNotInStatusError extends ConflictError { + constructor(distributionId: string, status: DistributionStatus) { + super(`Distribution ${distributionId} should be in status ${status}`) + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/holder.error.ts b/apps/mass-payout/backend/src/domain/errors/holder.error.ts new file mode 100644 index 000000000..5d74f61f5 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/holder.error.ts @@ -0,0 +1,229 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { InvalidDataError } from "@domain/errors/shared/invalid-data.error" + +export class HolderBatchPayoutIdMissingError extends InvalidDataError { + constructor() { + super("batchPayoutId is required") + } +} + +export class HolderHederaAddressInvalidError extends InvalidDataError { + constructor() { + super("holderHederaAddress must be in the format 0.0.X") + } +} + +export class HolderEvmAddressInvalidError extends InvalidDataError { + constructor() { + super("holderEvmAddress must be a valid Ethereum address") + } +} + +export class HolderRetryCounterNegativeError extends InvalidDataError { + constructor() { + super("retryCounter cannot be negative and is required") + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/payout.error.ts b/apps/mass-payout/backend/src/domain/errors/payout.error.ts new file mode 100644 index 000000000..6f93469f5 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/payout.error.ts @@ -0,0 +1,8 @@ +import { InvalidDataError } from "./shared/invalid-data.error" + +export class InvalidPayoutSubtypeError extends InvalidDataError { + constructor(message: string) { + super(message) + this.name = InvalidPayoutSubtypeError.name + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/shared/base-entity-invalid-dates.error.ts b/apps/mass-payout/backend/src/domain/errors/shared/base-entity-invalid-dates.error.ts new file mode 100644 index 000000000..e6255d671 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/shared/base-entity-invalid-dates.error.ts @@ -0,0 +1,211 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { InvalidDataError } from "@domain/errors/shared/invalid-data.error" + +export class BaseEntityInvalidDatesError extends InvalidDataError { + constructor() { + super("createdAt and updatedAt are required; createdAt cannot be later than updatedAt") + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/shared/conflict-error.ts b/apps/mass-payout/backend/src/domain/errors/shared/conflict-error.ts new file mode 100644 index 000000000..16db9fe9c --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/shared/conflict-error.ts @@ -0,0 +1,211 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { DomainError } from "@domain/errors/shared/domain.error" + +export abstract class ConflictError extends DomainError { + protected constructor(message: string) { + super(message) + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/shared/custom.error.ts b/apps/mass-payout/backend/src/domain/errors/shared/custom.error.ts new file mode 100644 index 000000000..2da3d59f5 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/shared/custom.error.ts @@ -0,0 +1,245 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export class CustomError extends Error { + static readonly MAX_MESSAGE_LENGTH = 500 + protected static JSON_MESSAGE = "message" + protected static JSON_CAUSE = "cause" + private static readonly DEFAULT_MESSAGE = "Internal error" + public originalError?: Error + public cause: string + + public constructor(message: string = CustomError.DEFAULT_MESSAGE, originalError?: Error, cause?: string) { + if (message.length > CustomError.MAX_MESSAGE_LENGTH) { + message = `${message.substring(0, CustomError.MAX_MESSAGE_LENGTH)}... (omitted)` + } + super(message) + this.stack = originalError ? `${this.stack}\n${originalError.stack}` : this.stack + this.name = this.constructor.name + this.originalError = originalError + this.cause = cause + } + + public static getRootError(error: Error): Error { + if (!(error instanceof CustomError)) { + return error + } + + if (error.originalError) { + return this.getRootError(error.originalError) + } + + return error + } + + public toJson(): any { + const rootError = CustomError.getRootError(this) + const cause = rootError instanceof CustomError ? rootError.cause : undefined + + return { + [CustomError.JSON_MESSAGE]: this.message, + [CustomError.JSON_CAUSE]: cause, + } + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/shared/domain.error.ts b/apps/mass-payout/backend/src/domain/errors/shared/domain.error.ts new file mode 100644 index 000000000..b4b9ecbeb --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/shared/domain.error.ts @@ -0,0 +1,211 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { CustomError } from "@domain/errors/shared/custom.error" + +export abstract class DomainError extends CustomError { + protected constructor(message: string) { + super(message, undefined, message) + } +} diff --git a/apps/mass-payout/backend/src/domain/errors/shared/invalid-data.error.ts b/apps/mass-payout/backend/src/domain/errors/shared/invalid-data.error.ts new file mode 100644 index 000000000..87798f0ae --- /dev/null +++ b/apps/mass-payout/backend/src/domain/errors/shared/invalid-data.error.ts @@ -0,0 +1,211 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { DomainError } from "@domain/errors/shared/domain.error" + +export abstract class InvalidDataError extends DomainError { + protected constructor(message: string) { + super(message) + } +} diff --git a/apps/mass-payout/backend/src/domain/model/asset-type.enum.ts b/apps/mass-payout/backend/src/domain/model/asset-type.enum.ts new file mode 100644 index 000000000..38d670e50 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/asset-type.enum.ts @@ -0,0 +1,208 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export enum AssetType { + EQUITY = "EQUITY", + BOND = "BOND", +} diff --git a/apps/mass-payout/backend/src/domain/model/asset.ts b/apps/mass-payout/backend/src/domain/model/asset.ts new file mode 100644 index 000000000..5d0f40a7e --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/asset.ts @@ -0,0 +1,402 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { + AssetEvmTokenAddressInvalidError, + AssetHederaTokenAddressInvalidError, + AssetLifeCycleCashFlowEvmAddressInvalidError, + AssetLifeCycleCashFlowHederaAddressInvalidError, + AssetNameMissingError, +} from "@domain/errors/asset.error" +import { AssetType } from "@domain/model/asset-type.enum" +import { BaseEntity } from "@domain/model/base-entity" +import { isNil } from "@nestjs/common/utils/shared.utils" +import { LifeCycleCashFlowAddress } from "./life-cycle-cash-flow-address.value-object" + +export class Asset extends BaseEntity { + private static readonly HEDERA_ADDRESS_REGEX = /^\d+\.\d+\.\d+$/ + private static readonly EVM_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/ + + constructor( + readonly id: string, + readonly name: string, + readonly type: AssetType, + readonly hederaTokenAddress: string, + readonly evmTokenAddress: string, + readonly symbol: string, + readonly maturityDate?: Date, + readonly lifeCycleCashFlowHederaAddress?: string, + readonly lifeCycleCashFlowEvmAddress?: string, + readonly isPaused: boolean = false, + readonly syncEnabled: boolean = true, + createdAt?: Date, + updatedAt?: Date, + ) { + super(id, createdAt, updatedAt) + this.validateFields() + } + + copyWith(props: Partial): Asset { + return new Asset( + props.id ?? this.id, + props.name ?? this.name, + props.type ?? this.type, + props.hederaTokenAddress ?? this.hederaTokenAddress, + props.evmTokenAddress ?? this.evmTokenAddress, + props.symbol ?? this.symbol, + props.maturityDate ?? this.maturityDate, + props.lifeCycleCashFlowHederaAddress ?? this.lifeCycleCashFlowHederaAddress, + props.lifeCycleCashFlowEvmAddress ?? this.lifeCycleCashFlowEvmAddress, + props.isPaused ?? this.isPaused, + props.syncEnabled ?? this.syncEnabled, + props.createdAt ?? this.createdAt, + props.updatedAt ?? this.updatedAt, + ) + } + + static create( + name: string, + type: AssetType, + hederaTokenAddress: string, + evmTokenAddress: string, + symbol: string, + maturityDate?: Date, + isPaused: boolean = false, + syncEnabled: boolean = true, + ): Asset { + return new Asset( + crypto.randomUUID(), + name, + type, + hederaTokenAddress, + evmTokenAddress, + symbol, + maturityDate, + undefined, + undefined, + isPaused, + syncEnabled, + ) + } + + static createExisting( + assetId: string, + name: string, + type: AssetType, + hederaTokenAddress: string, + evmTokenAddress: string, + symbol: string, + maturityDate: Date | undefined, + hederaLifeCycleCashFlowAddress: string, + evmLifeCycleCashFlowAddress: string, + isPaused: boolean, + syncEnabled: boolean, + createdAt: Date, + updatedAt: Date, + ): Asset { + return new Asset( + assetId, + name, + type, + hederaTokenAddress, + evmTokenAddress, + symbol, + maturityDate, + hederaLifeCycleCashFlowAddress, + evmLifeCycleCashFlowAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + } + + withLifeCycleCashFlow(lifeCycleCashFlowAddress: LifeCycleCashFlowAddress): Asset { + return this.copyWith({ + lifeCycleCashFlowHederaAddress: lifeCycleCashFlowAddress.hederaAddress, + lifeCycleCashFlowEvmAddress: lifeCycleCashFlowAddress.evmAddress, + updatedAt: new Date(), + }) + } + + withName(name: string): Asset { + return this.copyWith({ + name, + updatedAt: new Date(), + }) + } + + withType(type: AssetType): Asset { + return this.copyWith({ + type, + updatedAt: new Date(), + }) + } + + pause(): Asset { + return this.copyWith({ + isPaused: true, + updatedAt: new Date(), + }) + } + + unpause(): Asset { + return this.copyWith({ + isPaused: false, + updatedAt: new Date(), + }) + } + + enableSync(): Asset { + return this.copyWith({ + syncEnabled: true, + updatedAt: new Date(), + }) + } + + disableSync(): Asset { + return this.copyWith({ + syncEnabled: false, + updatedAt: new Date(), + }) + } + + private validateFields(): void { + this.validateName() + this.validateHederaTokenAddress() + this.validateEvmTokenAddress() + this.validateHederaLifeCycleCashFlowAddress() + this.validateEvmLifeCycleCashFlowAddress() + } + + private validateName(): void { + if (isNil(this.name) || this.name.trim().length === 0) { + throw new AssetNameMissingError() + } + } + + private validateHederaTokenAddress(): void { + if (isNil(this.hederaTokenAddress) || !Asset.HEDERA_ADDRESS_REGEX.test(this.hederaTokenAddress)) { + throw new AssetHederaTokenAddressInvalidError() + } + } + + private validateEvmTokenAddress(): void { + if (isNil(this.evmTokenAddress) || !Asset.EVM_ADDRESS_REGEX.test(this.evmTokenAddress)) { + throw new AssetEvmTokenAddressInvalidError() + } + } + + private validateHederaLifeCycleCashFlowAddress(): void { + if (this.lifeCycleCashFlowHederaAddress && !Asset.HEDERA_ADDRESS_REGEX.test(this.lifeCycleCashFlowHederaAddress)) { + throw new AssetLifeCycleCashFlowHederaAddressInvalidError() + } + } + + private validateEvmLifeCycleCashFlowAddress(): void { + if (this.lifeCycleCashFlowEvmAddress && !Asset.EVM_ADDRESS_REGEX.test(this.lifeCycleCashFlowEvmAddress)) { + throw new AssetLifeCycleCashFlowEvmAddressInvalidError() + } + } +} diff --git a/apps/mass-payout/backend/src/domain/model/base-entity.ts b/apps/mass-payout/backend/src/domain/model/base-entity.ts new file mode 100644 index 000000000..85c96df90 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/base-entity.ts @@ -0,0 +1,234 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BaseEntityInvalidDatesError } from "@domain/errors/shared/base-entity-invalid-dates.error" +import { isNil, isUndefined } from "@nestjs/common/utils/shared.utils" +import * as crypto from "crypto" + +export class BaseEntity { + readonly id: string + readonly createdAt: Date + readonly updatedAt: Date + + constructor(id: string = crypto.randomUUID(), createdAt: Date = new Date(), updatedAt: Date = createdAt) { + this.id = id + this.createdAt = createdAt + this.updatedAt = updatedAt + this.validateDates() + } + + isEmpty(value: object): boolean { + return isNil(value) || isUndefined(value) + } + + private validateDates() { + if ( + this.isEmpty(this.createdAt) || + this.isEmpty(this.updatedAt) || + this.createdAt.getTime() > this.updatedAt.getTime() + ) { + throw new BaseEntityInvalidDatesError() + } + } +} diff --git a/apps/mass-payout/backend/src/domain/model/batch-payout.ts b/apps/mass-payout/backend/src/domain/model/batch-payout.ts new file mode 100644 index 000000000..be3b4e6a1 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/batch-payout.ts @@ -0,0 +1,330 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BaseEntity } from "@domain/model/base-entity" +import { isNil } from "@nestjs/common/utils/shared.utils" +import { + BatchPayoutDistributionIdMissingError, + BatchPayoutHederaTransactionIdInvalidError, + BatchPayoutHederaTransactionHashInvalidError, + BatchPayoutHoldersNumberInvalidError, +} from "@domain/errors/batch-payout.error" +import { Distribution } from "@domain/model/distribution" + +export enum BatchPayoutStatus { + PARTIALLY_COMPLETED = "PARTIALLY_COMPLETED", + IN_PROGRESS = "IN_PROGRESS", + FAILED = "FAILED", + COMPLETED = "COMPLETED", +} + +export class BatchPayout extends BaseEntity { + readonly distribution: Distribution + readonly name: string + readonly hederaTransactionId: string + readonly hederaTransactionHash: string + readonly holdersNumber: number + readonly status: BatchPayoutStatus + + private constructor( + id: string, + distribution: Distribution, + name: string, + hederaTransactionId: string, + hederaTransactionHash: string, + holdersNumber: number, + status: BatchPayoutStatus, + createdAt: Date = new Date(), + updatedAt: Date = createdAt, + ) { + super(id, createdAt, updatedAt) + this.distribution = distribution + this.name = name + this.hederaTransactionId = hederaTransactionId + this.hederaTransactionHash = hederaTransactionHash + this.holdersNumber = holdersNumber + this.status = status + this.validateFields() + } + + static create( + distribution: Distribution, + name: string, + hederaTransactionId: string, + hederaTransactionHash: string, + holdersNumber: number, + status: BatchPayoutStatus, + createdAt?: Date, + updatedAt?: Date, + ): BatchPayout { + return new BatchPayout( + crypto.randomUUID(), + distribution, + name, + hederaTransactionId, + hederaTransactionHash, + holdersNumber, + status, + createdAt, + updatedAt, + ) + } + + static createExisting( + id: string, + distribution: Distribution, + name: string, + hederaTransactionId: string, + hederaTransactionHash: string, + holdersNumber: number, + status: BatchPayoutStatus, + createdAt: Date, + updatedAt: Date, + ): BatchPayout { + return new BatchPayout( + id, + distribution, + name, + hederaTransactionId, + hederaTransactionHash, + holdersNumber, + status, + createdAt, + updatedAt, + ) + } + + private validateFields(): void { + this.validateDistributionId() + this.validateHederaTransactionId() + this.validateHederaTransactionHash() + this.validateHoldersNumber() + } + + private validateDistributionId(): void { + if (isNil(this.distribution)) { + throw new BatchPayoutDistributionIdMissingError() + } + } + + private validateHederaTransactionId(): void { + const hederaTransactionIdRegex = /^\d+\.\d+\.\d+@\d+\.\d+$/ + if (isNil(this.hederaTransactionId) || !hederaTransactionIdRegex.test(this.hederaTransactionId)) { + throw new BatchPayoutHederaTransactionIdInvalidError() + } + } + + private validateHederaTransactionHash(): void { + const hederaTransactionHashRegex = /^0x[a-fA-F0-9]{96,98}$/ + if (isNil(this.hederaTransactionHash) || !hederaTransactionHashRegex.test(this.hederaTransactionHash)) { + throw new BatchPayoutHederaTransactionHashInvalidError() + } + } + + private validateHoldersNumber(): void { + if (isNil(this.holdersNumber) || this.holdersNumber <= 0) { + throw new BatchPayoutHoldersNumberInvalidError() + } + } +} diff --git a/apps/mass-payout/backend/src/domain/model/blockchain-listener.ts b/apps/mass-payout/backend/src/domain/model/blockchain-listener.ts new file mode 100644 index 000000000..af6e2bcff --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/blockchain-listener.ts @@ -0,0 +1,245 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { CustomError } from "@domain/errors/shared/custom.error" + +export interface MirrorNodeLog { + timestamp: string + data: string + topics: string[] +} + +export interface MirrorNodeResponse { + logs?: MirrorNodeLog[] +} + +export interface BlockchainEvent { + timestamp: string + name: string + [key: string]: any +} + +export interface TransferEvent extends BlockchainEvent { + from: string + to: string + value: number + rawValue: string +} + +export interface ApprovalEventData extends BlockchainEvent { + owner: string + spender: string + value: number + rawValue: string +} + +export class BlockchainEventListenerError extends CustomError {} + +export class BlockchainEventListenerConfig { + id: string + mirrorNodeUrl: string + contractId: string + tokenDecimals: number + startTimestamp: string +} diff --git a/apps/mass-payout/backend/src/domain/model/distribution.ts b/apps/mass-payout/backend/src/domain/model/distribution.ts new file mode 100644 index 000000000..6791a3b47 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/distribution.ts @@ -0,0 +1,729 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { + DistributionAssetIdMissingError, + DistributionExecutionDateInPastError, + DistributionExecutionDateMissingError, + DistributionNotCorporateActionError, + DistributionNotInStatusError, + DistributionNotPayoutError, + DistributionRecurrencyMissingError, +} from "@domain/errors/distribution.error" +import { Asset } from "@domain/model/asset" +import { BaseEntity } from "@domain/model/base-entity" +import { isNil } from "@nestjs/common/utils/shared.utils" +import { CorporateActionId } from "./value-objects/corporate-action-id" +import { SnapshotId } from "./value-objects/snapshot-id" + +export enum DistributionStatus { + SCHEDULED = "SCHEDULED", + IN_PROGRESS = "IN_PROGRESS", + FAILED = "FAILED", + COMPLETED = "COMPLETED", + CANCELLED = "CANCELLED", +} + +export enum DistributionType { + CORPORATE_ACTION = "CORPORATE_ACTION", + PAYOUT = "PAYOUT", +} + +export enum PayoutSubtype { + IMMEDIATE = "IMMEDIATE", + ONE_OFF = "ONE_OFF", + RECURRING = "RECURRING", + AUTOMATED = "AUTOMATED", +} + +export type CorporateActionDetails = { + type: DistributionType.CORPORATE_ACTION + corporateActionId: CorporateActionId + executionDate: Date +} + +export enum Recurrency { + HOURLY = "HOURLY", + DAILY = "DAILY", + WEEKLY = "WEEKLY", + MONTHLY = "MONTHLY", +} + +type ImmediatePayout = { + subtype: PayoutSubtype.IMMEDIATE + snapshotId: SnapshotId +} + +type OneOffPayout = { + subtype: PayoutSubtype.ONE_OFF + executeAt: Date + snapshotId?: SnapshotId +} + +type RecurringPayout = { + subtype: PayoutSubtype.RECURRING + executeAt: Date + recurrency: Recurrency + snapshotId?: SnapshotId +} + +type AutomatedPayout = { + subtype: PayoutSubtype.AUTOMATED + snapshotId?: SnapshotId +} + +export type PayoutDetails = { + type: DistributionType.PAYOUT + amount: string + amountType: AmountType + concept?: string +} & (ImmediatePayout | OneOffPayout | RecurringPayout | AutomatedPayout) + +export enum AmountType { + FIXED = "FIXED", + PERCENTAGE = "PERCENTAGE", +} + +export type DistributionDetails = CorporateActionDetails | PayoutDetails + +export class Distribution extends BaseEntity { + readonly asset: Asset + readonly details: DistributionDetails + status: DistributionStatus + + private constructor( + id: string, + asset: Asset, + details: DistributionDetails, + status: DistributionStatus, + createdAt: Date = new Date(), + updatedAt: Date = createdAt, + isExisting: boolean = false, + ) { + super(id, createdAt, updatedAt) + this.asset = asset + this.details = details + this.status = status + this.validateFields(isExisting) + } + + static createCorporateAction( + asset: Asset, + corporateActionId: CorporateActionId, + executionDate: Date, + status?: DistributionStatus, + createdAt?: Date, + updatedAt?: Date, + ): Distribution { + return new Distribution( + crypto.randomUUID(), + asset, + { + type: DistributionType.CORPORATE_ACTION, + corporateActionId, + executionDate, + }, + status ?? DistributionStatus.SCHEDULED, + createdAt, + updatedAt, + ) + } + + static createImmediate( + asset: Asset, + amount: string, + amountType: AmountType, + snapshotId?: SnapshotId, + status?: DistributionStatus, + concept?: string, + createdAt?: Date, + updatedAt?: Date, + ): Distribution { + return new Distribution( + crypto.randomUUID(), + asset, + { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + snapshotId, + amount, + amountType, + concept, + }, + status ?? DistributionStatus.SCHEDULED, + createdAt, + updatedAt, + ) + } + + static createOneOff( + asset: Asset, + executeAt: Date, + amount: string, + amountType: AmountType, + snapshotId?: SnapshotId, + status?: DistributionStatus, + concept?: string, + createdAt?: Date, + updatedAt?: Date, + ): Distribution { + return new Distribution( + crypto.randomUUID(), + asset, + { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.ONE_OFF, + snapshotId, + executeAt, + amount, + amountType, + concept, + }, + status ?? DistributionStatus.SCHEDULED, + createdAt, + updatedAt, + ) + } + + static createRecurring( + asset: Asset, + executeAt: Date, + recurrency: Recurrency, + amount: string, + amountType: AmountType, + snapshotId?: SnapshotId, + status?: DistributionStatus, + concept?: string, + createdAt?: Date, + updatedAt?: Date, + ): Distribution { + return new Distribution( + crypto.randomUUID(), + asset, + { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.RECURRING, + snapshotId, + executeAt, + recurrency, + amount, + amountType, + concept, + }, + status ?? DistributionStatus.SCHEDULED, + createdAt, + updatedAt, + ) + } + + static createAutomated( + asset: Asset, + amount: string, + amountType: AmountType, + concept?: string, + snapshotId?: SnapshotId, + status?: DistributionStatus, + createdAt?: Date, + updatedAt?: Date, + ): Distribution { + return new Distribution( + crypto.randomUUID(), + asset, + { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.AUTOMATED, + snapshotId, + amount, + amountType, + concept, + }, + status ?? DistributionStatus.SCHEDULED, + createdAt, + updatedAt, + ) + } + + static createExistingAutomated( + id: string, + asset: Asset, + amount: string, + amountType: AmountType, + concept?: string, + snapshotId?: SnapshotId, + status?: DistributionStatus, + createdAt?: Date, + updatedAt?: Date, + ): Distribution { + return new Distribution( + id, + asset, + { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.AUTOMATED, + snapshotId, + amount, + amountType, + concept, + }, + status ?? DistributionStatus.SCHEDULED, + createdAt, + updatedAt, + ) + } + + static createExistingCorporateAction( + id: string, + asset: Asset, + corporateActionId: CorporateActionId, + executionDate: Date, + status: DistributionStatus, + createdAt: Date, + updatedAt: Date, + ): Distribution { + return new Distribution( + id, + asset, + { + type: DistributionType.CORPORATE_ACTION, + corporateActionId, + executionDate, + }, + status, + createdAt, + updatedAt, + true, + ) + } + + static createExistingImmediate( + id: string, + asset: Asset, + snapshotId: SnapshotId | null, + status: DistributionStatus, + createdAt: Date, + updatedAt: Date, + amount: string, + amountType: AmountType, + concept: string, + ): Distribution { + return new Distribution( + id, + asset, + { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + snapshotId, + amount, + amountType, + concept, + }, + status, + createdAt, + updatedAt, + true, + ) + } + + static createExistingOneOff( + id: string, + asset: Asset, + snapshotId: SnapshotId, + executeAt: Date, + status: DistributionStatus, + amount: string, + amountType: AmountType, + createdAt: Date, + updatedAt: Date, + concept?: string, + ): Distribution { + return new Distribution( + id, + asset, + { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.ONE_OFF, + snapshotId, + executeAt, + amount, + amountType, + concept, + }, + status, + createdAt, + updatedAt, + true, + ) + } + + static createExistingRecurring( + id: string, + asset: Asset, + executeAt: Date, + recurrency: Recurrency, + amount: string, + amountType: AmountType, + snapshotId?: SnapshotId, + status?: DistributionStatus, + createdAt?: Date, + updatedAt?: Date, + concept?: string, + ): Distribution { + return new Distribution( + id, + asset, + { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.RECURRING, + snapshotId, + executeAt, + recurrency, + amount, + amountType, + concept, + }, + status ?? DistributionStatus.SCHEDULED, + createdAt, + updatedAt, + true, + ) + } + + createNextRecurring(): Distribution { + const details: any = this.details as any + return Distribution.createRecurring( + this.asset, + this.calculateNextRecurringDate(), + details.recurrency, + details.amount, + details.amountType, + undefined, + DistributionStatus.SCHEDULED, + details.concept, + ) + } + + updateSnapshotId(snapshot: number): void { + const snapshotId = SnapshotId.create(snapshot.toString()) + if (this.details.type !== DistributionType.PAYOUT) { + throw new Error("Cannot update snapshot ID for non-payout distribution") + } + this.details.snapshotId = snapshotId + } + + updateExecutionDate(executionDate: Date): Distribution { + if (this.details.type !== DistributionType.CORPORATE_ACTION) { + throw new Error("Cannot update execution date for non-corporate action distribution") + } + + return new Distribution( + this.id, + this.asset, + { + ...this.details, + executionDate, + }, + this.status, + this.createdAt, + new Date(), + ) + } + + calculateNextRecurringDate(): Date { + const details: RecurringPayout = this.details as RecurringPayout + const nextDate: Date = new Date(details.executeAt) + switch (details.recurrency) { + case Recurrency.HOURLY: + nextDate.setHours(nextDate.getHours() + 1) + break + case Recurrency.DAILY: + nextDate.setDate(nextDate.getDate() + 1) + break + case Recurrency.WEEKLY: + nextDate.setDate(nextDate.getDate() + 7) + break + case Recurrency.MONTHLY: + nextDate.setMonth(nextDate.getMonth() + 1) + break + } + + return nextDate + } + + verifyIsCorporateAction(): void { + if (this.details.type !== DistributionType.CORPORATE_ACTION) { + throw new DistributionNotCorporateActionError(this.id) + } + } + + verifyIsPayout(): void { + if (this.details.type !== DistributionType.PAYOUT) { + throw new DistributionNotPayoutError(this.id) + } + } + + verifyStatus(status: DistributionStatus): void { + if (this.status !== status) { + throw new DistributionNotInStatusError(this.id, status) + } + } + + cancel(): void { + this.verifyIsPayout() + this.verifyStatus(DistributionStatus.SCHEDULED) + + this.status = DistributionStatus.CANCELLED + } + + private validateFields(isExisting: boolean = false): void { + this.validateAsset() + + if (this.details.type === DistributionType.CORPORATE_ACTION) { + this.validateExecutionDate(isExisting) + } + + if (this.details.type === DistributionType.PAYOUT) { + if (this.details.subtype === PayoutSubtype.ONE_OFF) { + this.validateExecutionDate(isExisting) + } else if (this.details.subtype === PayoutSubtype.RECURRING) { + this.validateExecutionDate(isExisting) + this.validateRecurrency() + } + } + } + + private validateAsset(): void { + if (isNil(this.asset)) { + throw new DistributionAssetIdMissingError() + } + } + + private validateExecutionDate(isExisting: boolean = false): void { + let executionDate: Date | undefined + + if (this.details.type === DistributionType.CORPORATE_ACTION) { + executionDate = this.details.executionDate + } else if ( + this.details.type === DistributionType.PAYOUT && + (this.details.subtype === PayoutSubtype.ONE_OFF || this.details.subtype === PayoutSubtype.RECURRING) + ) { + executionDate = this.details.executeAt + } else { + return + } + + if (isNil(executionDate)) { + throw new DistributionExecutionDateMissingError() + } + + if (!isExisting && executionDate.getTime() <= new Date().getTime()) { + throw new DistributionExecutionDateInPastError() + } + } + + private validateRecurrency(): void { + if (isNil((this.details as RecurringPayout).recurrency)) { + throw new DistributionRecurrencyMissingError() + } + } +} diff --git a/apps/mass-payout/backend/src/domain/model/holder.ts b/apps/mass-payout/backend/src/domain/model/holder.ts new file mode 100644 index 000000000..7211fa87e --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/holder.ts @@ -0,0 +1,360 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BaseEntity } from "@domain/model/base-entity" +import { isNil } from "@nestjs/common/utils/shared.utils" +import { + HolderBatchPayoutIdMissingError, + HolderEvmAddressInvalidError, + HolderHederaAddressInvalidError, + HolderRetryCounterNegativeError, +} from "@domain/errors/holder.error" +import { BatchPayout } from "@domain/model/batch-payout" + +export enum HolderStatus { + PENDING = "PENDING", + RETRYING = "RETRYING", + SUCCESS = "SUCCESS", + FAILED = "FAILED", +} + +export class Holder extends BaseEntity { + readonly batchPayout: BatchPayout + readonly holderHederaAddress: string + readonly holderEvmAddress: string + retryCounter: number + status: HolderStatus + readonly lastError?: string + readonly nextRetryAt?: Date + amount?: string + + private constructor( + id: string, + batchPayout: BatchPayout, + holderHederaAddress: string, + holderEvmAddress: string, + retryCounter: number, + status: HolderStatus, + nextRetryAt: Date, + lastError?: string, + amount?: string, + createdAt: Date = new Date(), + updatedAt: Date = createdAt, + ) { + super(id, createdAt, updatedAt) + this.batchPayout = batchPayout + this.holderHederaAddress = holderHederaAddress + this.holderEvmAddress = holderEvmAddress + this.retryCounter = retryCounter + this.status = status + this.nextRetryAt = nextRetryAt + this.lastError = lastError + this.amount = amount + this.validateFields() + } + + static create( + batchPayout: BatchPayout, + holderHederaAddress: string, + holderEvmAddress: string, + retryCounter: number, + status: HolderStatus, + nextRetryAt?: Date, + lastError?: string, + amount?: string, + createdAt?: Date, + updatedAt?: Date, + ): Holder { + return new Holder( + crypto.randomUUID(), + batchPayout, + holderHederaAddress, + holderEvmAddress, + retryCounter, + status, + nextRetryAt, + lastError, + amount, + createdAt, + updatedAt, + ) + } + + static createExisting( + id: string, + batchPayout: BatchPayout, + holderHederaAddress: string, + holderEvmAddress: string, + retryCounter: number, + status: HolderStatus, + nextRetryAt: Date, + lastError: string, + amount: string, + createdAt: Date, + updatedAt: Date, + ): Holder { + return new Holder( + id, + batchPayout, + holderHederaAddress, + holderEvmAddress, + retryCounter, + status, + nextRetryAt, + lastError, + amount, + createdAt, + updatedAt, + ) + } + + retrying(): void { + this.status = HolderStatus.RETRYING + } + + succeed(amount: string): void { + this.status = HolderStatus.SUCCESS + this.amount = amount + } + + failed(): void { + this.status = HolderStatus.FAILED + this.retryCounter++ + } + + private validateFields(): void { + this.validateBatchPayout() + this.validateHolderHederaAddress() + this.validateHolderEvmAddress() + this.validateRetryCounter() + } + + private validateBatchPayout(): void { + if (isNil(this.batchPayout)) { + throw new HolderBatchPayoutIdMissingError() + } + } + + private validateHolderHederaAddress(): void { + // const hederaAddressRegex = /^\d+\.\d+\.\d+$/ + // TODO restore regexp validation after solving problem with hedera address from evm address + if (isNil(this.holderHederaAddress)) { + // || !hederaAddressRegex.test(this.holderHederaAddress)) { + throw new HolderHederaAddressInvalidError() + } + } + + private validateHolderEvmAddress(): void { + const evmAddressRegex = /^0x[a-fA-F0-9]{40}$/ + if (isNil(this.holderEvmAddress) || !evmAddressRegex.test(this.holderEvmAddress)) { + throw new HolderEvmAddressInvalidError() + } + } + + private validateRetryCounter(): void { + if (isNil(this.retryCounter) || this.retryCounter < 0) { + throw new HolderRetryCounterNegativeError() + } + } +} diff --git a/apps/mass-payout/backend/src/domain/model/life-cycle-cash-flow-address.value-object.ts b/apps/mass-payout/backend/src/domain/model/life-cycle-cash-flow-address.value-object.ts new file mode 100644 index 000000000..ae63b7388 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/life-cycle-cash-flow-address.value-object.ts @@ -0,0 +1,238 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { isNil } from "@nestjs/common/utils/shared.utils" +import { + AssetLifeCycleCashFlowEvmAddressInvalidError, + AssetLifeCycleCashFlowHederaAddressInvalidError, +} from "@domain/errors/asset.error" + +export class LifeCycleCashFlowAddress { + private static readonly HEDERA_ADDRESS_REGEX = /^\d+\.\d+\.\d+$/ + private static readonly EVM_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/ + + private constructor( + readonly hederaAddress: string, + readonly evmAddress: string, + ) { + this.validateHederaAddress() + this.validateEvmAddress() + } + + static create(hederaAddress: string, evmAddress: string): LifeCycleCashFlowAddress { + return new LifeCycleCashFlowAddress(hederaAddress, evmAddress) + } + + private validateHederaAddress(): void { + if (isNil(this.hederaAddress) || !LifeCycleCashFlowAddress.HEDERA_ADDRESS_REGEX.test(this.hederaAddress)) { + throw new AssetLifeCycleCashFlowHederaAddressInvalidError() + } + } + + private validateEvmAddress(): void { + if (isNil(this.evmAddress) || !LifeCycleCashFlowAddress.EVM_ADDRESS_REGEX.test(this.evmAddress)) { + throw new AssetLifeCycleCashFlowEvmAddressInvalidError() + } + } +} diff --git a/apps/mass-payout/backend/src/domain/model/page.ts b/apps/mass-payout/backend/src/domain/model/page.ts new file mode 100644 index 000000000..e9c20c2c2 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/page.ts @@ -0,0 +1,233 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export class OrderPageOptions { + static DEFAULT: OrderPageOptions = { + order: "DESC", + orderBy: "createdAt", + } + + order: "asc" | "desc" | "ASC" | "DESC" + orderBy: string +} + +export class PageOptions { + static DEFAULT: PageOptions = { + page: 1, + limit: 10, + order: OrderPageOptions.DEFAULT, + } + + page: number + limit: number + order: OrderPageOptions +} + +export interface Page { + items: T[] + total: number + page: number + limit: number + totalPages: number +} diff --git a/apps/mass-payout/backend/src/domain/model/value-objects/corporate-action-id.ts b/apps/mass-payout/backend/src/domain/model/value-objects/corporate-action-id.ts new file mode 100644 index 000000000..be26693c5 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/value-objects/corporate-action-id.ts @@ -0,0 +1,220 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { DistributionCorporateActionIDMissingError } from "@domain/errors/distribution.error" + +export class CorporateActionId { + readonly value: string + + private constructor(value: string) { + this.value = value + } + + static create(value: string): CorporateActionId { + if (!value || value.trim().length === 0) { + throw new DistributionCorporateActionIDMissingError() + } + return new CorporateActionId(value) + } +} diff --git a/apps/mass-payout/backend/src/domain/model/value-objects/snapshot-id.ts b/apps/mass-payout/backend/src/domain/model/value-objects/snapshot-id.ts new file mode 100644 index 000000000..30aacc57b --- /dev/null +++ b/apps/mass-payout/backend/src/domain/model/value-objects/snapshot-id.ts @@ -0,0 +1,220 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { DistributionSnapshotIDMissingError } from "@domain/errors/distribution.error" + +export class SnapshotId { + readonly value: string + + private constructor(value: string) { + this.value = value + } + + static create(value: string): SnapshotId { + if (!value || value.trim().length === 0) { + throw new DistributionSnapshotIDMissingError() + } + return new SnapshotId(value) + } +} diff --git a/apps/mass-payout/backend/src/domain/ports/asset-repository.port.ts b/apps/mass-payout/backend/src/domain/ports/asset-repository.port.ts new file mode 100644 index 000000000..ce267808c --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/asset-repository.port.ts @@ -0,0 +1,226 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { Page, PageOptions } from "@domain/model/page" + +export interface AssetRepository { + saveAsset(item: Asset): Promise + + updateAsset(item: Asset): Promise + + getAsset(id: string): Promise + + getAssetByName(name: string): Promise + + getAssetByHederaTokenAddress(hederaTokenAddress: string): Promise + + deleteAssets(ids: string[]): Promise + + getAllAssets(): Promise + + getAllSyncEnabledAssets(): Promise + + getAssets(pageOptions: PageOptions): Promise> +} diff --git a/apps/mass-payout/backend/src/domain/ports/asset-tokenization-studio.port.ts b/apps/mass-payout/backend/src/domain/ports/asset-tokenization-studio.port.ts new file mode 100644 index 000000000..d15706088 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/asset-tokenization-studio.port.ts @@ -0,0 +1,211 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetAssetInfoResponse } from "@domain/ports/get-asset-info-response.interface" + +export interface AssetTokenizationStudioService { + getAssetInfo(hederaTokenId: string): Promise + + takeSnapshot(hederaTokenId: string): Promise +} diff --git a/apps/mass-payout/backend/src/domain/ports/batch-payout-repository.port.ts b/apps/mass-payout/backend/src/domain/ports/batch-payout-repository.port.ts new file mode 100644 index 000000000..5fa2517de --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/batch-payout-repository.port.ts @@ -0,0 +1,218 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout } from "@domain/model/batch-payout" +import { Distribution } from "@domain/model/distribution" + +export interface BatchPayoutRepository { + getBatchPayout(id: string): Promise + + saveBatchPayout(batchPayout: BatchPayout): Promise + + saveBatchPayouts(batchPayouts: BatchPayout[]): Promise + + getBatchPayoutsByDistribution(distribution: Distribution): Promise + + updateBatchPayout(batchPayout: BatchPayout): Promise +} diff --git a/apps/mass-payout/backend/src/domain/ports/blockchain-event-config-repository.port.ts b/apps/mass-payout/backend/src/domain/ports/blockchain-event-config-repository.port.ts new file mode 100644 index 000000000..c394b99a4 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/blockchain-event-config-repository.port.ts @@ -0,0 +1,213 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BlockchainEventListenerConfig } from "@domain/model/blockchain-listener" + +export interface BlockchainEventListenerConfigRepository { + save(item: BlockchainEventListenerConfig): Promise + + update(item: BlockchainEventListenerConfig): Promise + + getConfig(): Promise +} diff --git a/apps/mass-payout/backend/src/domain/ports/blockchain-event-listener.service.ts b/apps/mass-payout/backend/src/domain/ports/blockchain-event-listener.service.ts new file mode 100644 index 000000000..40cfe48df --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/blockchain-event-listener.service.ts @@ -0,0 +1,210 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BlockchainEvent } from "@domain/model/blockchain-listener" + +export interface BlockchainEventListenerService { + fetchNewEvents(): Promise + updateStartTimestamp(newStartTimestamp: string): Promise +} diff --git a/apps/mass-payout/backend/src/domain/ports/blockchain-polling.port.ts b/apps/mass-payout/backend/src/domain/ports/blockchain-polling.port.ts new file mode 100644 index 000000000..026bbff76 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/blockchain-polling.port.ts @@ -0,0 +1,209 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export interface BlockchainPollingPort { + start(): Promise + stop(): void + restart(): void +} diff --git a/apps/mass-payout/backend/src/domain/ports/distribution-repository.port.ts b/apps/mass-payout/backend/src/domain/ports/distribution-repository.port.ts new file mode 100644 index 000000000..39014a89a --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/distribution-repository.port.ts @@ -0,0 +1,226 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Distribution, DistributionStatus } from "@domain/model/distribution" +import { Page, PageOptions } from "@domain/model/page" + +export interface DistributionRepository { + saveDistribution(distribution: Distribution): Promise + + getDistribution(id: string): Promise + + getAllDistributionsByAssetId(assetId: string): Promise + + getDistributionsByAssetId(assetId: string, pageOptions: PageOptions): Promise> + + findByCorporateActionId(assetId: string, corporateActionId: string): Promise + + findByExecutionDateRange(startDate: Date, endDate: Date, status?: DistributionStatus): Promise + + updateDistribution(distribution: Distribution): Promise + + getDistributions(pageOptions: PageOptions): Promise> + + getScheduledAutomatedDistributionsByEvmAddress(evmAddress: string): Promise +} diff --git a/apps/mass-payout/backend/src/domain/ports/execute-distribution-response.interface.ts b/apps/mass-payout/backend/src/domain/ports/execute-distribution-response.interface.ts new file mode 100644 index 000000000..a6a9762e4 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/execute-distribution-response.interface.ts @@ -0,0 +1,210 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export interface ExecuteDistributionResponse { + readonly failed: string[] + readonly succeeded: string[] + readonly paidAmount: string[] + readonly transactionId: string +} diff --git a/apps/mass-payout/backend/src/domain/ports/get-asset-info-response.interface.ts b/apps/mass-payout/backend/src/domain/ports/get-asset-info-response.interface.ts new file mode 100644 index 000000000..750d2bac5 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/get-asset-info-response.interface.ts @@ -0,0 +1,213 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetType } from "@domain/model/asset-type.enum" + +export interface GetAssetInfoResponse { + readonly hederaTokenAddress: string + readonly name: string + readonly symbol: string + readonly assetType: AssetType + readonly maturityDate?: Date +} diff --git a/apps/mass-payout/backend/src/domain/ports/hedera.port.ts b/apps/mass-payout/backend/src/domain/ports/hedera.port.ts new file mode 100644 index 000000000..368fd3f5d --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/hedera.port.ts @@ -0,0 +1,233 @@ +/* + * 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 use, reproduce, modify, distribute, and prepare + * Derivative Works of the Work, and to publicly perform and display the + * Work and such Derivative Works in any medium or format, whether now + * known or hereafter devised, provided that You properly attribute the + * Work in the manner specified by the author or licensor (but not in any + * way that suggests the licensor endorses You or Your use of the Work). + * + * 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, trademark, patent, 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 notice 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 Support. When 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 support. + * + * 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. + */ + +/** + * Response interface for Hedera transaction hash retrieval + */ +export interface HederaTransactionHashResponse { + /** The EVM transaction hash in hexadecimal format with 0x prefix */ + hederaTransactionHash: string + /** Whether the hash was retrieved from Mirror Node API or generated as fallback */ + isFromMirrorNode: boolean +} + +/** + * Port interface for Hedera Mirror Node operations + * Provides access to transaction data and EVM hash extraction + */ +export interface HederaService { + /** + * Retrieves the Hedera transaction hash for a parent transaction from Hedera Mirror Node + * Converts the base64 hash from Mirror Node API to hexadecimal format + * + * @param transactionId The Hedera transaction ID (format: accountId@seconds.nanoseconds) + * @returns Promise with Hedera transaction hash response + * @throws Error if transaction ID format is invalid + */ + getParentHederaTransactionHash(transactionId: string): Promise + + getEvmAddressFromHedera(hederaAddress: string): Promise + + getHederaAddressFromEvm(evmAddress: string): Promise +} diff --git a/apps/mass-payout/backend/src/domain/ports/holder-repository.port.ts b/apps/mass-payout/backend/src/domain/ports/holder-repository.port.ts new file mode 100644 index 000000000..542a58836 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/holder-repository.port.ts @@ -0,0 +1,224 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Holder, HolderStatus } from "@domain/model/holder" +import { Page, PageOptions } from "@domain/model/page" + +export interface HolderRepository { + saveHolder(holder: Holder): Promise + + saveHolders(holders: Holder[]): Promise + + updateHolder(holder: Holder): Promise + + getHoldersByBatchPayout(batchPayoutId: string): Promise + + getAllHoldersByDistributionId(distributionId: string): Promise + + getHoldersByDistributionId(distributionId: string, pageOptions: PageOptions): Promise> + + countHoldersByDistributionId(distributionId: string): Promise + + getHoldersByDistributionIdAndStatus(distributionId: string, holderStatus: HolderStatus): Promise +} diff --git a/apps/mass-payout/backend/src/domain/ports/life-cycle-cash-flow.port.ts b/apps/mass-payout/backend/src/domain/ports/life-cycle-cash-flow.port.ts new file mode 100644 index 000000000..6c06beb32 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/life-cycle-cash-flow.port.ts @@ -0,0 +1,265 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { LifeCycleCashFlowAddress } from "@domain/model/life-cycle-cash-flow-address.value-object" +import { ExecuteDistributionResponse } from "@domain/ports/execute-distribution-response.interface" + +export interface LifeCycleCashFlowPort { + deployContract(hederaTokenAddress: string, hederaUsdcAddress: string): Promise + + pause(assetId: string): Promise + + unpause(assetId: string): Promise + + isPaused(assetId: string): Promise + + executeDistribution( + lifeCycleCashFlowId: string, + asset: string, + distributionID: number, + pageIndex: number, + pageLength: number, + ): Promise + + executeDistributionByAddresses( + lifeCycleCashFlowId: string, + asset: string, + distributionID: number, + holders: string[], + ): Promise + + executeAmountSnapshot( + lifeCycleCashFlowId: string, + asset: string, + snapshotId: number, + pageIndex: number, + pageLength: number, + amount: string, + ): Promise + + executeAmountSnapshotByAddresses( + lifeCycleCashFlowId: string, + asset: string, + snapshotId: number, + holders: string[], + amount: string, + ): Promise + + executePercentageSnapshot( + lifeCycleCashFlowId: string, + asset: string, + snapshotId: number, + pageIndex: number, + pageLength: number, + percentage: string, + ): Promise + + executePercentageSnapshotByAddresses( + lifeCycleCashFlowId: string, + asset: string, + snapshotId: number, + holders: string[], + percentage: string, + ): Promise +} diff --git a/apps/mass-payout/backend/src/domain/ports/on-chain-distribution-repository.port.ts b/apps/mass-payout/backend/src/domain/ports/on-chain-distribution-repository.port.ts new file mode 100644 index 000000000..d0e1cad1c --- /dev/null +++ b/apps/mass-payout/backend/src/domain/ports/on-chain-distribution-repository.port.ts @@ -0,0 +1,233 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Distribution } from "@domain/model/distribution" +import { Asset } from "@domain/model/asset" + +export interface OnChainDistributionData { + corporateActionID: string + assetId: string + executionDate: Date + // Other relevant fields that may come from the ATS +} + +export interface OnChainDistributionRepositoryPort { + /** + * Gets all distributions for a specific asset from the ATS. + * The service layer will be responsible for filtering new ones + */ + getAllDistributionsByAsset(asset: Asset): Promise + + /** + * Gets the count of holders for a specific corporate action distribution from the ATS. + * @param distribution the distribution containing all necessary information + */ + getHoldersCountForCorporateActionId(distribution: Distribution): Promise + + /** + * Gets the count of holders for a specific payout distribution from the ATS. + * @param distribution the distribution containing all necessary information + */ + getHoldersCountForSnapshotId(distribution: Distribution): Promise +} diff --git a/apps/mass-payout/backend/src/domain/services/base-payout.domain-service.ts b/apps/mass-payout/backend/src/domain/services/base-payout.domain-service.ts new file mode 100644 index 000000000..bcc9dab1b --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/base-payout.domain-service.ts @@ -0,0 +1,331 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout, BatchPayoutStatus } from "@domain/model/batch-payout" +import { Distribution } from "@domain/model/distribution" +import { UpdateBatchPayoutStatusDomainService } from "./update-batch-payout-status.domain-service" +import { CreateHoldersDomainService } from "./create-holders.domain-service" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { HederaService } from "@domain/ports/hedera.port" +import { Inject } from "@nestjs/common" +import { ConfigService } from "@nestjs/config" +import { ExecuteDistributionResponse } from "@domain/ports/execute-distribution-response.interface" + +export abstract class BasePayoutDomainService { + protected constructor( + @Inject(CreateHoldersDomainService) + protected readonly createHoldersDomainService: CreateHoldersDomainService, + @Inject("UpdateBatchPayoutStatusDomainService") + protected readonly updateBatchPayoutStatusDomainService: UpdateBatchPayoutStatusDomainService, + @Inject("BatchPayoutRepository") + protected readonly batchPayoutRepository: BatchPayoutRepository, + @Inject("HederaService") + protected readonly hederaService: HederaService, + protected readonly configService: ConfigService, + ) {} + + async execute(distribution: Distribution) { + const batchPayouts = await this.createBatchPayouts(distribution) + await this.processBatchPayouts(batchPayouts) + } + + protected abstract getHoldersCount(distribution: Distribution): Promise + + protected abstract executeHederaCall(batch: BatchPayout, pageIndex: number): Promise + + protected async createBatchPayouts(distribution: Distribution): Promise { + const batchSize = this.configService.get("BATCH_SIZE") || 100 + const existingBatchPayouts = await this.batchPayoutRepository.getBatchPayoutsByDistribution(distribution) + if (existingBatchPayouts.length > 0) { + throw new Error(`BatchPayouts already exist for distribution ${distribution.id}`) + } + const holdersCount = await this.getHoldersCount(distribution) + const numberOfBatches = Math.ceil(holdersCount / batchSize) + + const batchPayouts: BatchPayout[] = [] + + for (let i = 0; i < numberOfBatches; i++) { + const currentBatchSize = Math.min(batchSize, holdersCount - i * batchSize) + + const batchPayout = BatchPayout.create( + distribution, + `Batch ${i + 1}`, + "0.0.0@0000000000.000000000", + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + currentBatchSize, + BatchPayoutStatus.IN_PROGRESS, + ) + + await this.batchPayoutRepository.saveBatchPayout(batchPayout) + batchPayouts.push(batchPayout) + } + + return batchPayouts + } + + protected async processBatchPayouts(batchPayouts: BatchPayout[]): Promise { + for (const [pageIndex, batchPayout] of batchPayouts.entries()) { + await this.processSingleBatchPayout(batchPayout, pageIndex) + } + } + + protected async processSingleBatchPayout(batchPayout: BatchPayout, pageIndex: number): Promise { + const result = await this.executeHederaCall(batchPayout, pageIndex) + const updatedBatchPayout = await this.handlePayoutResult(batchPayout, result) + await this.updateBatchPayoutStatusDomainService.execute(updatedBatchPayout) + } + + protected async handlePayoutResult( + batchPayout: BatchPayout, + result: ExecuteDistributionResponse, + ): Promise { + try { + await this.createHoldersDomainService.execute(batchPayout, result.failed, result.succeeded, result.paidAmount) + + if (result.transactionId) { + return await this.updateBatchPayoutTransactionHashes(batchPayout, result.transactionId) + } + + return batchPayout + } catch (error) { + console.error("[BasePayoutDomainService] ERROR in handlePayoutResult:", error) + throw error + } + } + + /** + * Updates the transaction addresses in BatchPayout after successful DLT execution + * @param batchPayout The batch payout to update + * @param transactionId The transaction ID from the DLT response + */ + private async updateBatchPayoutTransactionHashes( + batchPayout: BatchPayout, + transactionId: string, + ): Promise { + try { + const hederaTransactionId = transactionId + + const hashResponse = await this.hederaService.getParentHederaTransactionHash(transactionId) + const hederaTransactionHash = hashResponse.hederaTransactionHash + + const updatedBatchPayout = BatchPayout.createExisting( + batchPayout.id, + batchPayout.distribution, + batchPayout.name, + hederaTransactionId, + hederaTransactionHash, + batchPayout.holdersNumber, + batchPayout.status, + batchPayout.createdAt, + batchPayout.updatedAt, + ) + + await this.batchPayoutRepository.updateBatchPayout(updatedBatchPayout) + return updatedBatchPayout + } catch (error) { + console.error(`Failed to update transaction hashes for BatchPayout ${batchPayout.id}:`, error) + return batchPayout + } + } +} diff --git a/apps/mass-payout/backend/src/domain/services/create-holders.domain-service.ts b/apps/mass-payout/backend/src/domain/services/create-holders.domain-service.ts new file mode 100644 index 000000000..902e1f96d --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/create-holders.domain-service.ts @@ -0,0 +1,268 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout } from "@domain/model/batch-payout" +import { Holder, HolderStatus } from "@domain/model/holder" +import { Inject, Injectable } from "@nestjs/common" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { isZeroAddress } from "../../utils/isZeroAddress" +import { HederaService } from "@domain/ports/hedera.port" + +export const ONE_HOUR = 60 * 60 * 1000 +const INITIAL_RETRY_COUNT = 0 + +@Injectable() +export class CreateHoldersDomainService { + constructor( + @Inject("HolderRepository") + private readonly holderRepository: HolderRepository, + @Inject("HederaService") + private readonly hederaService: HederaService, + ) {} + + async execute( + batchPayout: BatchPayout, + failedAddresses: string[], + succeededAddresses: string[], + paidAmounts: string[], + ): Promise { + const filteredFailedAddresses = failedAddresses.filter((address) => !isZeroAddress(address)) + const filteredSucceededAddresses = succeededAddresses.filter((address) => !isZeroAddress(address)) + + const nextRetryAt = new Date(Date.now() + ONE_HOUR) + + let holders: Holder[] = await Promise.all( + filteredFailedAddresses.map(async (address) => { + return Holder.create( + batchPayout, + await this.hederaService.getHederaAddressFromEvm(address), + address, + INITIAL_RETRY_COUNT, + HolderStatus.FAILED, + nextRetryAt, + "Payment execution failed", + ) + }), + ) + + const successHolders = await Promise.all( + filteredSucceededAddresses.map(async (address, index) => { + return Holder.create( + batchPayout, + await this.hederaService.getHederaAddressFromEvm(address), + address, + INITIAL_RETRY_COUNT, + HolderStatus.SUCCESS, + undefined, + undefined, + paidAmounts[index], + ) + }), + ) + + holders = holders.concat(successHolders) + + return await this.holderRepository.saveHolders(holders) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/disable-asset-sync.domain-service.ts b/apps/mass-payout/backend/src/domain/services/disable-asset-sync.domain-service.ts new file mode 100644 index 000000000..b62c108d4 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/disable-asset-sync.domain-service.ts @@ -0,0 +1,228 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetNotFoundError } from "@domain/errors/asset.error" +import { Asset } from "@domain/model/asset" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class DisableAssetSyncDomainService { + constructor( + @Inject("AssetRepository") + private readonly assetRepository: AssetRepository, + ) {} + + async execute(assetId: string): Promise { + const asset = await this.assetRepository.getAsset(assetId) + if (!asset) { + throw new AssetNotFoundError(assetId) + } + if (!asset.syncEnabled) { + return asset + } + const syncDisabledAsset = asset.disableSync() + return await this.assetRepository.updateAsset(syncDisabledAsset) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/enable-asset-sync.domain-service.ts b/apps/mass-payout/backend/src/domain/services/enable-asset-sync.domain-service.ts new file mode 100644 index 000000000..7ad5850ea --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/enable-asset-sync.domain-service.ts @@ -0,0 +1,228 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetNotFoundError } from "@domain/errors/asset.error" +import { Asset } from "@domain/model/asset" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class EnableAssetSyncDomainService { + constructor( + @Inject("AssetRepository") + private readonly assetRepository: AssetRepository, + ) {} + + async execute(assetId: string): Promise { + const asset = await this.assetRepository.getAsset(assetId) + if (!asset) { + throw new AssetNotFoundError(assetId) + } + if (asset.syncEnabled) { + return asset + } + const syncEnabledAsset = asset.enableSync() + return await this.assetRepository.updateAsset(syncEnabledAsset) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/execute-corporate-action-distribution.domain-service.ts b/apps/mass-payout/backend/src/domain/services/execute-corporate-action-distribution.domain-service.ts new file mode 100644 index 000000000..2a2361abc --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/execute-corporate-action-distribution.domain-service.ts @@ -0,0 +1,291 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout } from "@domain/model/batch-payout" +import { Distribution } from "@domain/model/distribution" +import { Inject, Injectable } from "@nestjs/common" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { BasePayoutDomainService } from "@domain/services/base-payout.domain-service" +import { CreateHoldersDomainService } from "@domain/services/create-holders.domain-service" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" +import { ValidateAssetPauseStateDomainService } from "@domain/services/validate-asset-pause-state.domain-service" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { ConfigService } from "@nestjs/config" +import { OnChainDistributionRepositoryPort } from "@domain/ports/on-chain-distribution-repository.port" +import { HederaService } from "@domain/ports/hedera.port" +import { ExecuteDistributionResponse } from "@domain/ports/execute-distribution-response.interface" + +@Injectable() +export class ExecuteCorporateActionDistributionDomainService extends BasePayoutDomainService { + constructor( + @Inject("OnChainDistributionRepositoryPort") + private readonly onChainDistributionRepository: OnChainDistributionRepositoryPort, + @Inject(CreateHoldersDomainService) + readonly createHoldersDomainService: CreateHoldersDomainService, + @Inject("UpdateBatchPayoutStatusDomainService") + readonly updateBatchPayoutStatusDomainService: UpdateBatchPayoutStatusDomainService, + @Inject("BatchPayoutRepository") + readonly batchPayoutRepository: BatchPayoutRepository, + readonly configService: ConfigService, + @Inject("HederaService") + readonly hederaService: HederaService, + @Inject("OnChainLifeCycleCashFlowService") + private readonly onChainLifeCycleCashFlowService: LifeCycleCashFlowPort, + private readonly validateAssetPauseStateDomainService: ValidateAssetPauseStateDomainService, + ) { + super( + createHoldersDomainService, + updateBatchPayoutStatusDomainService, + batchPayoutRepository, + hederaService, + configService, + ) + } + + override async execute(distribution: Distribution): Promise { + distribution.verifyIsCorporateAction() + await this.validateAssetPauseStateDomainService.validateDomainPauseState(distribution.asset, distribution.id) + const now = new Date() + const executionDate = (distribution.details as any).executionDate + + const todayNormalized = new Date(now.getFullYear(), now.getMonth(), now.getDate()) + const executionDateNormalized = new Date( + executionDate.getFullYear(), + executionDate.getMonth(), + executionDate.getDate(), + ) + + if (todayNormalized < executionDateNormalized) { + return + } + const batchPayouts = await this.createBatchPayouts(distribution) + await this.processBatchPayouts(batchPayouts) + } + + protected override async getHoldersCount(distribution: Distribution): Promise { + distribution.verifyIsCorporateAction() + const holdersCount = await this.onChainDistributionRepository.getHoldersCountForCorporateActionId(distribution) + if (holdersCount <= 0) { + throw new Error(`No holders found for distribution ${distribution.id}`) + } + return holdersCount + } + + protected override async executeHederaCall( + batch: BatchPayout, + pageIndex: number, + ): Promise { + const distribution = batch.distribution + distribution.verifyIsCorporateAction() + const asset = distribution.asset + const corporateActionId = (distribution.details as any).corporateActionId.value + return this.onChainLifeCycleCashFlowService.executeDistribution( + asset.lifeCycleCashFlowHederaAddress, + asset.hederaTokenAddress, + Number(corporateActionId), + pageIndex, + batch.holdersNumber, + ) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/execute-payout-distribution.domain-service.ts b/apps/mass-payout/backend/src/domain/services/execute-payout-distribution.domain-service.ts new file mode 100644 index 000000000..428de3e6b --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/execute-payout-distribution.domain-service.ts @@ -0,0 +1,334 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout } from "@domain/model/batch-payout" +import { AmountType, Distribution, PayoutSubtype, PayoutDetails } from "@domain/model/distribution" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { OnChainDistributionRepositoryPort } from "@domain/ports/on-chain-distribution-repository.port" +import { BasePayoutDomainService } from "@domain/services/base-payout.domain-service" +import { CreateHoldersDomainService } from "@domain/services/create-holders.domain-service" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" +import { ValidateAssetPauseStateDomainService } from "@domain/services/validate-asset-pause-state.domain-service" +import { Inject, Injectable } from "@nestjs/common" +import { ConfigService } from "@nestjs/config" +import { ExecuteDistributionResponse } from "@domain/ports/execute-distribution-response.interface" +import { HederaService } from "@domain/ports/hedera.port" + +@Injectable() +export class ExecutePayoutDistributionDomainService extends BasePayoutDomainService { + constructor( + @Inject("AssetTokenizationStudioService") + private readonly assetTokenizationStudioService: AssetTokenizationStudioService, + @Inject("OnChainDistributionRepositoryPort") + private readonly onChainDistributionRepository: OnChainDistributionRepositoryPort, + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + @Inject(CreateHoldersDomainService) + readonly createHoldersDomainService: CreateHoldersDomainService, + @Inject("UpdateBatchPayoutStatusDomainService") + readonly updateBatchPayoutStatusDomainService: UpdateBatchPayoutStatusDomainService, + @Inject("UpdateDistributionStatusDomainService") + private readonly updateDistributionStatusDomainService: UpdateDistributionStatusDomainService, + @Inject("BatchPayoutRepository") + readonly batchPayoutRepository: BatchPayoutRepository, + readonly configService: ConfigService, + @Inject("HederaService") + readonly hederaService: HederaService, + @Inject("OnChainLifeCycleCashFlowService") + private readonly onChainLifeCycleCashFlowService: LifeCycleCashFlowPort, + readonly validateAssetPauseStateDomainService: ValidateAssetPauseStateDomainService, + ) { + super( + createHoldersDomainService, + updateBatchPayoutStatusDomainService, + batchPayoutRepository, + hederaService, + configService, + ) + } + + override async execute(distribution: Distribution): Promise { + distribution.verifyIsPayout() + await this.validateAssetPauseStateDomainService.validateDomainPauseState(distribution.asset, distribution.id) + + const distributionWithInProgressStatus = + this.updateDistributionStatusDomainService.setDistributionStatusToInProgress(distribution) + await this.distributionRepository.updateDistribution(distributionWithInProgressStatus) + + await this.createSnapshot(distributionWithInProgressStatus) + if ((distribution.details as any).subtype === PayoutSubtype.RECURRING) { + await this.createNextRecurringDistribution(distributionWithInProgressStatus) + } + const batchPayouts = await this.createBatchPayouts(distributionWithInProgressStatus) + await this.processBatchPayouts(batchPayouts) + } + + protected override async getHoldersCount(distribution: Distribution): Promise { + distribution.verifyIsPayout() + + const payoutDetails = distribution.details as PayoutDetails + if (!payoutDetails.snapshotId) { + throw new Error(`SnapshotId is missing for distribution ${distribution.id}`) + } + + const holdersCount = await this.onChainDistributionRepository.getHoldersCountForSnapshotId(distribution) + + if (holdersCount <= 0) { + throw new Error(`No holders found for distribution ${distribution.id}`) + } + + return holdersCount + } + + protected override async executeHederaCall( + batch: BatchPayout, + pageIndex: number, + ): Promise { + const distribution = batch.distribution + const asset = distribution.asset + + distribution.verifyIsPayout() + + const payoutDetails = distribution.details as PayoutDetails + if (!payoutDetails.snapshotId) { + throw new Error(`SnapshotId is missing for distribution ${distribution.id}`) + } + + const snapshotId = payoutDetails.snapshotId.value + + if (payoutDetails.amountType == AmountType.FIXED) { + return this.onChainLifeCycleCashFlowService.executeAmountSnapshot( + asset.lifeCycleCashFlowHederaAddress, + asset.hederaTokenAddress, + Number(snapshotId), + pageIndex, + batch.holdersNumber, + payoutDetails.amount, + ) + } else { + return this.onChainLifeCycleCashFlowService.executePercentageSnapshot( + asset.lifeCycleCashFlowHederaAddress, + asset.hederaTokenAddress, + Number(snapshotId), + pageIndex, + batch.holdersNumber, + payoutDetails.amount, + ) + } + } + + private async createSnapshot(distribution: Distribution): Promise { + const snapshot = await this.assetTokenizationStudioService.takeSnapshot(distribution.asset.hederaTokenAddress) + distribution.updateSnapshotId(snapshot) + await this.distributionRepository.updateDistribution(distribution) + } + + private async createNextRecurringDistribution(distribution: Distribution): Promise { + await this.distributionRepository.saveDistribution(distribution.createNextRecurring()) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/import-asset.domain-service.ts b/apps/mass-payout/backend/src/domain/services/import-asset.domain-service.ts new file mode 100644 index 000000000..158e78b2a --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/import-asset.domain-service.ts @@ -0,0 +1,280 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { Inject, Injectable } from "@nestjs/common" +import { ConfigService } from "@nestjs/config" +import { ConfigKeys } from "@config/config-keys" +import { AssetHederaTokenAddressAlreadyExistsError } from "@domain/errors/asset.error" +import { SyncFromOnChainDomainService } from "@domain/services/sync-from-onchain.domain-service" +import { HederaService } from "@domain/ports/hedera.port" + +@Injectable() +export class ImportAssetDomainService { + constructor( + @Inject("AssetRepository") + private readonly assetRepository: AssetRepository, + @Inject("OnChainLifeCycleCashFlowService") + private readonly onChainLifeCycleCashFlowService: LifeCycleCashFlowPort, + @Inject("AssetTokenizationStudioService") + private readonly assetTokenizationStudioService: AssetTokenizationStudioService, + @Inject("HederaService") + private readonly hederaService: HederaService, + private readonly configService: ConfigService, + private readonly syncFromOnChainDomainService: SyncFromOnChainDomainService, + ) {} + + async importAsset(hederaTokenAddress: string): Promise { + const hederaUsdcAddress = this.configService.get(ConfigKeys.HEDERA_USDC_ADDRESS) + + if (!hederaUsdcAddress) { + throw new Error("HEDERA_USDC_ADDRESS environment variable is not configured") + } + const evmTokenAddress = await this.hederaService.getEvmAddressFromHedera(hederaTokenAddress) + + const assetWithSameHederaTokenAddress = await this.assetRepository.getAssetByHederaTokenAddress(hederaTokenAddress) + if (assetWithSameHederaTokenAddress) { + throw new AssetHederaTokenAddressAlreadyExistsError(hederaTokenAddress) + } + + let getAssetInfoResponse + try { + getAssetInfoResponse = await this.assetTokenizationStudioService.getAssetInfo(hederaTokenAddress) + } catch (error) { + console.error(`Error getting asset info for ${hederaTokenAddress}:`, error) + throw new Error(`Failed to get asset information for token ${hederaTokenAddress}: ${error.message}`) + } + + if (!getAssetInfoResponse) { + throw new Error(`No asset information found for token ${hederaTokenAddress}`) + } + const isPaused = await this.onChainLifeCycleCashFlowService.isPaused(hederaTokenAddress) + + const lifeCycleCashFlowAddress = await this.onChainLifeCycleCashFlowService.deployContract( + hederaTokenAddress, + hederaUsdcAddress, + ) + + const asset = Asset.create( + getAssetInfoResponse.name, + getAssetInfoResponse.assetType, + hederaTokenAddress, + evmTokenAddress, + getAssetInfoResponse.symbol, + getAssetInfoResponse.maturityDate, + isPaused, + ) + + const assetWithLifeCycleCashFlow = asset.withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + await this.assetRepository.saveAsset(assetWithLifeCycleCashFlow) + + await this.syncFromOnChainDomainService.execute() + + return assetWithLifeCycleCashFlow + } +} diff --git a/apps/mass-payout/backend/src/domain/services/pause-asset.domain-service.ts b/apps/mass-payout/backend/src/domain/services/pause-asset.domain-service.ts new file mode 100644 index 000000000..83b1879ba --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/pause-asset.domain-service.ts @@ -0,0 +1,236 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetNotFoundError } from "@domain/errors/asset.error" +import { Asset } from "@domain/model/asset" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class PauseAssetDomainService { + constructor( + @Inject("AssetRepository") + private readonly assetRepository: AssetRepository, + @Inject("OnChainLifeCycleCashFlowService") + private readonly onChainLifeCycleCashFlowService: LifeCycleCashFlowPort, + ) {} + + async pause(assetId: string): Promise { + const asset = await this.assetRepository.getAsset(assetId) + if (!asset) { + throw new AssetNotFoundError(`Asset with ID ${assetId} not found`) + } + if (asset.isPaused) { + return asset + } + + await this.onChainLifeCycleCashFlowService.pause(asset.lifeCycleCashFlowHederaAddress) + + const pausedAsset = asset.pause() + await this.assetRepository.updateAsset(pausedAsset) + + return pausedAsset + } +} diff --git a/apps/mass-payout/backend/src/domain/services/retry-failed-holders.domain-service.ts b/apps/mass-payout/backend/src/domain/services/retry-failed-holders.domain-service.ts new file mode 100644 index 000000000..3813c0673 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/retry-failed-holders.domain-service.ts @@ -0,0 +1,312 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Inject, Injectable } from "@nestjs/common" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { Holder, HolderStatus } from "@domain/model/holder" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { DistributionNotFoundError } from "@domain/errors/distribution.error" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { AmountType, Distribution, DistributionStatus, DistributionType } from "@domain/model/distribution" +import { ExecuteDistributionResponse } from "@domain/ports/execute-distribution-response.interface" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" + +@Injectable() +export class RetryFailedHoldersDomainService { + constructor( + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + @Inject("HolderRepository") + private readonly holderRepository: HolderRepository, + @Inject("OnChainLifeCycleCashFlowService") + private readonly onChainLifeCycleCashFlowService: LifeCycleCashFlowPort, + @Inject("UpdateBatchPayoutStatusDomainService") + private readonly updateBatchPayoutStatusDomainService: UpdateBatchPayoutStatusDomainService, + ) {} + + async execute(distributionId: string): Promise { + const distribution = await this.distributionRepository.getDistribution(distributionId) + if (!distribution) { + throw new DistributionNotFoundError(distributionId) + } + distribution.verifyStatus(DistributionStatus.FAILED) + + const failedHolders = await this.holderRepository.getHoldersByDistributionIdAndStatus( + distributionId, + HolderStatus.FAILED, + ) + // Group holders by BatchPayout + const groupedByBatchPayout = failedHolders.reduce((group, holder) => { + const batchPayoutId = holder.batchPayout.id + const currentGroup = group[batchPayoutId] ?? [] + return { ...group, [batchPayoutId]: [...currentGroup, holder] } + }, {}) + + const batchPayoutIds = Object.keys(groupedByBatchPayout) + for (const batchPayoutId of batchPayoutIds) { + // Get BatchPayout from first holder as all holders form the same group are related to the same BatchPayout + const batchPayout = groupedByBatchPayout[batchPayoutId][0].batchPayout + const batchPayoutFailedHolders = groupedByBatchPayout[batchPayoutId] + await this.updateHoldersStatusToRetrying(batchPayoutFailedHolders) + const executeDistributionResponse = await this.executeDistribution(batchPayoutFailedHolders, distribution) + await this.updateHoldersAfterExecution(executeDistributionResponse, batchPayoutFailedHolders) + await this.updateBatchPayoutStatusDomainService.execute(batchPayout) + } + } + + private async updateHoldersStatusToRetrying(holders: Holder[]): Promise { + holders.forEach((holder) => holder.retrying()) + await this.holderRepository.saveHolders(holders) + } + + private async executeDistribution( + holders: Holder[], + distribution: Distribution, + ): Promise { + const holderAddresses = holders.map((failedHolder) => failedHolder.holderEvmAddress) + let response: ExecuteDistributionResponse + if (distribution.details.type === DistributionType.CORPORATE_ACTION) { + response = await this.onChainLifeCycleCashFlowService.executeDistributionByAddresses( + distribution.asset.lifeCycleCashFlowHederaAddress, + distribution.asset.hederaTokenAddress, + Number(distribution.details.corporateActionId.value), + holderAddresses, + ) + } else if (distribution.details.amountType === AmountType.FIXED) { + response = await this.onChainLifeCycleCashFlowService.executeAmountSnapshotByAddresses( + distribution.asset.lifeCycleCashFlowHederaAddress, + distribution.asset.hederaTokenAddress, + Number(distribution.details.snapshotId.value), + holderAddresses, + distribution.details.amount, + ) + } else { + response = await this.onChainLifeCycleCashFlowService.executePercentageSnapshotByAddresses( + distribution.asset.lifeCycleCashFlowHederaAddress, + distribution.asset.hederaTokenAddress, + Number(distribution.details.snapshotId.value), + holderAddresses, + distribution.details.amount, + ) + } + return response + } + + private async updateHoldersAfterExecution( + executeDistributionResponse: ExecuteDistributionResponse, + holders: Holder[], + ): Promise { + holders.forEach((holder) => { + const succeededIndex = executeDistributionResponse.succeeded.findIndex( + (holderAddress) => holderAddress.toLowerCase() === holder.holderEvmAddress.toLowerCase(), + ) + if (succeededIndex !== -1) { + holder.succeed(executeDistributionResponse.paidAmount[succeededIndex]) + } else { + holder.failed() + } + }) + await this.holderRepository.saveHolders(holders) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/sync-from-onchain.domain-service.ts b/apps/mass-payout/backend/src/domain/services/sync-from-onchain.domain-service.ts new file mode 100644 index 000000000..6cf2a22e7 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/sync-from-onchain.domain-service.ts @@ -0,0 +1,310 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Inject, Injectable, Logger } from "@nestjs/common" +import { Asset } from "@domain/model/asset" +import { Distribution, CorporateActionDetails } from "@domain/model/distribution" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { + OnChainDistributionData, + OnChainDistributionRepositoryPort, +} from "@domain/ports/on-chain-distribution-repository.port" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" + +@Injectable() +export class SyncFromOnChainDomainService { + private readonly logger = new Logger(SyncFromOnChainDomainService.name) + + constructor( + @Inject("AssetRepository") + private readonly assetRepository: AssetRepository, + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + @Inject("OnChainDistributionRepositoryPort") + private readonly onChainDistributionRepository: OnChainDistributionRepositoryPort, + @Inject("LifeCycleCashFlowPort") + private readonly lifeCycleCashFlowPort: LifeCycleCashFlowPort, + ) {} + + public async execute(): Promise { + this.logger.log("Starting distribution synchronization process") + const assets = await this.assetRepository.getAllSyncEnabledAssets() + this.logger.log(`Found ${assets.length} assets to sync distributions for`) + + for (const asset of assets) { + this.logger.log(`Syncing distributions for asset: ${asset.name} (${asset.hederaTokenAddress})`) + + if (asset.lifeCycleCashFlowHederaAddress) { + const isPaused = await this.lifeCycleCashFlowPort.isPaused(asset.lifeCycleCashFlowHederaAddress) + if (isPaused) { + this.logger.warn(`Contract for asset ${asset.name} is paused, skipping synchronization`) + continue + } + } + + await this.syncDistributionsForAsset(asset) + } + + this.logger.log("Distribution synchronization process completed") + } + + private async syncDistributionsForAsset(asset: Asset): Promise { + this.logger.log(`Fetching on-chain distributions for asset ${asset.hederaTokenAddress}`) + const remoteDistributions = await this.onChainDistributionRepository.getAllDistributionsByAsset(asset) + + this.logger.log(`Found ${remoteDistributions.length} on-chain distributions for asset ${asset.hederaTokenAddress}`) + if (remoteDistributions.length === 0) { + this.logger.log(`No distributions found for asset ${asset.hederaTokenAddress}, skipping sync`) + return + } + + let newDistributions = 0 + let updatedDistributions = 0 + let skippedDistributions = 0 + + await Promise.all( + remoteDistributions.map(async (remote) => { + const corporateActionId = (remote.details as CorporateActionDetails).corporateActionId.value + const existing = await this.distributionRepository.findByCorporateActionId(asset.id, corporateActionId) + + if (!existing) { + this.logger.log(`Creating new distribution for corporate action ${corporateActionId}`) + await this.distributionRepository.saveDistribution(remote) + newDistributions++ + } else if (this.executionDateChanged(existing, remote)) { + this.logger.log(`Updating execution date for corporate action ${corporateActionId}`) + const executionDate = (remote.details as CorporateActionDetails).executionDate + await this.updateExecutionDate(existing, executionDate) + updatedDistributions++ + } else { + this.logger.log(`Distribution for corporate action ${corporateActionId} is up to date, skipping`) + skippedDistributions++ + } + }), + ) + + this.logger.log(`Sync completed for asset ${asset.hederaTokenAddress}: ${newDistributions} new, + ${updatedDistributions} updated, ${skippedDistributions} skipped`) + } + + private executionDateChanged(local: Distribution, remote: Distribution): boolean { + const localDate = (local.details as CorporateActionDetails).executionDate + const remoteDate = (remote.details as CorporateActionDetails).executionDate + return localDate.valueOf() !== remoteDate.valueOf() + } + + private async createDistribution(remote: OnChainDistributionData): Promise { + const asset = await this.assetRepository.getAsset(remote.assetId) + const corporateActionId = CorporateActionId.create(remote.corporateActionID) + const distribution = Distribution.createCorporateAction(asset, corporateActionId, remote.executionDate) + await this.distributionRepository.saveDistribution(distribution) + } + + private async updateExecutionDate(distribution: Distribution, executionDate: Date): Promise { + const updatedDistribution = distribution.updateExecutionDate(executionDate) + await this.distributionRepository.saveDistribution(updatedDistribution) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/transition-batch-payout-to-partially-completed.domain-service.ts b/apps/mass-payout/backend/src/domain/services/transition-batch-payout-to-partially-completed.domain-service.ts new file mode 100644 index 000000000..334d812eb --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/transition-batch-payout-to-partially-completed.domain-service.ts @@ -0,0 +1,246 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout, BatchPayoutStatus } from "@domain/model/batch-payout" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class TransitionBatchPayoutToPartiallyCompletedDomainService { + constructor( + @Inject("BatchPayoutRepository") + private readonly batchPayoutRepository: BatchPayoutRepository, + @Inject("UpdateDistributionStatusDomainService") + private readonly updateDistributionStatusDomainService: UpdateDistributionStatusDomainService, + ) {} + + async execute(batchPayout: BatchPayout): Promise { + if (this.canTransitionToPartiallyCompleted(batchPayout)) { + const updatedBatchPayout = this.setBatchPayoutStatusToPartiallyCompleted(batchPayout) + const savedBatchPayout = await this.batchPayoutRepository.saveBatchPayout(updatedBatchPayout) + await this.updateDistributionStatusDomainService.execute(savedBatchPayout.distribution) + return savedBatchPayout + } + return batchPayout + } + + private canTransitionToPartiallyCompleted(batchPayout: BatchPayout): boolean { + return batchPayout.status !== BatchPayoutStatus.COMPLETED && batchPayout.status !== BatchPayoutStatus.FAILED + } + + private setBatchPayoutStatusToPartiallyCompleted(batchPayout: BatchPayout): BatchPayout { + return BatchPayout.createExisting( + batchPayout.id, + batchPayout.distribution, + batchPayout.name, + batchPayout.hederaTransactionId, + batchPayout.hederaTransactionHash, + batchPayout.holdersNumber, + BatchPayoutStatus.PARTIALLY_COMPLETED, + batchPayout.createdAt, + batchPayout.updatedAt, + ) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/unpause-asset.domain-service.ts b/apps/mass-payout/backend/src/domain/services/unpause-asset.domain-service.ts new file mode 100644 index 000000000..258bc73d7 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/unpause-asset.domain-service.ts @@ -0,0 +1,236 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Inject, Injectable } from "@nestjs/common" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { Asset } from "@domain/model/asset" + +@Injectable() +export class UnpauseAssetDomainService { + constructor( + @Inject("AssetRepository") + private readonly assetRepository: AssetRepository, + @Inject("OnChainLifeCycleCashFlowService") + private readonly onChainLifeCycleCashFlowService: LifeCycleCashFlowPort, + ) {} + + async unpause(assetId: string): Promise { + const asset = await this.assetRepository.getAsset(assetId) + if (!asset) { + throw new Error(`Asset with ID ${assetId} not found`) + } + + if (!asset.isPaused) { + return asset + } + + await this.onChainLifeCycleCashFlowService.unpause(asset.lifeCycleCashFlowHederaAddress) + + const unpausedAsset = asset.unpause() + await this.assetRepository.updateAsset(unpausedAsset) + + return unpausedAsset + } +} diff --git a/apps/mass-payout/backend/src/domain/services/update-asset.domain-service.ts b/apps/mass-payout/backend/src/domain/services/update-asset.domain-service.ts new file mode 100644 index 000000000..49f640ae6 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/update-asset.domain-service.ts @@ -0,0 +1,235 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { Inject, Injectable } from "@nestjs/common" + +import { AssetNameAlreadyExistsError, AssetNotFoundError } from "@domain/errors/asset.error" + +@Injectable() +export class UpdateAssetDomainService { + constructor( + @Inject("AssetRepository") + private readonly assetRepository: AssetRepository, + ) {} + + async updateAsset(id: string, name: string): Promise { + const existingAsset = await this.assetRepository.getAsset(id) + if (!existingAsset) { + throw new AssetNotFoundError(id) + } + + const assetWithSameName = await this.assetRepository.getAssetByName(name) + if (assetWithSameName && assetWithSameName.id !== id) { + throw new AssetNameAlreadyExistsError(name) + } + + const updatedAsset = existingAsset.withName(name) + + await this.assetRepository.updateAsset(updatedAsset) + + return updatedAsset + } +} diff --git a/apps/mass-payout/backend/src/domain/services/update-batch-payout-status.domain-service.ts b/apps/mass-payout/backend/src/domain/services/update-batch-payout-status.domain-service.ts new file mode 100644 index 000000000..82f7c3c67 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/update-batch-payout-status.domain-service.ts @@ -0,0 +1,272 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout, BatchPayoutStatus } from "@domain/model/batch-payout" +import { HolderStatus } from "@domain/model/holder" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { Inject, Injectable } from "@nestjs/common" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" + +@Injectable() +export class UpdateBatchPayoutStatusDomainService { + constructor( + @Inject("BatchPayoutRepository") + private readonly batchPayoutRepository: BatchPayoutRepository, + @Inject("HolderRepository") + private readonly holderRepository: HolderRepository, + @Inject("UpdateDistributionStatusDomainService") + private readonly updateDistributionStatusDomainService: UpdateDistributionStatusDomainService, + ) {} + + async execute(batchPayout: BatchPayout): Promise { + batchPayout = await this.determineStatusFromHolders(batchPayout) + batchPayout = await this.batchPayoutRepository.updateBatchPayout(batchPayout) + await this.updateDistributionStatusDomainService.execute(batchPayout.distribution) + return batchPayout + } + + private async determineStatusFromHolders(batchPayout: BatchPayout): Promise { + const holders = await this.holderRepository.getHoldersByBatchPayout(batchPayout.id) + const hasAnyHolder = holders.some((holder) => holder.status === HolderStatus.FAILED) + + if (hasAnyHolder) { + return this.setBatchPayoutStatusToFailed(batchPayout) + } + + const areAllHoldersSuccessful = holders.every((holder) => holder.status === HolderStatus.SUCCESS) + if (areAllHoldersSuccessful) { + return this.setBatchPayoutStatusToCompleted(batchPayout) + } + return batchPayout + } + + private setBatchPayoutStatusToFailed(batchPayout: BatchPayout): BatchPayout { + return BatchPayout.createExisting( + batchPayout.id, + batchPayout.distribution, + batchPayout.name, + batchPayout.hederaTransactionId, + batchPayout.hederaTransactionHash, + batchPayout.holdersNumber, + BatchPayoutStatus.FAILED, + batchPayout.createdAt, + batchPayout.updatedAt, + ) + } + + private setBatchPayoutStatusToCompleted(batchPayout: BatchPayout): BatchPayout { + return BatchPayout.createExisting( + batchPayout.id, + batchPayout.distribution, + batchPayout.name, + batchPayout.hederaTransactionId, + batchPayout.hederaTransactionHash, + batchPayout.holdersNumber, + BatchPayoutStatus.COMPLETED, + batchPayout.createdAt, + batchPayout.updatedAt, + ) + } +} diff --git a/apps/mass-payout/backend/src/domain/services/update-distribution-status.domain-service.ts b/apps/mass-payout/backend/src/domain/services/update-distribution-status.domain-service.ts new file mode 100644 index 000000000..8224cd559 --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/update-distribution-status.domain-service.ts @@ -0,0 +1,456 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayoutStatus } from "@domain/model/batch-payout" +import { Distribution, DistributionStatus, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { HolderStatus } from "@domain/model/holder" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { Inject, Injectable } from "@nestjs/common" + +@Injectable() +export class UpdateDistributionStatusDomainService { + constructor( + @Inject("DistributionRepository") + private readonly distributionRepository: DistributionRepository, + @Inject("BatchPayoutRepository") + private readonly batchPayoutRepository: BatchPayoutRepository, + @Inject("HolderRepository") + private readonly holderRepository: HolderRepository, + ) {} + + async execute(distribution: Distribution): Promise { + const batchPayouts = await this.batchPayoutRepository.getBatchPayoutsByDistribution(distribution) + if (batchPayouts.length === 0) { + return distribution + } + + const areAllBatchPayoutsCompleted = batchPayouts.every((p) => p.status === BatchPayoutStatus.COMPLETED) + + if (areAllBatchPayoutsCompleted) { + distribution = this.setDistributionStatusToCompleted(distribution) + } else { + const distributionWithUpdatedStatus = await this.determineStatusFromHolders(distribution) + distribution = distributionWithUpdatedStatus + } + return await this.distributionRepository.updateDistribution(distribution) + } + + private async determineStatusFromHolders(distribution: Distribution): Promise { + const holders = await this.holderRepository.getAllHoldersByDistributionId(distribution.id) + const hasAnyHolder = holders.some((holder) => holder.status === HolderStatus.FAILED) + + if (hasAnyHolder) { + return this.setDistributionStatusToFailed(distribution) + } else { + if (distribution.status !== DistributionStatus.IN_PROGRESS) { + return this.setDistributionStatusToInProgress(distribution) + } else { + return distribution + } + } + } + + public setDistributionStatusToInProgress(distribution: Distribution): Distribution { + if (distribution.details.type === DistributionType.CORPORATE_ACTION) { + return Distribution.createExistingCorporateAction( + distribution.id, + distribution.asset, + distribution.details.corporateActionId, + distribution.details.executionDate, + DistributionStatus.IN_PROGRESS, + distribution.createdAt, + new Date(), + ) + } else if (distribution.details.type === DistributionType.PAYOUT) { + if (distribution.details.subtype === PayoutSubtype.IMMEDIATE) { + return Distribution.createExistingImmediate( + distribution.id, + distribution.asset, + distribution.details.snapshotId, + DistributionStatus.IN_PROGRESS, + distribution.createdAt, + new Date(), + distribution.details.amount, + distribution.details.amountType, + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.ONE_OFF) { + return Distribution.createExistingOneOff( + distribution.id, + distribution.asset, + distribution.details.snapshotId, + distribution.details.executeAt, + DistributionStatus.IN_PROGRESS, + distribution.details.amount, + distribution.details.amountType, + distribution.createdAt, + new Date(), + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.RECURRING) { + return Distribution.createExistingRecurring( + distribution.id, + distribution.asset, + distribution.details.executeAt, + distribution.details.recurrency, + distribution.details.amount, + distribution.details.amountType, + distribution.details.snapshotId, + DistributionStatus.IN_PROGRESS, + distribution.createdAt, + new Date(), + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.AUTOMATED) { + return Distribution.createExistingAutomated( + distribution.id, + distribution.asset, + distribution.details.amount, + distribution.details.amountType, + distribution.details.concept, + distribution.details.snapshotId, + DistributionStatus.IN_PROGRESS, + distribution.createdAt, + new Date(), + ) + } + } + } + + private setDistributionStatusToFailed(distribution: Distribution): Distribution { + if (distribution.details.type === DistributionType.CORPORATE_ACTION) { + return Distribution.createExistingCorporateAction( + distribution.id, + distribution.asset, + distribution.details.corporateActionId, + distribution.details.executionDate, + DistributionStatus.FAILED, + distribution.createdAt, + new Date(), + ) + } else if (distribution.details.type === DistributionType.PAYOUT) { + if (distribution.details.subtype === PayoutSubtype.IMMEDIATE) { + return Distribution.createExistingImmediate( + distribution.id, + distribution.asset, + distribution.details.snapshotId, + DistributionStatus.FAILED, + distribution.createdAt, + new Date(), + distribution.details.amount, + distribution.details.amountType, + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.ONE_OFF) { + return Distribution.createExistingOneOff( + distribution.id, + distribution.asset, + distribution.details.snapshotId, + distribution.details.executeAt, + DistributionStatus.FAILED, + distribution.details.amount, + distribution.details.amountType, + distribution.createdAt, + new Date(), + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.RECURRING) { + return Distribution.createExistingRecurring( + distribution.id, + distribution.asset, + distribution.details.executeAt, + distribution.details.recurrency, + distribution.details.amount, + distribution.details.amountType, + distribution.details.snapshotId, + DistributionStatus.FAILED, + distribution.createdAt, + new Date(), + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.AUTOMATED) { + return Distribution.createExistingAutomated( + distribution.id, + distribution.asset, + distribution.details.amount, + distribution.details.amountType, + distribution.details.concept, + distribution.details.snapshotId, + DistributionStatus.FAILED, + distribution.createdAt, + new Date(), + ) + } + } + } + + private setDistributionStatusToCompleted(distribution: Distribution): Distribution { + if (distribution.details.type === DistributionType.CORPORATE_ACTION) { + return Distribution.createExistingCorporateAction( + distribution.id, + distribution.asset, + distribution.details.corporateActionId, + distribution.details.executionDate, + DistributionStatus.COMPLETED, + distribution.createdAt, + new Date(), + ) + } else if (distribution.details.type === DistributionType.PAYOUT) { + if (distribution.details.subtype === PayoutSubtype.IMMEDIATE) { + return Distribution.createExistingImmediate( + distribution.id, + distribution.asset, + distribution.details.snapshotId, + DistributionStatus.COMPLETED, + distribution.createdAt, + new Date(), + distribution.details.amount, + distribution.details.amountType, + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.ONE_OFF) { + return Distribution.createExistingOneOff( + distribution.id, + distribution.asset, + distribution.details.snapshotId, + distribution.details.executeAt, + DistributionStatus.COMPLETED, + distribution.details.amount, + distribution.details.amountType, + distribution.createdAt, + new Date(), + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.RECURRING) { + return Distribution.createExistingRecurring( + distribution.id, + distribution.asset, + distribution.details.executeAt, + distribution.details.recurrency, + distribution.details.amount, + distribution.details.amountType, + distribution.details.snapshotId, + DistributionStatus.COMPLETED, + distribution.createdAt, + new Date(), + distribution.details.concept, + ) + } else if (distribution.details.subtype === PayoutSubtype.AUTOMATED) { + return Distribution.createExistingAutomated( + distribution.id, + distribution.asset, + distribution.details.amount, + distribution.details.amountType, + distribution.details.concept, + distribution.details.snapshotId, + DistributionStatus.COMPLETED, + distribution.createdAt, + new Date(), + ) + } + } + } +} diff --git a/apps/mass-payout/backend/src/domain/services/validate-asset-pause-state.domain-service.ts b/apps/mass-payout/backend/src/domain/services/validate-asset-pause-state.domain-service.ts new file mode 100644 index 000000000..fe3f8686b --- /dev/null +++ b/apps/mass-payout/backend/src/domain/services/validate-asset-pause-state.domain-service.ts @@ -0,0 +1,237 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable, Logger } from "@nestjs/common" +import { Asset } from "@domain/model/asset" +import { AssetPausedError } from "@domain/errors/asset.error" + +@Injectable() +export class ValidateAssetPauseStateDomainService { + private readonly logger = new Logger(ValidateAssetPauseStateDomainService.name) + + /** + * Validates the pause state of an asset using only the domain state. + * This is a simplified version that doesn't check the DLT state for better performance. + * If the asset is paused in the domain, throws AssetPausedError. + * + * @param asset - The asset to validate + * @param distributionId - The distribution ID for logging purposes (optional) + * @throws AssetPausedError if the asset is paused in the domain + */ + async validateDomainPauseState(asset: Asset, distributionId?: string): Promise { + if (asset.isPaused) { + const logMessage = distributionId + ? `Attempted to execute operation for paused asset. Asset: ${asset.name} ` + + `(${asset.hederaTokenAddress}), Distribution ID: ${distributionId}` + : `Attempted to execute operation on paused asset. Asset: ${asset.name} (${asset.hederaTokenAddress})` + + this.logger.error(logMessage) + throw new AssetPausedError(asset.name, asset.hederaTokenAddress) + } + + this.logger.debug( + `Asset pause state validation passed. Asset: ${asset.name} (${asset.hederaTokenAddress}) is not paused.`, + ) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/asset-tokenization-studio-sdk.service.ts b/apps/mass-payout/backend/src/infrastructure/adapters/asset-tokenization-studio-sdk.service.ts new file mode 100644 index 000000000..082572300 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/asset-tokenization-studio-sdk.service.ts @@ -0,0 +1,244 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable } from "@nestjs/common" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" +import { + Bond, + GetBondDetailsRequest, + GetSecurityDetailsRequest, + Security, + TakeSnapshotRequest, +} from "@hashgraph/asset-tokenization-sdk" +import { AssetType } from "@domain/model/asset-type.enum" +import { GetAssetInfoResponse } from "@domain/ports/get-asset-info-response.interface" + +@Injectable() +export class AssetTokenizationStudioSdkService implements AssetTokenizationStudioService { + async getAssetInfo(hederaTokenAddress: string): Promise { + const getInfoRequest = new GetSecurityDetailsRequest({ securityId: hederaTokenAddress }) + const assetInfo = await Security.getInfo(getInfoRequest) + let maturityDate: Date + + if (!assetInfo) return null + + if (assetInfo.type == AssetType.BOND) { + const getBondDetailsRequest = new GetBondDetailsRequest({ bondId: hederaTokenAddress }) + const bondDetails = await Bond.getBondDetails(getBondDetailsRequest) + maturityDate = bondDetails.maturityDate + } + return { + hederaTokenAddress: hederaTokenAddress, + name: assetInfo.name, + symbol: assetInfo.symbol, + assetType: assetInfo.type as AssetType, + maturityDate: maturityDate, + } + } + + async takeSnapshot(hederaTokenId: string): Promise { + const snapshotResponse = await Security.takeSnapshot(new TakeSnapshotRequest({ securityId: hederaTokenId })) + return snapshotResponse.payload + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/blockchain-polling.service.ts b/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/blockchain-polling.service.ts new file mode 100644 index 000000000..af2330656 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/blockchain-polling.service.ts @@ -0,0 +1,66 @@ +import { ProcessBlockchainEventsUseCase } from "@application/use-cases/process-blockchain-events.use-case" +import { ConfigKeys } from "@config/config-keys" +import { BlockchainPollingPort } from "@domain/ports/blockchain-polling.port" +import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from "@nestjs/common" +import { ConfigService } from "@nestjs/config" + +@Injectable() +export class BlockchainPollingService implements OnModuleInit, OnModuleDestroy, BlockchainPollingPort { + private readonly logger = new Logger(BlockchainPollingService.name) + private intervalId: NodeJS.Timeout | null = null + private readonly pollTimeout: number + private readonly isEnabled: boolean = true + + constructor( + private readonly processBlockchainEventsUseCase: ProcessBlockchainEventsUseCase, + private readonly configService: ConfigService, + ) { + this.pollTimeout = configService.get(ConfigKeys.BLOCKCHAIN_LISTENER_POLL_TIMEOUT) + } + + onModuleInit() { + if (this.isEnabled) { + this.start() + } + } + + onModuleDestroy() { + this.stop() + } + + async start(): Promise { + if (this.intervalId || !this.isEnabled) { + return + } + this.logger.log(`Blockchain polling started: (interval: ${this.pollTimeout}ms)`) + await this.executeWithErrorHandling() + this.intervalId = setInterval(async () => { + await this.executeWithErrorHandling() + }, this.pollTimeout) + } + + stop(): void { + if (this.intervalId) { + clearInterval(this.intervalId) + this.intervalId = null + this.logger.log("Blockchain Polling stopped") + } + } + + restart(): void { + this.stop() + this.start() + } + + get isRunning(): boolean { + return this.intervalId !== null + } + + private async executeWithErrorHandling(): Promise { + try { + await this.processBlockchainEventsUseCase.execute() + } catch (error) { + this.logger.error(`Blockchain polling error: ${error.message}`, error.stack) + } + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/listener/abi_ERC20.ts b/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/listener/abi_ERC20.ts new file mode 100644 index 000000000..4ff33cdcf --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/listener/abi_ERC20.ts @@ -0,0 +1,358 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +const abiERC20 = [ + { + inputs: [ + { internalType: "string", name: "name_", type: "string" }, + { internalType: "string", name: "symbol_", type: "string" }, + { internalType: "uint8", name: "decimals_", type: "uint8" }, + { internalType: "uint256", name: "initialBalance_", type: "uint256" }, + { internalType: "address payable", name: "feeReceiver_", type: "address" }, + ], + stateMutability: "payable", + type: "constructor", + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "owner", type: "address" }, + { indexed: true, internalType: "address", name: "spender", type: "address" }, + { indexed: false, internalType: "uint256", name: "value", type: "uint256" }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "from", type: "address" }, + { indexed: true, internalType: "address", name: "to", type: "address" }, + { indexed: false, internalType: "uint256", name: "value", type: "uint256" }, + ], + name: "Transfer", + type: "event", + }, + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "address", name: "spender", type: "address" }, + ], + name: "allowance", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "approve", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "balanceOf", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [ + { + internalType: "uint8", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "subtractedValue", type: "uint256" }, + ], + name: "decreaseAllowance", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "addedValue", type: "uint256" }, + ], + name: "increaseAllowance", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "symbol", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "recipient", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "transfer", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "sender", type: "address" }, + { internalType: "address", name: "recipient", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "transferFrom", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, +] +export default abiERC20 diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/listener/hedera-blockchain-listener.service.ts b/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/listener/hedera-blockchain-listener.service.ts new file mode 100644 index 000000000..681b8fede --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/blockchain/listener/hedera-blockchain-listener.service.ts @@ -0,0 +1,351 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetBlockchainEventListenerConfigUseCase } from "@application/use-cases/get-blockchain-event-listener-config.use-case" +import { UpsertBlockchainEventListenerConfigUseCase } from "@application/use-cases/upsert-blockchain-event-listener-config.use-case" +import { + ApprovalEventData, + BlockchainEvent, + BlockchainEventListenerConfig, + BlockchainEventListenerError, + MirrorNodeLog, + MirrorNodeResponse, + TransferEvent, +} from "@domain/model/blockchain-listener" +import { BlockchainEventListenerService } from "@domain/ports/blockchain-event-listener.service" +import { Injectable, Logger } from "@nestjs/common" +import axios from "axios" +import chalk from "chalk" +import { Interface, LogDescription } from "ethers/lib/utils" +import abiERC20 from "./abi_ERC20" + +@Injectable() +export class HederaBlockchainListenerService implements BlockchainEventListenerService { + private readonly logger = new Logger(HederaBlockchainListenerService.name) + private readonly iface: Interface + private config: BlockchainEventListenerConfig + + constructor( + private readonly getConfigUseCase: GetBlockchainEventListenerConfigUseCase, + private readonly upsertConfigUseCase: UpsertBlockchainEventListenerConfigUseCase, + ) { + this.iface = new Interface(abiERC20) + } + + async fetchNewEvents(): Promise { + try { + this.config = await this.getConfigUseCase.execute() + const logs: MirrorNodeLog[] = await this.retrieveLogsFromMirrorNode( + this.config.mirrorNodeUrl, + this.config.contractId, + this.config.startTimestamp, + ) + const events: BlockchainEvent[] = [] + for (const log of logs) { + const event = this.decodeLog(log) + if (event) { + events.push(event) + } + } + this.logger.debug(`Fetched blockchain events ${events.length}, since: ${this.config.startTimestamp}`) + return events + } catch (error) { + throw new BlockchainEventListenerError("Error listening events", error) + } + } + + async updateStartTimestamp(newStartTimestamp: string): Promise { + this.config = await this.getConfigUseCase.execute() + if (Number(this.config.startTimestamp) >= Number(newStartTimestamp)) return + this.config.startTimestamp = newStartTimestamp + this.logger.verbose(`Updating config: ${chalk.yellow(JSON.stringify(this.config, null, 2))}`) + await this.upsertConfigUseCase.execute(this.config) + } + + private async retrieveLogsFromMirrorNode( + mirrorNodeUrl: string, + contractId: string, + startTimestamp: string, + ): Promise { + try { + const query = startTimestamp ? `?limit=100&order=asc×tamp=gt%3A${startTimestamp.toString()}` : "" + const url = `${mirrorNodeUrl}/api/v1/contracts/${contractId}/results/logs${query}` + this.logger.verbose(`Retrieving logs from Mirror Node: "${url}"`) + const { data }: { data: MirrorNodeResponse } = await axios.get(url) + return data.logs || [] + } catch (error) { + throw new BlockchainEventListenerError("Error extracting Mirror Node Logs", error) + } + } + + private decodeLog(log: MirrorNodeLog): BlockchainEvent | undefined { + try { + if (!log.data || log.data === "0x") { + this.logger.debug("Ignored event: ", log) + return + } + const parsed = this.iface.parseLog({ + data: log.data, + topics: log.topics, + }) + return this.logDecodedEvent(parsed, log.timestamp) + } catch (error) { + throw new BlockchainEventListenerError(`Error decoding log.\n${JSON.stringify(log, null, 2)}`, error) + } + } + + private logDecodedEvent(parsed: LogDescription, timestamp: string): BlockchainEvent | undefined { + const name = parsed.name + const eventData: BlockchainEvent = { + timestamp, + name: name, + } + switch (name) { + case "Transfer": + return this.decodeTransferEvent(parsed, eventData) + case "Approval": + return this.decodeApprovalEvent(parsed, eventData) + default: + return this.decodeDefaultEvent(parsed, eventData) + } + } + + private decodeTransferEvent(parsed: LogDescription, eventData: BlockchainEvent): TransferEvent { + const decoded: TransferEvent = { + ...eventData, + from: parsed.args.from, + to: parsed.args.to, + value: this.formatNumber(parsed.args.value), + rawValue: parsed.args.value.toString(), + } + this.logger.verbose(`Decoded event: ${chalk.green(JSON.stringify(decoded.to, null, 2))}`) + return decoded + } + + private decodeApprovalEvent(parsed: LogDescription, eventData: BlockchainEvent): ApprovalEventData { + return { + ...eventData, + owner: parsed.args.owner, + spender: parsed.args.spender, + value: this.formatNumber(parsed.args.value), + rawValue: parsed.args.value.toString(), + } + } + + private decodeDefaultEvent(parsed: LogDescription, eventData: BlockchainEvent): BlockchainEvent { + return { + ...eventData, + ...Object.fromEntries( + parsed.eventFragment.inputs.map((input, i) => { + const val = parsed.args[i] + return [input.name, typeof val === "object" ? val.toString() : val] + }), + ), + } + } + + private formatNumber(value: bigint): number { + return Number(value.toString()) / 10 ** this.config.tokenDecimals + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/hedera.service.ts b/apps/mass-payout/backend/src/infrastructure/adapters/hedera.service.ts new file mode 100644 index 000000000..6ea30f172 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/hedera.service.ts @@ -0,0 +1,398 @@ +/* + * 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 use, reproduce, modify, distribute, and prepare + * Derivative Works of the Work, and to publicly perform and display the + * Work and such Derivative Works in any medium or format, whether now + * known or hereafter devised, provided that You properly attribute the + * Work in the manner specified by the author or licensor (but not in any + * way that suggests the licensor endorses You or Your use of the Work). + * + * 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, trademark, patent, 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 notice 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 Support. When 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 support. + * + * 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. + */ + +import { Injectable, Logger } from "@nestjs/common" +import { ConfigService } from "@nestjs/config" +import * as crypto from "crypto" +import axios from "axios" +import { HederaService, HederaTransactionHashResponse } from "@domain/ports/hedera.port" +import { AccountId, EvmAddress } from "@hashgraph/sdk" + +/** + * Implementation of Hedera Mirror Node service + * Provides access to transaction data and Hedera hash extraction from Hedera Mirror Node API + */ +interface TransactionMirrorNodeResponse { + transactions?: Array<{ + transaction_hash?: string + nonce?: number + consensus_timestamp?: string + result?: string + }> +} + +interface AccountMirrorNodeResponse { + account: string +} + +@Injectable() +export class HederaServiceImpl implements HederaService { + private readonly logger = new Logger(HederaServiceImpl.name) + private readonly mirrorNodeUrl: string + private readonly maxRetries: number = 3 + + constructor(private readonly configService: ConfigService) { + this.mirrorNodeUrl = + this.configService.get("HEDERA_MIRROR_NODE_URL") || "https://testnet.mirrornode.hedera.com" + } + + /** + * Retrieves the Hedera transaction hash for a parent transaction from Hedera Mirror Node + * Uses robust HTTP client with timeout, retries and proper error handling + */ + async getParentHederaTransactionHash(transactionId: string): Promise { + this.validateTransactionId(transactionId) + + try { + const formattedTransactionId = this.convertTransactionIdFormat(transactionId) + const data: TransactionMirrorNodeResponse = await this.fetchData(`transactions/${formattedTransactionId}`) + + if (data.transactions && Array.isArray(data.transactions)) { + const parentTx = data.transactions.find((tx) => !tx.nonce || tx.nonce === 0) + + if (parentTx?.transaction_hash) { + const hederaTransactionHash = this.convertBase64ToTransactionHash(parentTx.transaction_hash) + this.logger.debug(`Retrieved Hedera hash from Mirror Node: ${hederaTransactionHash}`) + + return { + hederaTransactionHash, + isFromMirrorNode: true, + } + } + } + + this.logger.warn(`No parent transaction found for ${transactionId}, using fallback hash`) + return this.generateFallbackHash(transactionId) + } catch (error) { + this.logger.error(`Error fetching transaction hash from Mirror Node: ${error.message}`, error.stack) + return this.generateFallbackHash(transactionId) + } + } + + async getEvmAddressFromHedera(hederaAddress: string): Promise { + const input = hederaAddress.trim().toLowerCase() + const id = AccountId.fromString(input) + return `0x${id.toSolidityAddress()}` + } + + async getHederaAddressFromEvm(evmAddress: string): Promise { + const input = evmAddress.trim().toLowerCase() + const evmAddressWithPrefix = input.startsWith("0x") ? input : `0x${input}` + if (this.isLongZeroAddress(evmAddressWithPrefix)) { + return AccountId.fromEvmAddress(0, 0, evmAddressWithPrefix).toString() + } + return ((await this.fetchData(`accounts/${evmAddressWithPrefix}`)) as AccountMirrorNodeResponse).account + } + + /** + * Fetches data from Mirror Node with retry logic and timeout + */ + private async fetchData(path: string): Promise { + const url = `${this.mirrorNodeUrl}/api/v1/${path}` + + for (let attempt = 1; attempt <= this.maxRetries; attempt++) { + try { + this.logger.debug(`Fetching data from: ${url} (attempt ${attempt})`) + + const { data } = await axios.get(url) + + this.logger.debug(`Successfully fetched data for ${url}`) + return data + } catch (error) { + const isLastAttempt = attempt === this.maxRetries + + if (error.name === "AbortError") { + this.logger.warn(`Request timeout for ${url} (attempt ${attempt})`) + } else { + this.logger.warn(`Request failed for ${url} (attempt ${attempt}): ${error.message}`) + } + + if (isLastAttempt) { + throw error + } + + const delay = Math.pow(2, attempt - 1) * 1000 + await new Promise((resolve) => setTimeout(resolve, delay)) + } + } + + throw new Error("All retry attempts failed") + } + + /** + * Validates the format of a Hedera transaction ID + */ + private validateTransactionId(transactionId: string): void { + if (!transactionId || typeof transactionId !== "string") { + throw new Error("Transaction ID must be a non-empty string") + } + + const pattern = /^\d+\.\d+\.\d+[@-]\d+[.-]\d+$/ + if (!pattern.test(transactionId)) { + throw new Error(`Invalid transaction ID format: ${transactionId}. Expected format: accountId@seconds.nanoseconds`) + } + } + + /** + * Converts base64 hash to hexadecimal format with 0x prefix + * Returns the full 32-byte (64 hex characters) transaction hash + */ + private convertBase64ToTransactionHash(base64Hash: string): string { + const hex = Buffer.from(base64Hash, "base64").toString("hex") + return `0x${hex}` + } + + /** + * Generates a fallback transaction hash when Mirror Node data is unavailable + */ + private generateFallbackHash(transactionId: string): HederaTransactionHashResponse { + const hederaTransactionHash = this.generateTransactionHash(transactionId) + this.logger.debug(`Generated fallback Hedera transaction hash: ${hederaTransactionHash}`) + + return { + hederaTransactionHash, + isFromMirrorNode: false, + } + } + + /** + * Generates a fallback Hedera transaction hash when Mirror Node data is unavailable. + * Uses SHA-384 algorithm as specified in Hedera documentation for transaction integrity verification. + * @param transactionId - The Hedera transaction ID + * @returns A deterministic hash in the format 0x... + */ + private generateTransactionHash(transactionId: string): string { + // Use SHA-384 as per Hedera documentation for transaction hash computation + const hash = crypto.createHash("sha384").update(transactionId).digest("hex") + return `0x${hash}` + } + + /** + * Converts Hedera transaction ID format from @ to - for Mirror Node API + * Example: 0.0.2665309@1756125372.670066465 -> 0.0.2665309-1756125372-670066465 + */ + private convertTransactionIdFormat(transactionId: string): string { + const parts = transactionId.split("@") + if (parts.length !== 2) { + throw new Error(`Invalid transaction ID format: ${transactionId}`) + } + + const accountId = parts[0] + const timestamp = parts[1] + + const timestampFormatted = timestamp.replace(/\.([^.]+)$/, "-$1") + + return `${accountId}-${timestampFormatted}` + } + + private isLongZeroAddress(address: string) { + const addressBytes = EvmAddress.fromString(address).toBytes() + for (let i = 0; i < 12; i++) { + if (addressBytes[i] != 0) { + return false + } + } + return true + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/life-cycle-cash-flow-sdk.service.ts b/apps/mass-payout/backend/src/infrastructure/adapters/life-cycle-cash-flow-sdk.service.ts new file mode 100644 index 000000000..2ff9c856a --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/life-cycle-cash-flow-sdk.service.ts @@ -0,0 +1,436 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Inject, Injectable } from "@nestjs/common" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { LifeCycleCashFlowAddress } from "@domain/model/life-cycle-cash-flow-address.value-object" +import { + DeployRequest, + ExecuteAmountSnapshotByAddressesRequest, + ExecuteAmountSnapshotRequest, + ExecuteBondCashOutByAddressesRequest, + ExecuteBondCashOutRequest, + ExecuteDistributionByAddressesRequest, + ExecuteDistributionRequest, + ExecutePercentageSnapshotByAddressesRequest, + ExecutePercentageSnapshotRequest, + GetPaymentTokenRequest, + GetPaymentTokenDecimalsRequest, + IsPausedRequest, + LifeCycleCashFlow, + PauseRequest, + UnpauseRequest, +} from "@mass-payout/sdk" +import { ExecuteDistributionResponse } from "@domain/ports/execute-distribution-response.interface" +import { HederaService } from "@domain/ports/hedera.port" + +@Injectable() +export class LifeCycleCashFlowSdkService implements LifeCycleCashFlowPort { + constructor( + private readonly lifeCycleCashFlow: LifeCycleCashFlow, + @Inject("HederaService") + private readonly hederaService: HederaService, + ) {} + + async deployContract(hederaAssetTokenAddress: string, hederaTokenAddress: string): Promise { + console.log( + "[LifeCycleCashFlowService] deployContract called with:", + `\nToken: ${hederaAssetTokenAddress}`, + `\nUSDC: ${hederaTokenAddress}`, + ) + + const response = await this.lifeCycleCashFlow.deploy( + new DeployRequest({ asset: hederaAssetTokenAddress, paymentToken: hederaTokenAddress }), + ) + + const evmLifeCycleCashFlowAddress = response.payload + const hederaLifeCycleCashFlowAddress = await this.hederaService.getHederaAddressFromEvm(evmLifeCycleCashFlowAddress) + + return LifeCycleCashFlowAddress.create(hederaLifeCycleCashFlowAddress, evmLifeCycleCashFlowAddress) + } + + async pause(lifeCycleCashFlowId: string): Promise { + console.log("[LifeCycleCashFlowService] pause called for LifeCycleCashFlowId:", lifeCycleCashFlowId) + return await this.lifeCycleCashFlow.pause(new PauseRequest({ lifeCycleCashFlow: lifeCycleCashFlowId })) + } + + async unpause(lifeCycleCashFlowId: string): Promise { + console.log("[LifeCycleCashFlowService] unpause called for LifeCycleCashFlowId:", lifeCycleCashFlowId) + return await this.lifeCycleCashFlow.unpause(new UnpauseRequest({ lifeCycleCashFlow: lifeCycleCashFlowId })) + } + + async executeDistribution( + lifeCycleCashFlowId: string, + asset: string, + distributionID: number, + pageIndex: number, + pageLength: number, + ): Promise { + console.log("[LifeCycleCashFlowService] execute distribution called for asset:", asset) + const res = await this.lifeCycleCashFlow.executeDistribution( + new ExecuteDistributionRequest({ + lifeCycleCashFlow: lifeCycleCashFlowId, + asset: asset, + pageIndex: pageIndex, + pageLength: pageLength, + distributionId: distributionID, + }), + ) + return res as ExecuteDistributionResponse + } + + async executeDistributionByAddresses( + lifeCycleCashFlowId: string, + asset: string, + distributionID: number, + holders: string[], + ): Promise { + console.log("[LifeCycleCashFlowService] execute distribution by addresses called for asset:", asset) + const res = await this.lifeCycleCashFlow.executeDistributionByAddresses( + new ExecuteDistributionByAddressesRequest({ + lifeCycleCashFlow: lifeCycleCashFlowId, + asset: asset, + holders: holders, + distributionId: distributionID, + }), + ) + return res as ExecuteDistributionResponse + } + + async executeBondCashOut( + lifeCycleCashFlowId: string, + bond: string, + pageIndex: number, + pageLength: number, + ): Promise { + console.log("[LifeCycleCashFlowService] execute bond cash out called for bond:", bond) + const res = await this.lifeCycleCashFlow.executeBondCashOut( + new ExecuteBondCashOutRequest({ + lifeCycleCashFlow: lifeCycleCashFlowId, + bond: bond, + pageIndex: pageIndex, + pageLength: pageLength, + }), + ) + return res.payload + } + + async executeBondCashOutByAddresses(lifeCycleCashFlowId: string, bond: string, holders: string[]): Promise { + console.log("[LifeCycleCashFlowService] execute bond cash out by addresses called for bond:", bond) + const res = await this.lifeCycleCashFlow.executeBondCashOutByAddresses( + new ExecuteBondCashOutByAddressesRequest({ + lifeCycleCashFlow: lifeCycleCashFlowId, + bond: bond, + holders: holders, + }), + ) + return res.payload + } + + async executeAmountSnapshot( + lifeCycleCashFlowId: string, + asset: string, + snapshotId: number, + pageIndex: number, + pageLength: number, + amount: string, + ): Promise { + console.log("[LifeCycleCashFlowService] execute amount snapshot called for bond:", asset) + const res = await this.lifeCycleCashFlow.executeAmountSnapshot( + new ExecuteAmountSnapshotRequest({ + lifeCycleCashFlow: lifeCycleCashFlowId, + asset: asset, + snapshotId: snapshotId, + pageIndex: pageIndex, + pageLength: pageLength, + amount: amount, + }), + ) + return res as ExecuteDistributionResponse + } + + async executeAmountSnapshotByAddresses( + lifeCycleCashFlowId: string, + asset: string, + snapshotId: number, + holders: string[], + amount: string, + ): Promise { + console.log("[LifeCycleCashFlowService] execute amount snapshot by addresses called for bond:", asset) + const res = await this.lifeCycleCashFlow.executeAmountSnapshotByAddresses( + new ExecuteAmountSnapshotByAddressesRequest({ + lifeCycleCashFlow: lifeCycleCashFlowId, + asset: asset, + snapshotId: snapshotId, + holders: holders, + amount: amount, + }), + ) + return res as ExecuteDistributionResponse + } + + async executePercentageSnapshot( + lifeCycleCashFlowId: string, + asset: string, + snapshotId: number, + pageIndex: number, + pageLength: number, + percentage: string, + ): Promise { + console.log("[ChainLifeCycleCashFlowService] execute percentage snapshot called for bond:", asset) + const res = await this.lifeCycleCashFlow.executePercentageSnapshot( + new ExecutePercentageSnapshotRequest({ + lifeCycleCashFlow: lifeCycleCashFlowId, + asset: asset, + snapshotId: snapshotId, + pageIndex: pageIndex, + pageLength: pageLength, + percentage: percentage, + }), + ) + return res as ExecuteDistributionResponse + } + + async executePercentageSnapshotByAddresses( + lifeCycleCashFlowId: string, + asset: string, + snapshotId: number, + holders: string[], + percentage: string, + ): Promise { + console.log("[LifeCycleCashFlowService] execute percentage snapshot by addresses called for bond:", asset) + const res = await this.lifeCycleCashFlow.executePercentageSnapshotByAddresses( + new ExecutePercentageSnapshotByAddressesRequest({ + lifeCycleCashFlow: lifeCycleCashFlowId, + asset: asset, + snapshotId: snapshotId, + holders: holders, + percentage: percentage, + }), + ) + return res as ExecuteDistributionResponse + } + + async isPaused(lifeCycleCashFlowId: string): Promise { + console.log("[LifeCycleCashFlowService] isPaused called for LifeCycleCashFlow:", lifeCycleCashFlowId) + const res = await this.lifeCycleCashFlow.isPaused(new IsPausedRequest({ lifeCycleCashFlow: lifeCycleCashFlowId })) + return res.payload + } + + async getPaymentToken(lifeCycleCashFlowId: string): Promise { + console.log("[LifeCycleCashFlowService] getPaymentToken called for LifeCycleCashFlow:", lifeCycleCashFlowId) + const res = await this.lifeCycleCashFlow.getPaymentToken( + new GetPaymentTokenRequest({ lifeCycleCashFlow: lifeCycleCashFlowId }), + ) + return res.payload + } + + async getPaymentTokenDecimals(lifeCycleCashFlowId: string): Promise { + console.log("[LifeCycleCashFlowService] getPaymentTokenDecimals called for LifeCycleCashFlow:", lifeCycleCashFlowId) + const res = await this.lifeCycleCashFlow.getPaymentTokenDecimals( + new GetPaymentTokenDecimalsRequest({ lifeCycleCashFlow: lifeCycleCashFlowId }), + ) + return res.payload + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/on-chain-distribution.repository.ts b/apps/mass-payout/backend/src/infrastructure/adapters/on-chain-distribution.repository.ts new file mode 100644 index 000000000..3261f6841 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/on-chain-distribution.repository.ts @@ -0,0 +1,314 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { OnChainDistributionRepositoryPort } from "@domain/ports/on-chain-distribution-repository.port" +import { Distribution, DistributionType, CorporateActionDetails, PayoutDetails } from "@domain/model/distribution" +import { AssetType } from "@domain/model/asset-type.enum" +import { Asset } from "@domain/model/asset" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { + Bond, + Equity, + Security, + GetAllCouponsRequest, + GetAllDividendsRequest, + GetTotalCouponHoldersRequest, + GetTotalDividendHoldersRequest, + GetTotalTokenHoldersAtSnapshotRequest, +} from "@hashgraph/asset-tokenization-sdk" + +export class OnChainDistributionRepository implements OnChainDistributionRepositoryPort { + async getAllDistributionsByAsset(asset: Asset): Promise { + switch (asset.type) { + case AssetType.BOND: + return this.getCouponsForAsset(asset) + case AssetType.EQUITY: + return this.getDividendsForAsset(asset) + default: + return [] + } + } + + async getHoldersCountForCorporateActionId(distribution: Distribution): Promise { + if (distribution.details.type !== DistributionType.CORPORATE_ACTION) { + throw new Error(`Distribution ${distribution.id} is not a corporate action distribution`) + } + + const corporateActionDetails = distribution.details as CorporateActionDetails + const corporateActionId = Number(corporateActionDetails.corporateActionId.value) + const tokenId = distribution.asset.hederaTokenAddress + const assetType = distribution.asset.type + + switch (assetType) { + case AssetType.BOND: { + const couponRequest = new GetTotalCouponHoldersRequest({ + securityId: tokenId, + couponId: corporateActionId, + }) + return await Bond.getTotalCouponHolders(couponRequest) + } + + case AssetType.EQUITY: { + const dividendRequest = new GetTotalDividendHoldersRequest({ + securityId: tokenId, + dividendId: corporateActionId, + }) + return await Equity.getTotalDividendHolders(dividendRequest) + } + + default: + throw new Error(`Unsupported asset type: ${assetType} for corporate action ${corporateActionId}`) + } + } + + async getHoldersCountForSnapshotId(distribution: Distribution): Promise { + if (distribution.details.type !== DistributionType.PAYOUT) { + throw new Error(`Distribution ${distribution.id} is not a payout distribution`) + } + + const payoutDetails = distribution.details as PayoutDetails + if (!payoutDetails.snapshotId) { + throw new Error(`SnapshotId is missing for distribution ${distribution.id}`) + } + + const snapshotId = Number(payoutDetails.snapshotId.value) + const tokenId = distribution.asset.hederaTokenAddress + + const request = new GetTotalTokenHoldersAtSnapshotRequest({ + securityId: tokenId, + snapshotId, + }) + return await Security.getTotalTokenHoldersAtSnapshot(request) + } + + private async getCouponsForAsset(asset: Asset): Promise { + const request = new GetAllCouponsRequest({ securityId: asset.hederaTokenAddress }) + const coupons = await Bond.getAllCoupons(request) + const now = new Date() + + const futureCoupons = coupons + .filter((coupon) => coupon.executionDate > now) + .sort((a, b) => a.executionDate.getTime() - b.executionDate.getTime()) + + return futureCoupons.map((coupon) => { + const corporateActionId = CorporateActionId.create(coupon.couponId.toString()) + return Distribution.createCorporateAction(asset, corporateActionId, coupon.executionDate) + }) + } + + private async getDividendsForAsset(asset: Asset): Promise { + const request = new GetAllDividendsRequest({ securityId: asset.hederaTokenAddress }) + const dividends = await Equity.getAllDividends(request) + const now = new Date() + + const futureDividends = dividends + .filter((dividend) => dividend.executionDate > now) + .sort((a, b) => a.executionDate.getTime() - b.executionDate.getTime()) + + return futureDividends.map((dividend) => { + const corporateActionId = CorporateActionId.create(dividend.dividendId.toString()) + return Distribution.createCorporateAction(asset, corporateActionId, dividend.executionDate) + }) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/asset.repository.error.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/asset.repository.error.ts new file mode 100644 index 000000000..4d992a0ba --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/asset.repository.error.ts @@ -0,0 +1,229 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { CustomError } from "@domain/errors/shared/custom.error" +import { Asset } from "@domain/model/asset" + +export class AssetRepositoryError extends CustomError { + static readonly ERRORS = { + SAVE_ASSET: (asset: Asset) => `Error saving asset: ${JSON.stringify(asset)}.`, + DUPLICATED_ASSET: (name: string, hederaTokenAddress: string) => + `Duplicate asset detected – name “${name}” or Hedera address “${hederaTokenAddress}” is already registered.`, + GET_ASSET: (id: string) => `Error getting asset with id: ${id}.`, + GET_ASSET_BY_NAME: (name: string) => `Error getting asset with name: ${name}.`, + GET_ASSET_BY_HEDERA_TOKEN_ADDRESS: (hederaTokenAddress: string) => + `Error getting asset with hederaTokenAddress: ${hederaTokenAddress}.`, + UPDATE_ASSET: (id: string) => `Error updating asset with id: ${JSON.stringify(id)}.`, + GET_ASSETS: () => "Error getting assets", + GET_SYNC_ENABLED_ASSETS: () => "Error getting sync enabled assets", + DELETE_ASSETS: (ids: string[]) => `Error deleting assets with ids: ${JSON.stringify(ids)}.`, + } + + constructor( + message: string, + public originalError?: Error, + ) { + super(message, originalError) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/batch-payout.repository.error.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/batch-payout.repository.error.ts new file mode 100644 index 000000000..849a348e9 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/batch-payout.repository.error.ts @@ -0,0 +1,225 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { CustomError } from "@domain/errors/shared/custom.error" +import { BatchPayout } from "@domain/model/batch-payout" + +export class BatchPayoutRepositoryError extends CustomError { + static readonly ERRORS = { + SAVE_BATCH_PAYOUT: (batchPayout: BatchPayout) => `Error saving batch payout: ${JSON.stringify(batchPayout)}.`, + SAVE_BATCH_PAYOUTS: (batchPayouts: BatchPayout[]) => `Error saving batch payouts: ${JSON.stringify(batchPayouts)}.`, + GET_BATCH_PAYOUT: (id: string) => `Error getting batch payout with id: ${id}.`, + GET_BATCH_PAYOUTS_BY_DISTRIBUTION: (distributionId: string) => + `Error getting batch payouts for distribution with id: ${distributionId}.`, + UPDATE_BATCH_PAYOUT: (batchPayout: BatchPayout) => `Error updating batch payout: ${JSON.stringify(batchPayout)}.`, + } + + constructor( + message: string, + public originalError?: Error, + ) { + super(message) + this.name = BatchPayoutRepositoryError.name + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/distribution.repository.error.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/distribution.repository.error.ts new file mode 100644 index 000000000..b80d1445f --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/distribution.repository.error.ts @@ -0,0 +1,229 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { CustomError } from "@domain/errors/shared/custom.error" +import { Distribution } from "@domain/model/distribution" + +export class DistributionRepositoryError extends CustomError { + static readonly ERRORS = { + SAVE_DISTRIBUTION: (distribution: Distribution) => `Error saving distribution: ${JSON.stringify(distribution)}.`, + GET_DISTRIBUTION: (id: string) => `Error getting distribution with id: ${id}.`, + GET_DISTRIBUTIONS_BY_ASSET: (assetId: string) => `Error getting distributions for asset with id: ${assetId}.`, + GET_DISTRIBUTION_BY_CORP_ACTION: (assetId: string, corporateActionId: string) => + `Error getting distribution for asset ${assetId} and corporate action id: ${corporateActionId}.`, + GET_DISTRIBUTIONS_BY_EXECUTION_DATE: (startDate: Date, endDate: Date) => + `Error getting distributions by execution date range: ${startDate.toISOString()} to ${endDate.toISOString()}.`, + UPDATE_DISTRIBUTION: (distribution: Distribution) => + `Error updating distribution: ${JSON.stringify(distribution)}.`, + GET_DISTRIBUTIONS: () => "Error getting distributions.", + } + + constructor( + message: string, + public originalError?: Error, + ) { + super(message) + this.name = DistributionRepositoryError.name + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/holder.repository.error.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/holder.repository.error.ts new file mode 100644 index 000000000..a7bdfa398 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/errors/holder.repository.error.ts @@ -0,0 +1,230 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { CustomError } from "@domain/errors/shared/custom.error" +import { Holder, HolderStatus } from "@domain/model/holder" + +export class HolderRepositoryError extends CustomError { + static readonly ERRORS = { + SAVE_HOLDER: (holder: Holder) => `Error saving holder: ${JSON.stringify(holder)}.`, + SAVE_HOLDERS: (holders: Holder[]) => `Error saving holders: ${JSON.stringify(holders)}.`, + UPDATE_HOLDER: (holder: Holder) => `Error updating holder: ${JSON.stringify(holder)}.`, + GET_HOLDERS_BY_BATCH_PAYOUT: (batchPayoutId: string) => + `Error getting holders for batch payout with id: ${batchPayoutId}.`, + GET_HOLDERS_BY_DISTRIBUTION: (distributionId: string) => + `Error getting holders for distribution with id: ${distributionId}.`, + GET_HOLDER_COUNT_BY_DISTRIBUTION: (distributionId: string) => + `Error getting holder count for distribution with id: ${distributionId}.`, + GET_HOLDERS_BY_DISTRIBUTION_AND_STATUS: (distributionId: string, status: HolderStatus) => + `Error getting holders for distribution with id: ${distributionId} and status: ${status}.`, + } + + constructor( + message: string, + public originalError?: Error, + ) { + super(message) + this.name = HolderRepositoryError.name + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/asset.persistence.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/asset.persistence.ts new file mode 100644 index 000000000..20e114590 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/asset.persistence.ts @@ -0,0 +1,274 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { BaseEntityPersistence } from "@infrastructure/adapters/repositories/model/base-entity.persistence" +import { Column, Entity } from "typeorm" + +@Entity("Asset") +export class AssetPersistence extends BaseEntityPersistence { + @Column({ nullable: false, unique: true }) + name: string + + @Column({ nullable: false }) + type: string + + @Column({ nullable: false, unique: true }) + hederaTokenAddress: string + + @Column({ nullable: false }) + evmTokenAddress: string + + @Column({ nullable: false }) + symbol: string + + @Column({ nullable: true }) + maturityDate: Date + + @Column({ nullable: true }) + lifeCycleCashFlowHederaAddress: string + + @Column({ nullable: true }) + lifeCycleCashFlowEvmAddress: string + + @Column({ nullable: false, default: false }) + isPaused: boolean + + @Column({ nullable: false, default: true }) + syncEnabled: boolean + + static fromAsset(asset: Asset): AssetPersistence { + const entityPersistence: AssetPersistence = BaseEntityPersistence.fromEntity(asset, new AssetPersistence()) + entityPersistence.name = asset.name + entityPersistence.type = asset.type + entityPersistence.hederaTokenAddress = asset.hederaTokenAddress + entityPersistence.evmTokenAddress = asset.evmTokenAddress + entityPersistence.symbol = asset.symbol + entityPersistence.maturityDate = asset.maturityDate + entityPersistence.lifeCycleCashFlowHederaAddress = asset.lifeCycleCashFlowHederaAddress + entityPersistence.lifeCycleCashFlowEvmAddress = asset.lifeCycleCashFlowEvmAddress + entityPersistence.isPaused = asset.isPaused + entityPersistence.syncEnabled = asset.syncEnabled + return entityPersistence + } + + toAsset(): Asset { + return Asset.createExisting( + this.id, + this.name, + this.type as AssetType, + this.hederaTokenAddress, + this.evmTokenAddress, + this.symbol, + this.maturityDate || undefined, + this.lifeCycleCashFlowHederaAddress || undefined, + this.lifeCycleCashFlowEvmAddress || undefined, + this.isPaused, + this.syncEnabled, + this.createdAt, + this.updatedAt, + ) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/base-entity.persistence.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/base-entity.persistence.ts new file mode 100644 index 000000000..479b3bc11 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/base-entity.persistence.ts @@ -0,0 +1,224 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Column, CreateDateColumn, UpdateDateColumn } from "typeorm" +import { BaseEntity } from "@domain/model/base-entity" + +export class BaseEntityPersistence { + @Column({ type: "uuid", primary: true }) + id: string + + @CreateDateColumn() + createdAt: Date + + @UpdateDateColumn() + updatedAt: Date + + static fromEntity(entity: T, entityPersistence: P): P { + entityPersistence.id = entity.id + entityPersistence.createdAt = entity.createdAt + entityPersistence.updatedAt = entity.updatedAt + return entityPersistence + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/batch-payout.persistence.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/batch-payout.persistence.ts new file mode 100644 index 000000000..7a232ac1f --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/batch-payout.persistence.ts @@ -0,0 +1,272 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout } from "@domain/model/batch-payout" +import { BaseEntityPersistence } from "@infrastructure/adapters/repositories/model/base-entity.persistence" +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" + +export enum BatchPayoutStatus { + IN_PROGRESS = "IN_PROGRESS", + PARTIALLY_COMPLETED = "PARTIALLY_COMPLETED", + FAILED = "FAILED", + COMPLETED = "COMPLETED", +} + +@Entity("BatchPayout") +export class BatchPayoutPersistence extends BaseEntityPersistence { + @Column({ nullable: false }) + name: string + + @Column({ name: "distribution_id", type: "uuid" }) + distributionId: string + + @ManyToOne(() => DistributionPersistence, { onDelete: "CASCADE", nullable: false }) + @JoinColumn({ name: "distribution_id" }) + distribution: DistributionPersistence + + @Column({ nullable: false }) + hederaTransactionId: string + + @Column({ nullable: false }) + hederaTransactionHash: string + + @Column({ nullable: true }) + holdersNumber?: number + + @Column({ type: "enum", enum: BatchPayoutStatus, nullable: false }) + status: BatchPayoutStatus + + static fromBatchPayout(batchPayout: BatchPayout): BatchPayoutPersistence { + const entityPersistence: BatchPayoutPersistence = BaseEntityPersistence.fromEntity( + batchPayout, + new BatchPayoutPersistence(), + ) + entityPersistence.id = batchPayout.id + entityPersistence.name = batchPayout.name + entityPersistence.distributionId = batchPayout.distribution.id + entityPersistence.distribution = DistributionPersistence.fromDistribution(batchPayout.distribution) + entityPersistence.hederaTransactionId = batchPayout.hederaTransactionId + entityPersistence.hederaTransactionHash = batchPayout.hederaTransactionHash + entityPersistence.holdersNumber = batchPayout.holdersNumber + entityPersistence.status = batchPayout.status + entityPersistence.createdAt = batchPayout.createdAt + entityPersistence.updatedAt = batchPayout.updatedAt + return entityPersistence + } + + toBatchPayout(): BatchPayout { + return BatchPayout.createExisting( + this.id, + this.distribution.toDistribution(), + this.name, + this.hederaTransactionId, + this.hederaTransactionHash, + this.holdersNumber, + this.status, + this.createdAt, + this.updatedAt, + ) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/blockchain-event-listener-config.persistence.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/blockchain-event-listener-config.persistence.ts new file mode 100644 index 000000000..007686453 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/blockchain-event-listener-config.persistence.ts @@ -0,0 +1,245 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BlockchainEventListenerConfig } from "@domain/model/blockchain-listener" +import { BaseEntityPersistence } from "@infrastructure/adapters/repositories/model/base-entity.persistence" +import { Column, Entity, PrimaryGeneratedColumn } from "typeorm" + +@Entity("BlockchainEventListenerConfig") +export class BlockchainEventListenerConfigPersistence extends BaseEntityPersistence { + @PrimaryGeneratedColumn("uuid") + id: string + + @Column({ nullable: false }) + startTimestamp: string + + @Column({ nullable: false }) + mirrorNodeUrl: string + + @Column({ nullable: false }) + contractId: string + + @Column({ nullable: false }) + tokenDecimals: number + + toDomain(): BlockchainEventListenerConfig { + const config = new BlockchainEventListenerConfig() + config.id = this.id + config.startTimestamp = this.startTimestamp + config.mirrorNodeUrl = this.mirrorNodeUrl + config.contractId = this.contractId + config.tokenDecimals = this.tokenDecimals + return config + } + + static fromDomain(config: BlockchainEventListenerConfig): BlockchainEventListenerConfigPersistence { + const entity = new BlockchainEventListenerConfigPersistence() + entity.id = config.id || crypto.randomUUID() + entity.startTimestamp = config.startTimestamp.toString() + entity.mirrorNodeUrl = config.mirrorNodeUrl + entity.contractId = config.contractId + entity.tokenDecimals = config.tokenDecimals + return entity + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/distribution.persistence.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/distribution.persistence.ts new file mode 100644 index 000000000..4bc3a5f1c --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/distribution.persistence.ts @@ -0,0 +1,356 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { + AmountType, + Distribution, + DistributionStatus, + DistributionType, + PayoutSubtype, + Recurrency, +} from "@domain/model/distribution" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm" +import { BaseEntityPersistence } from "./base-entity.persistence" + +@Entity("Distribution") +export class DistributionPersistence extends BaseEntityPersistence { + @Column({ name: "asset_id", type: "uuid" }) + assetId: string + + @ManyToOne(() => AssetPersistence, { onDelete: "CASCADE", nullable: false }) + @JoinColumn({ name: "asset_id" }) + asset: AssetPersistence + + @Column({ nullable: true }) + corporateActionID?: string + + @Column({ nullable: true }) + snapshotId?: string + + @Column({ nullable: true }) + amount?: string + + @Column({ type: "enum", enum: AmountType, nullable: true }) + amountType?: AmountType + + @Column({ type: "timestamp with time zone", nullable: true }) + executionDate?: Date + + @Column({ type: "enum", enum: Recurrency, nullable: true }) + recurrency?: Recurrency + + @Column({ type: "enum", enum: DistributionType, nullable: false }) + type: DistributionType + + @Column({ type: "enum", enum: PayoutSubtype, nullable: true }) + subtype?: PayoutSubtype + + @Column({ type: "enum", enum: DistributionStatus, nullable: false }) + status: DistributionStatus + + @Column({ nullable: true }) + concept?: string + + static fromDistribution(distribution: Distribution): DistributionPersistence { + const persistence = new DistributionPersistence() + persistence.id = distribution.id + persistence.assetId = distribution.asset.id + persistence.asset = AssetPersistence.fromAsset(distribution.asset) + persistence.type = distribution.details.type + persistence.status = distribution.status + persistence.createdAt = distribution.createdAt + persistence.updatedAt = distribution.updatedAt + + if (distribution.details.type === DistributionType.CORPORATE_ACTION) { + persistence.corporateActionID = distribution.details.corporateActionId.value + persistence.executionDate = distribution.details.executionDate + } else if (distribution.details.type === DistributionType.PAYOUT) { + persistence.subtype = distribution.details.subtype + persistence.snapshotId = distribution.details.snapshotId?.value + persistence.amount = distribution.details.amount + persistence.amountType = distribution.details.amountType + persistence.concept = distribution.details.concept + if (distribution.details.subtype === PayoutSubtype.ONE_OFF) { + persistence.executionDate = distribution.details.executeAt + } else if (distribution.details.subtype === PayoutSubtype.RECURRING) { + persistence.executionDate = distribution.details.executeAt + persistence.recurrency = distribution.details.recurrency + } + } + + return persistence + } + + toDistribution(): Distribution { + if (this.type === DistributionType.CORPORATE_ACTION) { + return Distribution.createExistingCorporateAction( + this.id, + this.asset.toAsset(), + CorporateActionId.create(this.corporateActionID), + this.executionDate, + this.status, + this.createdAt, + this.updatedAt, + ) + } else if (this.type === DistributionType.PAYOUT) { + if (this.subtype === PayoutSubtype.IMMEDIATE) { + return Distribution.createExistingImmediate( + this.id, + this.asset.toAsset(), + this.snapshotId ? SnapshotId.create(this.snapshotId) : null, + this.status, + this.createdAt, + this.updatedAt, + this.amount, + this.amountType, + this.concept, + ) + } else if (this.subtype === PayoutSubtype.ONE_OFF) { + return Distribution.createExistingOneOff( + this.id, + this.asset.toAsset(), + this.snapshotId ? SnapshotId.create(this.snapshotId) : null, + this.executionDate, + this.status, + this.amount, + this.amountType, + this.createdAt, + this.updatedAt, + this.concept, + ) + } else if (this.subtype === PayoutSubtype.RECURRING) { + return Distribution.createExistingRecurring( + this.id, + this.asset.toAsset(), + this.executionDate, + this.recurrency, + this.amount, + this.amountType, + this.snapshotId ? SnapshotId.create(this.snapshotId) : null, + this.status, + this.createdAt, + this.updatedAt, + this.concept, + ) + } else if (this.subtype === PayoutSubtype.AUTOMATED) { + return Distribution.createExistingAutomated( + this.id, + this.asset.toAsset(), + this.amount, + this.amountType, + this.concept ? this.concept : null, + this.snapshotId ? SnapshotId.create(this.snapshotId) : null, + this.status, + this.createdAt, + this.updatedAt, + ) + } + } + + throw new Error("Invalid distribution type or subtype") + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/holder.persistence.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/holder.persistence.ts new file mode 100644 index 000000000..1b97398f4 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/model/holder.persistence.ts @@ -0,0 +1,269 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Holder, HolderStatus } from "@domain/model/holder" +import { BaseEntityPersistence } from "@infrastructure/adapters/repositories/model/base-entity.persistence" +import { Column, Entity, JoinColumn, ManyToOne } from "typeorm" +import { BatchPayoutPersistence } from "@infrastructure/adapters/repositories/model/batch-payout.persistence" + +@Entity("Holder") +export class HolderPersistence extends BaseEntityPersistence { + @Column({ name: "batch_payout_id", type: "uuid" }) + batchPayoutId: string + + @ManyToOne(() => BatchPayoutPersistence, { onDelete: "CASCADE", nullable: false }) + @JoinColumn({ name: "batch_payout_id" }) + batchPayout: BatchPayoutPersistence + + @Column({ nullable: false }) + holderHederaAddress: string + + @Column({ nullable: false }) + holderEvmAddress: string + + @Column({ nullable: false }) + retryCounter: number + + @Column({ type: "enum", enum: HolderStatus, nullable: false }) + status: HolderStatus + + @Column({ nullable: true }) + lastError: string + + @Column({ nullable: true }) + nextRetryAt: Date + + @Column({ nullable: true }) + amount: string + + static fromHolder(holder: Holder): HolderPersistence { + const entityPersistence: HolderPersistence = BaseEntityPersistence.fromEntity(holder, new HolderPersistence()) + entityPersistence.batchPayoutId = holder.batchPayout.id + entityPersistence.batchPayout = BatchPayoutPersistence.fromBatchPayout(holder.batchPayout) + entityPersistence.holderHederaAddress = holder.holderHederaAddress + entityPersistence.holderEvmAddress = holder.holderEvmAddress + entityPersistence.retryCounter = holder.retryCounter + entityPersistence.status = holder.status + entityPersistence.lastError = holder.lastError ?? null + entityPersistence.nextRetryAt = holder.nextRetryAt + entityPersistence.amount = holder.amount + return entityPersistence + } + + toHolder(): Holder { + return Holder.createExisting( + this.id, + this.batchPayout.toBatchPayout(), + this.holderHederaAddress, + this.holderEvmAddress, + this.retryCounter, + this.status, + this.nextRetryAt, + this.lastError ?? undefined, + this.amount, + this.createdAt, + this.updatedAt, + ) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-asset.repository.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-asset.repository.ts new file mode 100644 index 000000000..21d2615a0 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-asset.repository.ts @@ -0,0 +1,341 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { Page, PageOptions } from "@domain/model/page" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { AssetRepositoryError } from "@infrastructure/adapters/repositories/errors/asset.repository.error" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { Injectable } from "@nestjs/common" +import { InjectRepository } from "@nestjs/typeorm" +import { FindOptionsOrder, Repository } from "typeorm" + +// https://www.postgresql.org/docs/current/errcodes-appendix.html +export const PG_SQLSTATE_UNIQUE_VIOLATION = "23505" + +@Injectable() +export class AssetTypeOrmRepository implements AssetRepository { + constructor( + @InjectRepository(AssetPersistence) + private readonly assetRepository: Repository, + ) {} + + async saveAsset(item: Asset): Promise { + const assetPersistence = AssetPersistence.fromAsset(item) + try { + await this.assetRepository.insert(assetPersistence) + } catch (error) { + if (error.code === PG_SQLSTATE_UNIQUE_VIOLATION) { + throw new AssetRepositoryError( + AssetRepositoryError.ERRORS.DUPLICATED_ASSET(item.name, item.hederaTokenAddress), + error, + ) + } + throw new AssetRepositoryError(AssetRepositoryError.ERRORS.SAVE_ASSET(item), error) + } + return assetPersistence.toAsset() + } + + async updateAsset(item: Asset): Promise { + const assetPersistence = AssetPersistence.fromAsset(item) + try { + await this.assetRepository.update(assetPersistence.id, assetPersistence) + } catch (error) { + throw new AssetRepositoryError(AssetRepositoryError.ERRORS.UPDATE_ASSET(item.id), error) + } + return assetPersistence.toAsset() + } + + async getAsset(id: string): Promise { + let assetPersistence: AssetPersistence + try { + assetPersistence = await this.assetRepository.findOne({ + where: { id }, + }) + } catch (error) { + throw new AssetRepositoryError(AssetRepositoryError.ERRORS.GET_ASSET(id), error) + } + return assetPersistence ? assetPersistence.toAsset() : undefined + } + + async getAssetByName(name: string): Promise { + let assetPersistence: AssetPersistence + try { + assetPersistence = await this.assetRepository.findOne({ + where: { name }, + }) + } catch (error) { + throw new AssetRepositoryError(AssetRepositoryError.ERRORS.GET_ASSET_BY_NAME(name), error) + } + return assetPersistence ? assetPersistence.toAsset() : undefined + } + + async getAssetByHederaTokenAddress(hederaTokenAddress: string): Promise { + let assetPersistence: AssetPersistence + try { + assetPersistence = await this.assetRepository.findOne({ + where: { hederaTokenAddress }, + }) + } catch (error) { + throw new AssetRepositoryError( + AssetRepositoryError.ERRORS.GET_ASSET_BY_HEDERA_TOKEN_ADDRESS(hederaTokenAddress), + error, + ) + } + return assetPersistence ? assetPersistence.toAsset() : undefined + } + + async deleteAssets(ids: string[]): Promise { + try { + await this.assetRepository.delete(ids) + } catch (error) { + throw new AssetRepositoryError(AssetRepositoryError.ERRORS.DELETE_ASSETS(ids), error) + } + } + + getAllAssets(): Promise { + try { + return this.assetRepository.find().then((assets) => assets.map((asset) => asset.toAsset())) + } catch (error) { + throw new AssetRepositoryError(AssetRepositoryError.ERRORS.GET_ASSETS(), error) + } + } + + getAllSyncEnabledAssets(): Promise { + try { + return this.assetRepository + .find({ + where: { syncEnabled: true }, + }) + .then((assets) => assets.map((asset) => asset.toAsset())) + } catch (error) { + throw new AssetRepositoryError(AssetRepositoryError.ERRORS.GET_SYNC_ENABLED_ASSETS(), error) + } + } + + async getAssets(pageOptions: PageOptions): Promise> { + try { + const skip = (pageOptions.page - 1) * pageOptions.limit + const take = pageOptions.limit + const order: FindOptionsOrder = { + [pageOptions.order?.orderBy || "createdAt"]: pageOptions.order?.order || "DESC", + } + const [assetPersistenceList, total] = await this.assetRepository.findAndCount({ + skip, + take, + order, + }) + const assets = assetPersistenceList.map((assetPersistence) => assetPersistence.toAsset()) + return { + items: assets, + total, + page: pageOptions.page, + limit: pageOptions.limit, + totalPages: Math.ceil(total / pageOptions.limit), + } + } catch (error) { + throw new AssetRepositoryError(AssetRepositoryError.ERRORS.GET_ASSETS(), error) + } + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-batch-payout.repository.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-batch-payout.repository.ts new file mode 100644 index 000000000..9adeb68fc --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-batch-payout.repository.ts @@ -0,0 +1,282 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout } from "@domain/model/batch-payout" +import { Distribution } from "@domain/model/distribution" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { BatchPayoutPersistence } from "@infrastructure/adapters/repositories/model/batch-payout.persistence" +import { BatchPayoutRepositoryError } from "@infrastructure/adapters/repositories/errors/batch-payout.repository.error" +import { Injectable } from "@nestjs/common" +import { InjectRepository } from "@nestjs/typeorm" +import { Repository } from "typeorm" + +@Injectable() +export class BatchPayoutTypeOrmRepository implements BatchPayoutRepository { + constructor( + @InjectRepository(BatchPayoutPersistence) + private readonly batchPayoutRepository: Repository, + ) {} + + async saveBatchPayout(item: BatchPayout): Promise { + try { + const batchPayoutPersistence = BatchPayoutPersistence.fromBatchPayout(item) + batchPayoutPersistence.createdAt = undefined + batchPayoutPersistence.updatedAt = undefined + const result = await this.batchPayoutRepository.insert(batchPayoutPersistence) + batchPayoutPersistence.createdAt = result.generatedMaps[0].createdAt + batchPayoutPersistence.updatedAt = result.generatedMaps[0].updatedAt + return batchPayoutPersistence.toBatchPayout() + } catch (error) { + throw new BatchPayoutRepositoryError(BatchPayoutRepositoryError.ERRORS.SAVE_BATCH_PAYOUT(item), error) + } + } + + async saveBatchPayouts(items: BatchPayout[]): Promise { + try { + const batchPayoutPersistenceList = items.map((item) => BatchPayoutPersistence.fromBatchPayout(item)) + await this.batchPayoutRepository.insert(batchPayoutPersistenceList) + return batchPayoutPersistenceList.map((batchPayoutPersistence) => batchPayoutPersistence.toBatchPayout()) + } catch (error) { + throw new BatchPayoutRepositoryError(BatchPayoutRepositoryError.ERRORS.SAVE_BATCH_PAYOUTS(items), error) + } + } + + async getBatchPayout(id: string): Promise { + try { + const batchPayoutPersistence = await this.batchPayoutRepository.findOne({ + where: { id }, + relations: ["distribution", "distribution.asset"], + }) + return batchPayoutPersistence ? batchPayoutPersistence.toBatchPayout() : undefined + } catch (error) { + throw new BatchPayoutRepositoryError(BatchPayoutRepositoryError.ERRORS.GET_BATCH_PAYOUT(id), error) + } + } + + async getBatchPayoutsByDistribution(distribution: Distribution): Promise { + try { + const batchPayoutPersistenceList = await this.batchPayoutRepository.find({ + where: { distributionId: distribution.id }, + relations: ["distribution", "distribution.asset"], + }) + return batchPayoutPersistenceList.map((batchPayoutPersistence) => batchPayoutPersistence.toBatchPayout()) + } catch (error) { + throw new BatchPayoutRepositoryError( + BatchPayoutRepositoryError.ERRORS.GET_BATCH_PAYOUTS_BY_DISTRIBUTION(distribution.id), + error, + ) + } + } + + async updateBatchPayout(item: BatchPayout): Promise { + try { + let batchPayoutPersistence = BatchPayoutPersistence.fromBatchPayout(item) + batchPayoutPersistence.updatedAt = new Date() + batchPayoutPersistence = await this.batchPayoutRepository.save(batchPayoutPersistence) + return batchPayoutPersistence.toBatchPayout() + } catch (error) { + throw new BatchPayoutRepositoryError(BatchPayoutRepositoryError.ERRORS.UPDATE_BATCH_PAYOUT(item), error) + } + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-blockchain-event-listener-config.repository.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-blockchain-event-listener-config.repository.ts new file mode 100644 index 000000000..2f3ec1fee --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-blockchain-event-listener-config.repository.ts @@ -0,0 +1,235 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BlockchainEventListenerConfig } from "@domain/model/blockchain-listener" +import { BlockchainEventListenerConfigRepository } from "@domain/ports/blockchain-event-config-repository.port" +import { BlockchainEventListenerConfigPersistence } from "@infrastructure/adapters/repositories/model/blockchain-event-listener-config.persistence" +import { Injectable } from "@nestjs/common" +import { InjectRepository } from "@nestjs/typeorm" +import { Repository } from "typeorm" + +@Injectable() +export class BlockchainEventListenerConfigTypeOrmRepository implements BlockchainEventListenerConfigRepository { + constructor( + @InjectRepository(BlockchainEventListenerConfigPersistence) + private readonly repository: Repository, + ) {} + + async save(item: BlockchainEventListenerConfig): Promise { + const persistenceEntity = BlockchainEventListenerConfigPersistence.fromDomain(item) + const savedEntity = await this.repository.save(persistenceEntity) + return savedEntity.toDomain() + } + + async update(item: BlockchainEventListenerConfig): Promise { + const persistenceEntity = BlockchainEventListenerConfigPersistence.fromDomain(item) + const updatedEntity = await this.repository.save(persistenceEntity) + return updatedEntity.toDomain() + } + + async getConfig(): Promise { + const entity = await this.repository.findOne({ where: {}, order: { id: "ASC" } }) + return entity ? entity.toDomain() : undefined + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-distribution.repository.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-distribution.repository.ts new file mode 100644 index 000000000..f404a8277 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-distribution.repository.ts @@ -0,0 +1,375 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Distribution, DistributionStatus, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { Page, PageOptions } from "@domain/model/page" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { DistributionRepositoryError } from "@infrastructure/adapters/repositories/errors/distribution.repository.error" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { Injectable } from "@nestjs/common" +import { InjectRepository } from "@nestjs/typeorm" +import { Between, FindOptionsOrder, Repository } from "typeorm" + +@Injectable() +export class DistributionTypeOrmRepository implements DistributionRepository { + constructor( + @InjectRepository(DistributionPersistence) + private readonly distributionRepository: Repository, + ) {} + + async saveDistribution(distribution: Distribution): Promise { + try { + const distributionPersistence = DistributionPersistence.fromDistribution(distribution) + const savedPersistence = await this.distributionRepository.save(distributionPersistence) + return savedPersistence.toDistribution() + } catch (error) { + throw new DistributionRepositoryError(DistributionRepositoryError.ERRORS.SAVE_DISTRIBUTION(distribution), error) + } + } + + async getDistribution(id: string): Promise { + try { + const distributionPersistence = await this.distributionRepository.findOne({ + where: { id }, + relations: ["asset"], + }) + return distributionPersistence ? distributionPersistence.toDistribution() : null + } catch (error) { + throw new DistributionRepositoryError(DistributionRepositoryError.ERRORS.GET_DISTRIBUTION(id), error) + } + } + + async getAllDistributionsByAssetId(assetId: string): Promise { + try { + const distributionPersistences = await this.distributionRepository.find({ + where: { assetId }, + relations: ["asset"], + }) + return distributionPersistences.map((p) => p.toDistribution()) + } catch (error) { + throw new DistributionRepositoryError( + DistributionRepositoryError.ERRORS.GET_DISTRIBUTIONS_BY_ASSET(assetId), + error, + ) + } + } + + async findByCorporateActionId(assetId: string, corporateActionId: string): Promise { + try { + const distributionPersistence = await this.distributionRepository.findOne({ + where: { + corporateActionID: corporateActionId, + assetId: assetId, + }, + relations: ["asset"], + }) + return distributionPersistence ? distributionPersistence.toDistribution() : null + } catch (error) { + throw new DistributionRepositoryError( + DistributionRepositoryError.ERRORS.GET_DISTRIBUTION_BY_CORP_ACTION(assetId, corporateActionId), + error, + ) + } + } + + async findByExecutionDateRange(startDate: Date, endDate: Date, status?: DistributionStatus): Promise { + try { + const where: any = { executionDate: Between(startDate, endDate), status } + + const persistences = await this.distributionRepository.find({ + where, + relations: ["asset"], + }) + return persistences.map((p) => p.toDistribution()) + } catch (error) { + throw new DistributionRepositoryError( + DistributionRepositoryError.ERRORS.GET_DISTRIBUTIONS_BY_EXECUTION_DATE(startDate, endDate), + error, + ) + } + } + + async updateDistribution(distribution: Distribution): Promise { + try { + const distributionPersistence = DistributionPersistence.fromDistribution(distribution) + distributionPersistence.updatedAt = new Date() + const updatedPersistence = await this.distributionRepository.save(distributionPersistence) + return updatedPersistence.toDistribution() + } catch (error) { + throw new DistributionRepositoryError(DistributionRepositoryError.ERRORS.UPDATE_DISTRIBUTION(distribution), error) + } + } + + async getDistributions(pageOptions: PageOptions): Promise> { + try { + const skip = (pageOptions.page - 1) * pageOptions.limit + const take = pageOptions.limit + const order: FindOptionsOrder = { + [pageOptions.order?.orderBy || "createdAt"]: pageOptions.order?.order || "DESC", + } + const [distributionPersistences, total] = await this.distributionRepository.findAndCount({ + skip, + take, + order, + relations: ["asset"], + }) + const distributions = distributionPersistences.map((p) => p.toDistribution()) + return { + items: distributions, + total, + page: pageOptions.page, + limit: pageOptions.limit, + totalPages: Math.ceil(total / pageOptions.limit), + } + } catch (error) { + throw new DistributionRepositoryError(DistributionRepositoryError.ERRORS.GET_DISTRIBUTIONS(), error) + } + } + + async getDistributionsByAssetId(assetId: string, pageOptions: PageOptions): Promise> { + try { + const skip = (pageOptions.page - 1) * pageOptions.limit + const take = pageOptions.limit + const order = { + [pageOptions.order.orderBy]: pageOptions.order.order, + } + + const [distributionPersistences, total] = await this.distributionRepository.findAndCount({ + where: { assetId }, + relations: ["asset"], + skip, + take, + order, + }) + + const distributions = distributionPersistences.map((persistence) => persistence.toDistribution()) + + return { + items: distributions, + total, + page: pageOptions.page, + limit: pageOptions.limit, + totalPages: Math.ceil(total / pageOptions.limit), + } + } catch (error) { + throw new DistributionRepositoryError( + DistributionRepositoryError.ERRORS.GET_DISTRIBUTIONS_BY_ASSET(assetId), + error, + ) + } + } + + async getScheduledAutomatedDistributionsByEvmAddress(evmAddress: string): Promise { + const distributionPersistences = await this.distributionRepository.find({ + where: { + asset: { lifeCycleCashFlowEvmAddress: evmAddress.toLowerCase() }, + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.AUTOMATED, + status: DistributionStatus.SCHEDULED, + }, + relations: ["asset"], + }) + return distributionPersistences.map((persistence) => persistence.toDistribution()) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-holder.repository.ts b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-holder.repository.ts new file mode 100644 index 000000000..e72e728a8 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/adapters/repositories/typeorm-holder.repository.ts @@ -0,0 +1,384 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Holder, HolderStatus } from "@domain/model/holder" +import { Page, PageOptions } from "@domain/model/page" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { HolderRepositoryError } from "@infrastructure/adapters/repositories/errors/holder.repository.error" +import { HolderPersistence } from "@infrastructure/adapters/repositories/model/holder.persistence" +import { Injectable } from "@nestjs/common" +import { InjectRepository } from "@nestjs/typeorm" +import { Repository } from "typeorm" + +@Injectable() +export class HolderTypeOrmRepository implements HolderRepository { + constructor( + @InjectRepository(HolderPersistence) + private readonly holderRepository: Repository, + ) {} + + async saveHolder(holder: Holder): Promise { + try { + const persistence = HolderPersistence.fromHolder(holder) + await this.holderRepository.save(persistence) + return persistence.toHolder() + } catch (error) { + throw new HolderRepositoryError(HolderRepositoryError.ERRORS.SAVE_HOLDER(holder), error) + } + } + + async saveHolders(holders: Holder[]): Promise { + try { + const persistences = holders.map((holder) => { + const holderPersistence = HolderPersistence.fromHolder(holder) + // TODO We do not need to set updateAt as it is done automatically due to @UpdateDateColumn, + // the problem is that the date is set in UTC, but we are setting createdAt as + // new Date() in entities constructors, giving error when transforming from persistence to domain + // model because updateAt is less than createdAt in that case. We should + // avoid setting createdAt dates in constructors or store @UpdateDateColumn as dates with + // proper timezone or set project timezone to UTC + holderPersistence.updatedAt = new Date() + return holderPersistence + }) + await this.holderRepository.save(persistences) + return persistences.map((persistence) => persistence.toHolder()) + } catch (error) { + throw new HolderRepositoryError(HolderRepositoryError.ERRORS.SAVE_HOLDERS(holders), error) + } + } + + async updateHolder(holder: Holder): Promise { + try { + const persistence = HolderPersistence.fromHolder(holder) + await this.holderRepository.update(persistence.id, persistence) + return persistence.toHolder() + } catch (error) { + throw new HolderRepositoryError(HolderRepositoryError.ERRORS.UPDATE_HOLDER(holder), error) + } + } + + async getHoldersByBatchPayout(batchPayoutId: string): Promise { + try { + const holders = await this.holderRepository.find({ + relations: { + batchPayout: { + distribution: { asset: true }, + }, + }, + where: { + batchPayout: { + id: batchPayoutId, + }, + }, + }) + return holders.map((holder) => holder.toHolder()) + } catch (error) { + throw new HolderRepositoryError(HolderRepositoryError.ERRORS.GET_HOLDERS_BY_BATCH_PAYOUT(batchPayoutId), error) + } + } + + async getAllHoldersByDistributionId(distributionId: string): Promise { + try { + const holders = await this.holderRepository.find({ + relations: { + batchPayout: { + distribution: { asset: true }, + }, + }, + where: { + batchPayout: { + distributionId, + }, + }, + }) + + return holders.map((holder) => holder.toHolder()) + } catch (error) { + throw new HolderRepositoryError(HolderRepositoryError.ERRORS.GET_HOLDERS_BY_DISTRIBUTION(distributionId), error) + } + } + + async getHoldersByDistributionId(distributionId: string, pageOptions: PageOptions): Promise> { + try { + const skip = (pageOptions.page - 1) * pageOptions.limit + const take = pageOptions.limit + const order = { + [pageOptions.order.orderBy]: pageOptions.order.order, + } + + const [persistences, total] = await this.holderRepository.findAndCount({ + where: { + batchPayout: { + distributionId, + }, + }, + relations: { + batchPayout: { + distribution: { asset: true }, + }, + }, + skip, + take, + order, + }) + + return { + items: persistences.map((persistence) => persistence.toHolder()), + total, + page: pageOptions.page, + limit: pageOptions.limit, + totalPages: Math.ceil(total / pageOptions.limit), + } + } catch (error) { + throw new HolderRepositoryError(HolderRepositoryError.ERRORS.GET_HOLDERS_BY_DISTRIBUTION(distributionId), error) + } + } + + async countHoldersByDistributionId(distributionId: string): Promise { + try { + return await this.holderRepository.count({ + where: { + batchPayout: { + distributionId, + }, + }, + relations: { + batchPayout: { + distribution: true, + }, + }, + }) + } catch (error) { + throw new HolderRepositoryError( + HolderRepositoryError.ERRORS.GET_HOLDER_COUNT_BY_DISTRIBUTION(distributionId), + error, + ) + } + } + + async getHoldersByDistributionIdAndStatus(distributionId: string, status: HolderStatus): Promise { + try { + const holders = await this.holderRepository.find({ + relations: { + batchPayout: { + distribution: { asset: true }, + }, + }, + where: { + batchPayout: { + distributionId, + }, + status, + }, + }) + + return holders.map((holder) => holder.toHolder()) + } catch (error) { + throw new HolderRepositoryError( + HolderRepositoryError.ERRORS.GET_HOLDERS_BY_DISTRIBUTION_AND_STATUS(distributionId, status), + error, + ) + } + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/cron/mass-payout-cron.service.ts b/apps/mass-payout/backend/src/infrastructure/cron/mass-payout-cron.service.ts new file mode 100644 index 000000000..52d659a6c --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/cron/mass-payout-cron.service.ts @@ -0,0 +1,220 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable, Logger } from "@nestjs/common" +import { Cron, CronExpression } from "@nestjs/schedule" +import { ProcessScheduledPayoutsUseCase } from "@application/use-cases/process-scheduled-payouts.use-case" + +@Injectable() +export class MassPayoutCronService { + private readonly logger = new Logger(MassPayoutCronService.name) + + constructor(private readonly processScheduledPayoutsUseCase: ProcessScheduledPayoutsUseCase) {} + + @Cron(CronExpression.EVERY_DAY_AT_9AM) + async handleScheduledPayouts(): Promise { + this.logger.log("Starting scheduled mass payouts execution") + await this.processScheduledPayoutsUseCase.execute() + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/asset/asset.controller.ts b/apps/mass-payout/backend/src/infrastructure/rest/asset/asset.controller.ts new file mode 100644 index 000000000..7ea9718af --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/asset/asset.controller.ts @@ -0,0 +1,329 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { DisableAssetSyncUseCase } from "@application/use-cases/disable-asset-sync.use-case" +import { EnableAssetSyncUseCase } from "@application/use-cases/enable-asset-sync.use-case" +import { ExecutePayoutUseCase } from "@application/use-cases/execute-payout.use-case" +import { GetAssetDistributionsUseCase } from "@application/use-cases/get-asset-distributions.use-case" +import { GetAssetUseCase } from "@application/use-cases/get-asset.use-case" +import { GetAssetsUseCase } from "@application/use-cases/get-assets.use-case" +import { GetBasicAssetInformationUseCase } from "@application/use-cases/get-basic-asset-information.use-case" +import { ImportAssetUseCase } from "@application/use-cases/import-asset.use-case" +import { PauseAssetUseCase } from "@application/use-cases/pause-asset.use-case" +import { UnpauseAssetUseCase } from "@application/use-cases/unpause-asset.use-case" +import { Body, Get, HttpCode, HttpStatus, Param, Patch, Post, Query } from "@nestjs/common" +import { DistributionResponse } from "../distribution/distribution.response" +import { PageOptionsRequest } from "../page-options.request" +import { PageResponse } from "../page.response" +import { RestController } from "../rest.decorator" +import { AssetResponse } from "./asset.response" +import { CreatePayoutRequest } from "./create-payout.request" +import { GetBasicAssetInformationRequest } from "./get-basic-asset-information.request" +import { GetBasicAssetInformationResponse } from "./get-basic-asset-information.response" +import { ImportAssetRequest } from "./import-asset.request" +import { GetDistributionHolderCountUseCase } from "@application/use-cases/get-distribution-holder-count.use-case" + +@RestController("assets") +export class AssetController { + constructor( + private readonly disableAssetSyncUseCase: DisableAssetSyncUseCase, + private readonly enableAssetSyncUseCase: EnableAssetSyncUseCase, + private readonly importAssetUseCase: ImportAssetUseCase, + private readonly pauseAssetUseCase: PauseAssetUseCase, + private readonly unpauseAssetUseCase: UnpauseAssetUseCase, + private readonly getAssetUseCase: GetAssetUseCase, + private readonly getAssetsUseCase: GetAssetsUseCase, + private readonly getBasicAssetInformationUseCase: GetBasicAssetInformationUseCase, + private readonly getAssetDistributionsUseCase: GetAssetDistributionsUseCase, + private readonly getDistributionHolderCountUseCase: GetDistributionHolderCountUseCase, + private readonly executePayoutUseCase: ExecutePayoutUseCase, + ) {} + + @Post("import") + async importAsset(@Body() request: ImportAssetRequest): Promise { + const asset = await this.importAssetUseCase.execute(request.hederaTokenAddress) + return AssetResponse.fromAsset(asset) + } + + @Patch(":assetId/pause") + @HttpCode(HttpStatus.OK) + async pauseAsset(@Param("assetId") assetId: string): Promise { + await this.pauseAssetUseCase.execute(assetId) + } + + @Patch(":assetId/unpause") + @HttpCode(HttpStatus.OK) + async unpauseAsset(@Param("assetId") assetId: string): Promise { + await this.unpauseAssetUseCase.execute(assetId) + } + + @Get() + async getAssets(@Query() pageOptions: PageOptionsRequest): Promise> { + const result = await this.getAssetsUseCase.execute(pageOptions.toPageOptions()) + return PageResponse.fromPage(result, AssetResponse.fromAsset) + } + + @Get(":assetId") + async getAsset(@Param("assetId") assetId: string): Promise { + const asset = await this.getAssetUseCase.execute(assetId) + return AssetResponse.fromAsset(asset) + } + + @Get(":hederaTokenAddress/metadata") + async getBasicAssetInformation( + @Param() request: GetBasicAssetInformationRequest, + ): Promise { + const response = await this.getBasicAssetInformationUseCase.execute(request.hederaTokenAddress) + return new GetBasicAssetInformationResponse( + response.hederaTokenAddress, + response.name, + response.symbol, + response.assetType, + response.maturityDate, + ) + } + + @Get(":assetId/distributions") + async getAssetDistributions( + @Param("assetId") assetId: string, + @Query() pageOptions: PageOptionsRequest, + ): Promise> { + const result = await this.getAssetDistributionsUseCase.execute(assetId, pageOptions.toPageOptions()) + + const distributions = PageResponse.fromPage(result, DistributionResponse.fromDistribution) + for (let i: number = 0; i < distributions.items.length; i++) { + const distribution = distributions.items[i] + distribution.holdersNumber = await this.getDistributionHolderCountUseCase.execute(distribution.id) + } + return distributions + } + + @Post(":assetId/distributions/payout") + @HttpCode(HttpStatus.CREATED) + async createPayout(@Param("assetId") assetId: string, @Body() request: CreatePayoutRequest): Promise { + await this.executePayoutUseCase.execute({ + assetId, + subtype: request.subtype, + executeAt: request.executeAt ? new Date(request.executeAt) : undefined, + recurrency: request.recurrency, + amount: request.amount, + amountType: request.amountType, + concept: request.concept, + }) + } + + @Patch(":assetId/enable-sync") + @HttpCode(HttpStatus.OK) + async enableAssetSync(@Param("assetId") assetId: string): Promise { + const asset = await this.enableAssetSyncUseCase.execute(assetId) + return AssetResponse.fromAsset(asset) + } + + @Patch(":assetId/disable-sync") + @HttpCode(HttpStatus.OK) + async disableAssetSync(@Param("assetId") assetId: string): Promise { + const asset = await this.disableAssetSyncUseCase.execute(assetId) + return AssetResponse.fromAsset(asset) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/asset/asset.response.ts b/apps/mass-payout/backend/src/infrastructure/rest/asset/asset.response.ts new file mode 100644 index 000000000..5023fa0e6 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/asset/asset.response.ts @@ -0,0 +1,239 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" + +export class AssetResponse { + id: string + name: string + type: string + hederaTokenAddress: string + evmTokenAddress: string + symbol: string + lifeCycleCashFlowHederaAddress?: string + lifeCycleCashFlowEvmAddress?: string + maturityDate?: Date + isPaused: boolean + syncEnabled: boolean + createdAt: Date + updatedAt: Date + + static fromAsset(asset: Asset): AssetResponse { + const response = new AssetResponse() + response.id = asset.id + response.name = asset.name + response.type = asset.type + response.hederaTokenAddress = asset.hederaTokenAddress + response.evmTokenAddress = asset.evmTokenAddress + response.symbol = asset.symbol + response.lifeCycleCashFlowHederaAddress = asset.lifeCycleCashFlowHederaAddress + response.lifeCycleCashFlowEvmAddress = asset.lifeCycleCashFlowEvmAddress + response.maturityDate = asset.maturityDate + response.isPaused = asset.isPaused + response.syncEnabled = asset.syncEnabled + response.createdAt = asset.createdAt + response.updatedAt = asset.updatedAt + return response + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/asset/create-payout.request.ts b/apps/mass-payout/backend/src/infrastructure/rest/asset/create-payout.request.ts new file mode 100644 index 000000000..72347107e --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/asset/create-payout.request.ts @@ -0,0 +1,231 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AmountType, PayoutSubtype, Recurrency } from "@domain/model/distribution" +import { IsEnum, IsNotEmpty, IsOptional, ValidateIf } from "class-validator" +import { IsFutureDateString } from "src/utils/IsFutureDateString" +import { IsPositiveNumberString } from "src/utils/IsPositiveNumberString" + +export class CreatePayoutRequest { + @IsEnum(PayoutSubtype) + subtype: PayoutSubtype + + @ValidateIf((o) => o.subtype && (o.subtype === PayoutSubtype.ONE_OFF || o.subtype === PayoutSubtype.RECURRING)) + @IsFutureDateString() + executeAt?: string + + @ValidateIf((o) => o.recurrency) + @IsEnum(Recurrency) + recurrency?: Recurrency + + @IsNotEmpty() + @IsPositiveNumberString() + amount: string + + @IsEnum(AmountType) + amountType: AmountType + + @IsOptional() + concept: string +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/asset/get-basic-asset-information.request.ts b/apps/mass-payout/backend/src/infrastructure/rest/asset/get-basic-asset-information.request.ts new file mode 100644 index 000000000..65fc01999 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/asset/get-basic-asset-information.request.ts @@ -0,0 +1,212 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { IsNotEmpty, IsString, Matches } from "class-validator" + +export class GetBasicAssetInformationRequest { + @IsString() + @IsNotEmpty() + @Matches(/^\d+\.\d+\.\d+$/, { message: "hederaTokenAddress must be a valid Hedera address format" }) + hederaTokenAddress: string +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/asset/get-basic-asset-information.response.ts b/apps/mass-payout/backend/src/infrastructure/rest/asset/get-basic-asset-information.response.ts new file mode 100644 index 000000000..0dc524332 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/asset/get-basic-asset-information.response.ts @@ -0,0 +1,221 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetType } from "@domain/model/asset-type.enum" + +export class GetBasicAssetInformationResponse { + hederaTokenAddress: string + name: string + symbol: string + assetType: AssetType + maturityDate?: Date + + constructor(hederaTokenAddress: string, name: string, symbol: string, assetType: AssetType, maturityDate?: Date) { + this.hederaTokenAddress = hederaTokenAddress + this.name = name + this.symbol = symbol + this.assetType = assetType + this.maturityDate = maturityDate + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/asset/import-asset.request.ts b/apps/mass-payout/backend/src/infrastructure/rest/asset/import-asset.request.ts new file mode 100644 index 000000000..af47ad3d7 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/asset/import-asset.request.ts @@ -0,0 +1,212 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { IsNotEmpty, IsString, Matches } from "class-validator" + +export class ImportAssetRequest { + @IsString() + @IsNotEmpty() + @Matches(/^\d+\.\d+\.\d+$/, { message: "hederaTokenAddress must be a valid Hedera address format" }) + hederaTokenAddress: string +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/blockchain/blockchain.controller.ts b/apps/mass-payout/backend/src/infrastructure/rest/blockchain/blockchain.controller.ts new file mode 100644 index 000000000..bbd543f2c --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/blockchain/blockchain.controller.ts @@ -0,0 +1,242 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetBlockchainEventListenerConfigUseCase } from "@application/use-cases/get-blockchain-event-listener-config.use-case" +import { StartBlockchainPollingUseCase } from "@application/use-cases/start-blockchain-polling.use-case" +import { StopBlockchainPollingUseCase } from "@application/use-cases/stop-blockchain-polling.use-case" +import { UpsertBlockchainEventListenerConfigUseCase } from "@application/use-cases/upsert-blockchain-event-listener-config.use-case" +import { BlockchainEventListenerConfig } from "@domain/model/blockchain-listener" +import { Body, Get, Patch, Post } from "@nestjs/common" +import { RestController } from "../rest.decorator" + +@RestController("blockchain") +export class BlockchainController { + constructor( + private readonly startBlockchainUseCase: StartBlockchainPollingUseCase, + private readonly stopBlockchainUseCase: StopBlockchainPollingUseCase, + private readonly upsertBlockchainEventListenerConfigUseCase: UpsertBlockchainEventListenerConfigUseCase, + private readonly getBlockchainEventListenerConfigUseCase: GetBlockchainEventListenerConfigUseCase, + ) {} + + @Get("/config") + async getConfig(): Promise { + return await this.getBlockchainEventListenerConfigUseCase.execute() + } + + @Post("/config") + async upsertConfig(@Body() body: Partial): Promise { + const config = await this.getBlockchainEventListenerConfigUseCase.execute() + return await this.upsertBlockchainEventListenerConfigUseCase.execute({ ...config, ...body }) + } + + @Patch("/polling/start") + async start(): Promise { + await this.startBlockchainUseCase.execute() + } + + @Patch("/polling/stop") + async stop(): Promise { + await this.stopBlockchainUseCase.execute() + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/distribution/distribution.controller.ts b/apps/mass-payout/backend/src/infrastructure/rest/distribution/distribution.controller.ts new file mode 100644 index 000000000..c740a1ec5 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/distribution/distribution.controller.ts @@ -0,0 +1,265 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetDistributionHoldersUseCase } from "@application/use-cases/get-distribution-holders.use-case" +import { GetDistributionsUseCase } from "@application/use-cases/get-distributions.use-case" +import { DistributionResponse } from "@infrastructure/rest/distribution/distribution.response" +import { PageOptionsRequest } from "@infrastructure/rest/page-options.request" +import { PageResponse } from "@infrastructure/rest/page.response" +import { RestController } from "@infrastructure/rest/rest.decorator" +import { Get, HttpCode, HttpStatus, Param, Patch, Query } from "@nestjs/common" +import { HolderResponse } from "@infrastructure/rest/responses/holder.response" +import { GetDistributionUseCase } from "@application/use-cases/get-distribution.use-case" +import { CancelDistributionUseCase } from "@application/use-cases/cancel-distribution.use-case" +import { RetryFailedHoldersUseCase } from "@application/use-cases/retry-failed-holders.use-case" + +@RestController("distributions") +export class DistributionController { + constructor( + private readonly getDistributionsUseCase: GetDistributionsUseCase, + private readonly getDistributionHoldersUseCase: GetDistributionHoldersUseCase, + private readonly getDistributionUseCase: GetDistributionUseCase, + private readonly cancelDistributionUseCase: CancelDistributionUseCase, + private readonly retryFailedHoldersUseCase: RetryFailedHoldersUseCase, + ) {} + + @Get() + async getDistributions(@Query() pageOptionsRequest: PageOptionsRequest): Promise> { + const pageOptions = pageOptionsRequest.toPageOptions() + const distributions = await this.getDistributionsUseCase.execute(pageOptions) + return PageResponse.fromPage(distributions, DistributionResponse.fromDistribution) + } + + @Get(":distributionId") + async getDistribution(@Param("distributionId") distributionId: string): Promise { + const distribution = await this.getDistributionUseCase.execute(distributionId) + return DistributionResponse.fromDistribution(distribution) + } + + @Get(":distributionId/holders") + async getHolders( + @Param("distributionId") distributionId: string, + @Query() pageOptionsRequest: PageOptionsRequest, + ): Promise> { + const pageOptions = pageOptionsRequest.toPageOptions() + const holders = await this.getDistributionHoldersUseCase.execute(distributionId, pageOptions) + return PageResponse.fromPage(holders, HolderResponse.fromHolder) + } + + @Patch(":distributionId/cancel") + @HttpCode(HttpStatus.OK) + async cancelDistribution(@Param("distributionId") distributionId: string): Promise { + await this.cancelDistributionUseCase.execute({ + distributionId, + }) + } + + @Patch(":distributionId/retry") + @HttpCode(HttpStatus.OK) + async retryDistribution(@Param("distributionId") distributionId: string): Promise { + await this.retryFailedHoldersUseCase.execute({ + distributionId, + }) + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/distribution/distribution.response.ts b/apps/mass-payout/backend/src/infrastructure/rest/distribution/distribution.response.ts new file mode 100644 index 000000000..eb1261483 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/distribution/distribution.response.ts @@ -0,0 +1,267 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { + CorporateActionDetails, + Distribution, + DistributionType, + PayoutDetails, + PayoutSubtype, + Recurrency, +} from "@domain/model/distribution" +import { AssetResponse } from "@infrastructure/rest/asset/asset.response" +import { Logger } from "@nestjs/common" + +export class DistributionResponse { + private static readonly logger = new Logger(DistributionResponse.name) + + id: string + asset: AssetResponse + type: string + corporateActionID?: string + executionDate?: Date + amount?: string + amountType?: string + concept?: string + subtype?: string + status: string + holdersNumber: number + recurrency?: Recurrency + + createdAt: Date + updatedAt: Date + + static fromDistribution(distribution: Distribution): DistributionResponse { + const response = new DistributionResponse() + response.id = distribution.id + response.asset = AssetResponse.fromAsset(distribution.asset) + response.type = distribution.details.type + response.status = distribution.status + response.createdAt = distribution.createdAt + response.updatedAt = distribution.updatedAt + + if (distribution.details.type === DistributionType.CORPORATE_ACTION) { + const corporateActionDetails = distribution.details as CorporateActionDetails + response.corporateActionID = corporateActionDetails.corporateActionId?.value || null + response.executionDate = corporateActionDetails.executionDate + } else if (distribution.details.type === DistributionType.PAYOUT) { + const payoutDetails = distribution.details as PayoutDetails + response.amount = payoutDetails.amount + response.amountType = payoutDetails.amountType + response.concept = payoutDetails.concept + response.subtype = payoutDetails.subtype + + if (distribution.details.subtype == PayoutSubtype.IMMEDIATE) { + response.executionDate = distribution.createdAt + } else if ("executeAt" in payoutDetails) { + response.executionDate = payoutDetails.executeAt + } + if (distribution.details.subtype == PayoutSubtype.RECURRING) { + response.recurrency = distribution.details.recurrency + } + } + + return response + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/page-options.request.ts b/apps/mass-payout/backend/src/infrastructure/rest/page-options.request.ts new file mode 100644 index 000000000..a766a9020 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/page-options.request.ts @@ -0,0 +1,249 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { PageOptions } from "@domain/model/page" +import { Type } from "class-transformer" +import { IsIn, IsInt, IsOptional, IsString, Min } from "class-validator" + +export class PageOptionsRequest { + @IsOptional() + @Type(() => Number) + @IsInt() + @Min(1) + page: number = 1 + + @IsOptional() + @Type(() => Number) + @IsInt() + @Min(1) + limit: number = 10 + + @IsOptional() + @IsString() + orderBy: string = "createdAt" + + @IsOptional() + @IsIn(["ASC", "DESC", "asc", "desc"]) + order: string = "DESC" + + toPageOptions(): PageOptions { + return { + page: this.page, + limit: this.limit, + order: { + orderBy: this.orderBy, + order: this.order as "asc" | "desc" | "ASC" | "DESC", + }, + } + } + + static readonly DEFAULT: PageOptionsRequest = (() => { + const instance = new PageOptionsRequest() + instance.page = 1 + instance.limit = 10 + instance.orderBy = "createdAt" + instance.order = "DESC" + return instance + })() +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/page.response.ts b/apps/mass-payout/backend/src/infrastructure/rest/page.response.ts new file mode 100644 index 000000000..7cefe7a1d --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/page.response.ts @@ -0,0 +1,223 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Page } from "@domain/model/page" + +export class PageResponse { + items: T[] + total: number + page: number + limit: number + totalPages: number + + static fromPage(page: Page, transform: (item: T) => R): PageResponse { + const response = new PageResponse() + response.items = page.items.map(transform) + response.total = page.total + response.page = page.page + response.limit = page.limit + response.totalPages = page.totalPages + return response + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/responses/batchpayout.response.ts b/apps/mass-payout/backend/src/infrastructure/rest/responses/batchpayout.response.ts new file mode 100644 index 000000000..34ba8bc16 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/responses/batchpayout.response.ts @@ -0,0 +1,227 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout } from "@domain/model/batch-payout" + +export class BatchPayoutResponse { + id: string + distributionId: string + name: string + hederaTransactionId: string + hederaTransactionHash: string + holdersNumber: number + status: string + + static fromBatchPayout(batchPayout: BatchPayout): BatchPayoutResponse { + const response = new BatchPayoutResponse() + response.id = batchPayout.id + response.distributionId = batchPayout.distribution.id + response.name = batchPayout.name + response.hederaTransactionId = batchPayout.hederaTransactionId + response.hederaTransactionHash = batchPayout.hederaTransactionHash + response.holdersNumber = batchPayout.holdersNumber + response.status = batchPayout.status + return response + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/responses/holder.response.ts b/apps/mass-payout/backend/src/infrastructure/rest/responses/holder.response.ts new file mode 100644 index 000000000..bf3d5cbd5 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/responses/holder.response.ts @@ -0,0 +1,236 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Holder } from "@domain/model/holder" +import { BatchPayoutResponse } from "@infrastructure/rest/responses/batchpayout.response" + +export class HolderResponse { + id: string + batchPayout: BatchPayoutResponse + holderHederaAddress: string + holderEvmAddress: string + retryCounter: number + status: string + amount: string + lastError?: string + nextRetryAt?: Date + createdAt: Date + updatedAt: Date + + static fromHolder(holder: Holder): HolderResponse { + const response = new HolderResponse() + response.id = holder.id + response.batchPayout = BatchPayoutResponse.fromBatchPayout(holder.batchPayout) + response.holderHederaAddress = holder.holderHederaAddress + response.holderEvmAddress = holder.holderEvmAddress + response.retryCounter = holder.retryCounter + response.status = holder.status + response.amount = holder.amount + response.lastError = holder.lastError ?? null + response.nextRetryAt = holder.nextRetryAt + response.createdAt = holder.createdAt + response.updatedAt = holder.updatedAt + return response + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/rest-exception.filter.ts b/apps/mass-payout/backend/src/infrastructure/rest/rest-exception.filter.ts new file mode 100644 index 000000000..329d887b0 --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/rest-exception.filter.ts @@ -0,0 +1,304 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetNotFoundError } from "@domain/errors/asset.error" +import { BlockchainEventListenerConfigNotFoundError } from "@domain/errors/blockchain-event-error" +import { DistributionNotFoundError } from "@domain/errors/distribution.error" +import { ConflictError } from "@domain/errors/shared/conflict-error" +import { CustomError } from "@domain/errors/shared/custom.error" +import { DomainError } from "@domain/errors/shared/domain.error" +import { InvalidDataError } from "@domain/errors/shared/invalid-data.error" +import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus, Logger } from "@nestjs/common" + +@Catch() +export class RestExceptionFilter implements ExceptionFilter { + private readonly logger = new Logger(RestExceptionFilter.name) + + catch(error: Error, host: ArgumentsHost): any { + this.logger.error(error.message, error.stack, error.name) + const ctx = host.switchToHttp() + const response = ctx.getResponse() + if (error instanceof HttpException) { + const status = error.getStatus() + const original = error.getResponse() + + const payload = + typeof original === "string" + ? { statusCode: status, message: original } + : Array.isArray((original as any)?.message) + ? { statusCode: status, message: (original as any).message.join(", ") } + : original + return response.status(status).json(payload) + } + + const messageFromError = this.getHttpMessageFromError(error) + const codeFromError = this.getHttpCodeFromError(error) + const causeFromError = this.getHttpCauseFromError(error) + + const exception = new HttpException(messageFromError, codeFromError, { cause: causeFromError }) + const status = exception.getStatus() + const safePayload = this.maskIfInternalError(exception) + + response.status(status).json(safePayload) + } + + private getHttpMessageFromError(error: Error): string { + if (error instanceof CustomError) { + return error.toJson() + } else { + return new CustomError().toJson() + } + } + + private getHttpCauseFromError(error: Error): string { + if (error instanceof CustomError) { + return error.toJson().cause + } else { + return new CustomError().toJson().cause + } + } + + private getHttpCodeFromError(error: Error): HttpStatus { + const rootError = CustomError.getRootError(error) + if (rootError instanceof DomainError) { + return this.mapDomainErrorToHttpStatus(rootError) + } + + return HttpStatus.INTERNAL_SERVER_ERROR + } + + private mapDomainErrorToHttpStatus(error: DomainError): HttpStatus { + switch (true) { + case error instanceof InvalidDataError: + return HttpStatus.BAD_REQUEST + case error instanceof ConflictError: + return HttpStatus.CONFLICT + case error instanceof AssetNotFoundError: + case error instanceof DistributionNotFoundError: + case error instanceof BlockchainEventListenerConfigNotFoundError: + return HttpStatus.NOT_FOUND + default: + return HttpStatus.INTERNAL_SERVER_ERROR + } + } + + private maskIfInternalError(exc: HttpException): { + statusCode: number + message: string + cause?: unknown + } { + if (exc.getStatus() == HttpStatus.INTERNAL_SERVER_ERROR) { + return { + statusCode: HttpStatus.INTERNAL_SERVER_ERROR, + message: "Internal server error", + } + } + + return { + statusCode: exc.getStatus(), + message: exc.message, + cause: exc.cause, + } + } +} diff --git a/apps/mass-payout/backend/src/infrastructure/rest/rest.decorator.ts b/apps/mass-payout/backend/src/infrastructure/rest/rest.decorator.ts new file mode 100644 index 000000000..e49f7c02a --- /dev/null +++ b/apps/mass-payout/backend/src/infrastructure/rest/rest.decorator.ts @@ -0,0 +1,220 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { applyDecorators, Controller, UseFilters, UsePipes, ValidationPipe } from "@nestjs/common" +import { RestExceptionFilter } from "@infrastructure/rest/rest-exception.filter" + +export function RestController(prefix?: string) { + return applyDecorators( + Controller(prefix), + UsePipes( + new ValidationPipe({ + transform: true, + whitelist: true, + forbidNonWhitelisted: true, + }), + ), + UseFilters(new RestExceptionFilter()), + ) +} diff --git a/apps/mass-payout/backend/src/main.ts b/apps/mass-payout/backend/src/main.ts new file mode 100644 index 000000000..32db0a188 --- /dev/null +++ b/apps/mass-payout/backend/src/main.ts @@ -0,0 +1,247 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { LogLevel } from "@nestjs/common" +import { NestFactory } from "@nestjs/core" +import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger" +import { AppModule } from "./app.module" + +function getLogLevels(minLogLevel: LogLevel): LogLevel[] { + const logLevels: LogLevel[] = ["verbose", "debug", "log", "warn", "error", "fatal"] + const idx = logLevels.indexOf(minLogLevel as LogLevel) + return logLevels.slice(idx) +} + +function setupSwagger(app: any) { + const config = new DocumentBuilder() + .setTitle("API Docs") + .setDescription("The API description") + .setVersion("1.0") + .build() + + const document = SwaggerModule.createDocument(app, config) + SwaggerModule.setup("swagger", app, document) +} + +async function bootstrap() { + const app = await NestFactory.create(AppModule, { + bufferLogs: true, + logger: getLogLevels((process.env.LOG_LEVEL as LogLevel) || "log"), + }) + + app.enableCors({ + origin: ["http://localhost:5173"], + methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"], + allowedHeaders: ["Content-Type", "Authorization"], + credentials: true, + }) + + if (process.env.APP_ENV == "local") { + setupSwagger(app) + } + + await app.listen(3000) +} + +bootstrap() diff --git a/apps/mass-payout/backend/src/utils/IsFutureDateString.ts b/apps/mass-payout/backend/src/utils/IsFutureDateString.ts new file mode 100644 index 000000000..9d7f01ab1 --- /dev/null +++ b/apps/mass-payout/backend/src/utils/IsFutureDateString.ts @@ -0,0 +1,23 @@ +import { registerDecorator, ValidationArguments, ValidationOptions } from "class-validator" + +export function IsFutureDateString(validationOptions?: ValidationOptions) { + return function (object: object, propertyName: string) { + registerDecorator({ + name: "isFutureDateString", + target: object.constructor, + propertyName: propertyName, + options: validationOptions, + validator: { + validate(value: any) { + if (typeof value !== "string") return false + const date = new Date(value) + if (isNaN(date.getTime())) return false + return date > new Date() + }, + defaultMessage(args: ValidationArguments) { + return `${args.property} must be a future date` + }, + }, + }) + } +} diff --git a/apps/mass-payout/backend/src/utils/IsPositiveNumberString.ts b/apps/mass-payout/backend/src/utils/IsPositiveNumberString.ts new file mode 100644 index 000000000..97a967e5f --- /dev/null +++ b/apps/mass-payout/backend/src/utils/IsPositiveNumberString.ts @@ -0,0 +1,22 @@ +import { registerDecorator, ValidationArguments, ValidationOptions } from "class-validator" + +export function IsPositiveNumberString(validationOptions?: ValidationOptions) { + return function (object: object, propertyName: string) { + registerDecorator({ + name: "isPositiveNumberString", + target: object.constructor, + propertyName: propertyName, + options: validationOptions, + validator: { + validate(value: any, args: ValidationArguments) { + if (typeof value !== "string") return false + const num = Number(value) + return !isNaN(num) && num > 0 && isFinite(num) + }, + defaultMessage(args: ValidationArguments) { + return `${args.property} must be a positive number string` + }, + }, + }) + } +} diff --git a/apps/mass-payout/backend/src/utils/isZeroAddress.ts b/apps/mass-payout/backend/src/utils/isZeroAddress.ts new file mode 100644 index 000000000..fa77d6cf1 --- /dev/null +++ b/apps/mass-payout/backend/src/utils/isZeroAddress.ts @@ -0,0 +1,209 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { constants } from "ethers" + +export function isZeroAddress(address: string): boolean { + return constants.AddressZero === address +} diff --git a/apps/mass-payout/backend/test/e2e/asset/execute-manual.e2e.spec.ts b/apps/mass-payout/backend/test/e2e/asset/execute-manual.e2e.spec.ts new file mode 100644 index 000000000..86f7ed32e --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/asset/execute-manual.e2e.spec.ts @@ -0,0 +1,491 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { AmountType, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { faker } from "@faker-js/faker" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { CreatePayoutRequest } from "@infrastructure/rest/asset/create-payout.request" +import { HttpStatus } from "@nestjs/common" +import { E2eTestApp } from "@test/e2e/shared/e2e-test.app" +import { E2eUtils } from "@test/e2e/shared/e2e-utils" +import { TestConstants } from "@test/e2e/shared/test-constants" +import { AssetUtils } from "@test/shared/asset.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import request from "supertest" +import { Repository } from "typeorm" + +describe("POST /assets/:assetId/distributions/payout", () => { + let e2eTestApp: E2eTestApp + let internalAssetRepository: Repository + let internalDistributionRepository: Repository + + let asset: Asset + + beforeAll(async () => { + try { + e2eTestApp = await E2eTestApp.create() + if (!e2eTestApp) { + throw new Error("E2eTestApp.create() returned undefined") + } + internalAssetRepository = e2eTestApp.getRepository(AssetPersistence) + internalDistributionRepository = e2eTestApp.getRepository(DistributionPersistence) + } catch (error) { + console.error("Error in beforeAll:", error) + throw error + } + }, TestConstants.BEFORE_ALL_TIMEOUT) + + beforeEach(async () => { + asset = AssetUtils.newInstance() + await internalAssetRepository.save(asset) + }) + + afterAll(async () => { + if (e2eTestApp) { + await e2eTestApp.stop() + } + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + await E2eUtils.purgeOrRecreate(internalAssetRepository) + await E2eUtils.purgeOrRecreate(internalDistributionRepository) + }, TestConstants.AFTER_EACH_TIMEOUT) + + describe("Success cases", () => { + it.skip("should execute immediate payout successfully", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const distribution = DistributionUtils.newInstance({ + asset: asset, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + amount: amount, + amountType: AmountType.FIXED, + snapshotId: SnapshotId.create("some-snapshot-id"), + }, + }) + await internalDistributionRepository.save(distribution) + + const payload: CreatePayoutRequest = { + subtype: PayoutSubtype.IMMEDIATE, + amount, + amountType: AmountType.FIXED, + concept: "Test payout", + } + + const response = await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(payload) + .expect(HttpStatus.CREATED) + + expect(response.body).toBeDefined() + }) + + it.skip("should execute one-off payout successfully", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const executeAt = faker.date.future() + const distribution = DistributionUtils.newInstance({ + asset: asset, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.ONE_OFF, + amount: amount, + amountType: AmountType.FIXED, + executeAt: executeAt, + }, + }) + await internalDistributionRepository.save(distribution) + + const payload: CreatePayoutRequest = { + subtype: PayoutSubtype.ONE_OFF, + amount, + executeAt: executeAt.toISOString(), + amountType: AmountType.FIXED, + concept: "Test one-off payout", + } + + const response = await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(payload) + .expect(HttpStatus.CREATED) + + expect(response.body).toBeDefined() + }) + }) + + describe("Validation errors", () => { + it("should return 400 when subtype is missing", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const requestBody = { + amount, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(400) + }) + + it("should return 400 when subtype is invalid", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const requestBody = { + subtype: "INVALID_SUBTYPE", + amount, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(400) + }) + + it("should return 400 when amount is missing", async () => { + const requestBody = { + subtype: PayoutSubtype.IMMEDIATE, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(400) + }) + + it("should return 400 when amount is not a positive number", async () => { + const invalidAmounts = ["0", "-100", "abc", ""] + + for (const amount of invalidAmounts) { + const requestBody = { + subtype: PayoutSubtype.IMMEDIATE, + amount, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(400) + } + }) + + it("should return 400 when executeAt is missing for one-off payout", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const requestBody = { + subtype: PayoutSubtype.ONE_OFF, + amount, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(400) + }) + + it("should return 400 when executeAt is not a valid date string", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const requestBody = { + subtype: PayoutSubtype.ONE_OFF, + amount, + executeAt: "invalid-date", + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(400) + }) + + it("should return 400 when executeAt is in the past", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const pastDate = faker.date.past().toISOString() + const requestBody = { + subtype: PayoutSubtype.ONE_OFF, + amount, + executeAt: pastDate, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(400) + }) + + it.skip("should not require executeAt for immediate payout", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const requestBody = { + subtype: PayoutSubtype.IMMEDIATE, + amount, + executeAt: faker.date.future().toISOString(), + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(201) + }) + }) + + describe("Business logic errors", () => { + it("should return 404 when asset does not exist", async () => { + const nonExistentAssetId = faker.string.uuid() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const requestBody = { + subtype: PayoutSubtype.IMMEDIATE, + amount, + amountType: AmountType.FIXED, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${nonExistentAssetId}/distributions/payout`) + .send(requestBody) + .expect(404) + }) + }) + + describe.skip("Edge cases", () => { + it("should handle very large amounts", async () => { + const largeAmount = "999999999999999999" + const requestBody = { + subtype: PayoutSubtype.IMMEDIATE, + amount: largeAmount, + amountType: AmountType.FIXED, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(201) + }) + + it("should handle decimal amounts", async () => { + const decimalAmount = "123.456789" + const requestBody = { + subtype: PayoutSubtype.IMMEDIATE, + amount: decimalAmount, + amountType: AmountType.FIXED, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(201) + }) + + it("should handle executeAt at the boundary of future date validation", async () => { + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const nearFutureDate = new Date(Date.now() + 10 * 1000).toISOString() + const requestBody = { + subtype: PayoutSubtype.ONE_OFF, + amount, + executeAt: nearFutureDate, + } + + await request(e2eTestApp.app.getHttpServer()) + .post(`/assets/${asset.id}/distributions/payout`) + .send(requestBody) + .expect(201) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/e2e/distribution/cancel-distribution.e2e.spec.ts b/apps/mass-payout/backend/test/e2e/distribution/cancel-distribution.e2e.spec.ts new file mode 100644 index 000000000..890847514 --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/distribution/cancel-distribution.e2e.spec.ts @@ -0,0 +1,280 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AmountType, DistributionStatus, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { faker } from "@faker-js/faker" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { HttpStatus } from "@nestjs/common" +import { E2eTestApp } from "@test/e2e/shared/e2e-test.app" +import { E2eUtils } from "@test/e2e/shared/e2e-utils" +import { TestConstants } from "@test/e2e/shared/test-constants" +import { AssetUtils } from "@test/shared/asset.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import request from "supertest" +import { Repository } from "typeorm" + +describe("PATCH /distributions/:distributionId/cancel", () => { + let e2eTestApp: E2eTestApp + let internalDistributionRepository: Repository + let internalAssetRepository: Repository + const baseEndpoint = "/distributions" + + beforeAll(async () => { + try { + e2eTestApp = await E2eTestApp.create() + if (!e2eTestApp) { + throw new Error("E2eTestApp.create() returned undefined") + } + internalDistributionRepository = e2eTestApp.getRepository(DistributionPersistence) + internalAssetRepository = e2eTestApp.getRepository(AssetPersistence) + } catch (error) { + console.error("Error in beforeAll:", error) + throw error + } + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + if (e2eTestApp) { + await e2eTestApp.stop() + } + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + if (internalDistributionRepository) { + await E2eUtils.purgeOrRecreate(internalDistributionRepository) + } + if (internalAssetRepository) { + await E2eUtils.purgeOrRecreate(internalAssetRepository) + } + }, TestConstants.AFTER_EACH_TIMEOUT) + + it( + "should cancel distribution successfully", + async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + const distribution = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.ONE_OFF, + executeAt: faker.date.future(), + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: faker.helpers.objectValue(AmountType), + }, + status: DistributionStatus.SCHEDULED, + }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(distribution)) + + const endpoint = `${baseEndpoint}/${distribution.id}/cancel` + + await request(e2eTestApp.app.getHttpServer()).patch(endpoint).expect(HttpStatus.OK) + + const updatedDistribution = await internalDistributionRepository.findOneBy({ id: distribution.id }) + expect(updatedDistribution.status).toBe(DistributionStatus.CANCELLED) + }, + TestConstants.TEST_TIMEOUT, + ) +}) diff --git a/apps/mass-payout/backend/test/e2e/distribution/get-distribution-holders.e2e.spec.ts b/apps/mass-payout/backend/test/e2e/distribution/get-distribution-holders.e2e.spec.ts new file mode 100644 index 000000000..1bcb73b88 --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/distribution/get-distribution-holders.e2e.spec.ts @@ -0,0 +1,422 @@ +/* + * 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 to comply with Section 4(c) of the License and + * to reproduce 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 2024 IOBuilders + * + * 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. + */ + +import { TestConstants } from "@test/e2e/shared/test-constants" +import { Repository } from "typeorm" +import { E2eTestApp } from "@test/e2e/shared/e2e-test.app" +import { faker } from "@faker-js/faker" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { HttpStatus } from "@nestjs/common" +import { E2eUtils } from "@test/e2e/shared/e2e-utils" +import { AssetUtils } from "@test/shared/asset.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { BatchPayoutPersistence } from "@infrastructure/adapters/repositories/model/batch-payout.persistence" +import { HolderPersistence } from "@infrastructure/adapters/repositories/model/holder.persistence" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { HolderStatus } from "@domain/model/holder" +import { fakeHederaAddress } from "@test/shared/utils" +import request from "supertest" + +describe("GET /distributions/:distributionId/holders", () => { + let e2eTestApp: E2eTestApp + let internalDistributionRepository: Repository + let internalAssetRepository: Repository + let internalBatchPayoutRepository: Repository + let internalHolderRepository: Repository + + const baseEndpoint = "/distributions" + + beforeAll(async () => { + try { + e2eTestApp = await E2eTestApp.create() + if (!e2eTestApp) { + throw new Error("E2eTestApp.create() returned undefined") + } + internalDistributionRepository = e2eTestApp.getRepository(DistributionPersistence) + internalAssetRepository = e2eTestApp.getRepository(AssetPersistence) + internalBatchPayoutRepository = e2eTestApp.getRepository(BatchPayoutPersistence) + internalHolderRepository = e2eTestApp.getRepository(HolderPersistence) + } catch (error) { + console.error("Error in beforeAll:", error) + throw error + } + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + if (e2eTestApp) { + await e2eTestApp.stop() + } + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + if (internalHolderRepository) { + await E2eUtils.purgeOrRecreate(internalHolderRepository) + } + if (internalBatchPayoutRepository) { + await E2eUtils.purgeOrRecreate(internalBatchPayoutRepository) + } + if (internalDistributionRepository) { + await E2eUtils.purgeOrRecreate(internalDistributionRepository) + } + if (internalAssetRepository) { + await E2eUtils.purgeOrRecreate(internalAssetRepository) + } + }) + + const createTestData = async () => { + // Create asset + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + + // Create distribution + const distribution = DistributionUtils.newInstance({ asset }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(distribution)) + + // Create batch payout + const batchPayout = BatchPayoutUtils.newInstance({ distribution }) + await internalBatchPayoutRepository.save(BatchPayoutPersistence.fromBatchPayout(batchPayout)) + + const holders = [ + { + id: faker.string.uuid(), + batchPayoutId: batchPayout.id, + holderHederaAddress: fakeHederaAddress(), + holderEvmAddress: faker.finance.ethereumAddress(), + retryCounter: 1, + status: HolderStatus.FAILED, + lastError: "Insufficient balance", + nextRetryAt: new Date(), + createdAt: new Date(), + updatedAt: new Date(), + }, + { + id: faker.string.uuid(), + batchPayoutId: batchPayout.id, + holderHederaAddress: fakeHederaAddress(), + holderEvmAddress: faker.finance.ethereumAddress(), + retryCounter: 2, + status: HolderStatus.SUCCESS, + amount: "100.99", + lastError: "Network error", + nextRetryAt: new Date(), + createdAt: new Date(), + updatedAt: new Date(), + }, + ] + + await internalHolderRepository.save(holders) + + return { distribution, batchPayout, holders } + } + + it("should return paginated holders for a distribution", async () => { + // Arrange + const { distribution, holders } = await createTestData() + const endpoint = `${baseEndpoint}/${distribution.id}/holders` + const page = 1 + const limit = 10 + + // Act + const response = await request(e2eTestApp.app.getHttpServer()) + .get(endpoint) + .query({ page, limit, order: "DESC", orderBy: "createdAt" }) + .expect(HttpStatus.OK) + + // Assert + expect(response.body).toMatchObject({ + items: expect.arrayContaining([ + expect.objectContaining({ + id: holders[0].id, + holderHederaAddress: holders[0].holderHederaAddress, + holderEvmAddress: holders[0].holderEvmAddress, + retryCounter: holders[0].retryCounter, + status: holders[0].status, + lastError: holders[0].lastError, + createdAt: holders[0].createdAt.toISOString(), + updatedAt: holders[0].updatedAt.toISOString(), + }), + expect.objectContaining({ + id: holders[1].id, + holderHederaAddress: holders[1].holderHederaAddress, + holderEvmAddress: holders[1].holderEvmAddress, + retryCounter: holders[1].retryCounter, + status: holders[1].status, + amount: holders[1].amount, + lastError: holders[1].lastError, + createdAt: holders[1].createdAt.toISOString(), + updatedAt: holders[1].updatedAt.toISOString(), + }), + ]), + total: 2, + page, + limit, + totalPages: 1, + }) + }) + + it("should return empty page when no holders exist for distribution", async () => { + // Arrange + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + + const distribution = DistributionUtils.newInstance({ asset }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(distribution)) + + const endpoint = `${baseEndpoint}/${distribution.id}/holders` + const page = 1 + const limit = 10 + + // Act + const response = await request(e2eTestApp.app.getHttpServer()) + .get(endpoint) + .query({ page, limit }) + .expect(HttpStatus.OK) + + // Assert + expect(response.body).toEqual({ + items: [], + total: 0, + page, + limit, + totalPages: 0, + }) + }) + + it("should return 404 when distribution does not exist", async () => { + // Arrange + const nonExistentId = faker.string.uuid() + const endpoint = `${baseEndpoint}/${nonExistentId}/holders` + + // Act & Assert + await request(e2eTestApp.app.getHttpServer()) + .get(endpoint) + .query({ page: 1, limit: 10 }) + .expect(HttpStatus.NOT_FOUND) + }) + + it("should respect pagination parameters", async () => { + // Arrange + const { distribution } = await createTestData() + const endpoint = `${baseEndpoint}/${distribution.id}/holders` + const page = 1 + const limit = 1 + + // Act + const response = await request(e2eTestApp.app.getHttpServer()) + .get(endpoint) + .query({ page, limit }) + .expect(HttpStatus.OK) + + // Assert + expect(response.body).toMatchObject({ + items: expect.any(Array), + total: 2, // We created 2 holders + page, + limit, + totalPages: 2, + }) + expect(response.body.items).toHaveLength(1) // Should return only 1 item due to limit=1 + }) +}) diff --git a/apps/mass-payout/backend/test/e2e/distribution/get-distributions.e2e.spec.ts b/apps/mass-payout/backend/test/e2e/distribution/get-distributions.e2e.spec.ts new file mode 100644 index 000000000..6b2dd3e51 --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/distribution/get-distributions.e2e.spec.ts @@ -0,0 +1,420 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetType } from "@domain/model/asset-type.enum" +import { CorporateActionDetails, DistributionStatus, DistributionType } from "@domain/model/distribution" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { faker } from "@faker-js/faker" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { HttpStatus } from "@nestjs/common" +import { E2eTestApp } from "@test/e2e/shared/e2e-test.app" +import { E2eUtils } from "@test/e2e/shared/e2e-utils" +import { TestConstants } from "@test/e2e/shared/test-constants" +import { AssetUtils } from "@test/shared/asset.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { fakeHederaAddress } from "@test/shared/utils" +import request from "supertest" +import { Repository } from "typeorm" + +describe("GET /distributions", () => { + let e2eTestApp: E2eTestApp + let internalDistributionRepository: Repository + let internalAssetRepository: Repository + const endpoint = "/distributions" + + beforeAll(async () => { + try { + e2eTestApp = await E2eTestApp.create() + if (!e2eTestApp) { + throw new Error("E2eTestApp.create() returned undefined") + } + internalDistributionRepository = e2eTestApp.getRepository(DistributionPersistence) + internalAssetRepository = e2eTestApp.getRepository(AssetPersistence) + } catch (error) { + console.error("Error in beforeAll:", error) + throw error + } + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + if (e2eTestApp) { + await e2eTestApp.stop() + } + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + if (internalDistributionRepository) { + await E2eUtils.purgeOrRecreate(internalDistributionRepository) + } + if (internalAssetRepository) { + await E2eUtils.purgeOrRecreate(internalAssetRepository) + } + }, TestConstants.AFTER_EACH_TIMEOUT) + + it( + "should return paginated distributions successfully", + async () => { + const asset = AssetUtils.newInstance({ + name: "Test Asset", + type: AssetType.EQUITY, + hederaTokenAddress: fakeHederaAddress(), + evmTokenAddress: faker.finance.ethereumAddress(), + lifeCycleCashFlowHederaAddress: fakeHederaAddress(), + lifeCycleCashFlowEvmAddress: faker.finance.ethereumAddress(), + isPaused: false, + }) + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + + const executionDate1 = faker.date.future() + const executionDate2 = faker.date.future() + const distribution1 = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create("corp-action-1"), + executionDate: executionDate1, + }, + status: DistributionStatus.SCHEDULED, + }) + const distribution2 = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create("corp-action-2"), + executionDate: executionDate2, + }, + status: DistributionStatus.COMPLETED, + }) + + await internalDistributionRepository.save([ + DistributionPersistence.fromDistribution(distribution1), + DistributionPersistence.fromDistribution(distribution2), + ]) + + const response = await request(e2eTestApp.app.getHttpServer()) + .get(endpoint) + .query({ page: 1, limit: 10 }) + .expect(HttpStatus.OK) + + expect(response.body).toEqual({ + items: [ + { + id: distribution2.id, + asset: { + id: asset.id, + name: asset.name, + type: asset.type, + hederaTokenAddress: asset.hederaTokenAddress, + evmTokenAddress: asset.evmTokenAddress, + symbol: asset.symbol, + lifeCycleCashFlowHederaAddress: asset.lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: asset.lifeCycleCashFlowEvmAddress, + maturityDate: asset.maturityDate, + isPaused: asset.isPaused, + syncEnabled: asset.syncEnabled, + createdAt: expect.any(String), + updatedAt: expect.any(String), + }, + corporateActionID: (distribution2.details as CorporateActionDetails).corporateActionId.value, + executionDate: (distribution2.details as CorporateActionDetails).executionDate.toISOString(), + status: distribution2.status, + type: distribution2.details.type, + createdAt: expect.any(String), + updatedAt: expect.any(String), + }, + { + id: distribution1.id, + asset: { + id: asset.id, + name: asset.name, + type: asset.type, + hederaTokenAddress: asset.hederaTokenAddress, + evmTokenAddress: asset.evmTokenAddress, + symbol: asset.symbol, + lifeCycleCashFlowHederaAddress: asset.lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: asset.lifeCycleCashFlowEvmAddress, + maturityDate: asset.maturityDate, + isPaused: asset.isPaused, + syncEnabled: asset.syncEnabled, + createdAt: expect.any(String), + updatedAt: expect.any(String), + }, + corporateActionID: (distribution1.details as CorporateActionDetails).corporateActionId.value, + executionDate: (distribution1.details as CorporateActionDetails).executionDate.toISOString(), + status: distribution1.status, + type: distribution1.details.type, + createdAt: expect.any(String), + updatedAt: expect.any(String), + }, + ], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + }) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "should return empty page when no distributions exist", + async () => { + const response = await request(e2eTestApp.app.getHttpServer()) + .get(endpoint) + .query({ page: 1, limit: 10 }) + .expect(HttpStatus.OK) + + expect(response.body).toEqual({ + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + }) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "should handle pagination correctly", + async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + + const distributions = Array.from({ length: 15 }, () => DistributionUtils.newInstance({ asset })) + await internalDistributionRepository.save(distributions.map((d) => DistributionPersistence.fromDistribution(d))) + + const response = await request(e2eTestApp.app.getHttpServer()) + .get(endpoint) + .query({ page: 2, limit: 5 }) + .expect(HttpStatus.OK) + + expect(response.body.items).toHaveLength(5) + expect(response.body.total).toBe(15) + expect(response.body.page).toBe(2) + expect(response.body.limit).toBe(5) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "should use default pagination when no parameters provided", + async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + + const distribution = DistributionUtils.newInstance({ asset }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(distribution)) + + const response = await request(e2eTestApp.app.getHttpServer()).get(endpoint).expect(HttpStatus.OK) + + expect(response.body.items).toHaveLength(1) + expect(response.body.total).toBe(1) + expect(response.body.page).toBe(1) + expect(response.body.limit).toBe(10) + }, + TestConstants.TEST_TIMEOUT, + ) +}) diff --git a/apps/mass-payout/backend/test/e2e/distribution/retry-failed-holders.e2e.spec.ts b/apps/mass-payout/backend/test/e2e/distribution/retry-failed-holders.e2e.spec.ts new file mode 100644 index 000000000..fafd20a86 --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/distribution/retry-failed-holders.e2e.spec.ts @@ -0,0 +1,312 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AmountType, DistributionStatus, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { faker } from "@faker-js/faker" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { HttpStatus } from "@nestjs/common" +import { E2eTestApp } from "@test/e2e/shared/e2e-test.app" +import { E2eUtils } from "@test/e2e/shared/e2e-utils" +import { TestConstants } from "@test/e2e/shared/test-constants" +import { AssetUtils } from "@test/shared/asset.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import request from "supertest" +import { Repository } from "typeorm" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { BatchPayoutPersistence } from "@infrastructure/adapters/repositories/model/batch-payout.persistence" +import { HolderPersistence } from "@infrastructure/adapters/repositories/model/holder.persistence" +import { HolderUtils } from "@test/shared/holder.utils" +import { BatchPayoutStatus } from "@domain/model/batch-payout" +import { HolderStatus } from "@domain/model/holder" + +describe("PATCH /distributions/:distributionId/retry", () => { + let e2eTestApp: E2eTestApp + let internalDistributionRepository: Repository + let internalAssetRepository: Repository + let internalBatchPayoutRepository: Repository + let internalHolderRepository: Repository + const baseEndpoint = "/distributions" + + beforeAll(async () => { + try { + e2eTestApp = await E2eTestApp.create() + if (!e2eTestApp) { + throw new Error("E2eTestApp.create() returned undefined") + } + internalDistributionRepository = e2eTestApp.getRepository(DistributionPersistence) + internalAssetRepository = e2eTestApp.getRepository(AssetPersistence) + internalBatchPayoutRepository = e2eTestApp.getRepository(BatchPayoutPersistence) + internalHolderRepository = e2eTestApp.getRepository(HolderPersistence) + } catch (error) { + console.error("Error in beforeAll:", error) + throw error + } + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + if (e2eTestApp) { + await e2eTestApp.stop() + } + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + if (internalHolderRepository) { + await E2eUtils.purgeOrRecreate(internalHolderRepository) + } + if (internalBatchPayoutRepository) { + await E2eUtils.purgeOrRecreate(internalBatchPayoutRepository) + } + if (internalDistributionRepository) { + await E2eUtils.purgeOrRecreate(internalDistributionRepository) + } + if (internalAssetRepository) { + await E2eUtils.purgeOrRecreate(internalAssetRepository) + } + }, TestConstants.AFTER_EACH_TIMEOUT) + + it( + "should retry distribution failed holders successfully", + async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + const distribution = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.ONE_OFF, + executeAt: faker.date.future(), + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + status: DistributionStatus.FAILED, + }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(distribution)) + const batchPayout = BatchPayoutUtils.newInstance({ distribution, status: BatchPayoutStatus.FAILED }) + await internalBatchPayoutRepository.save(BatchPayoutPersistence.fromBatchPayout(batchPayout)) + const holder = HolderUtils.newInstance({ batchPayout, status: HolderStatus.FAILED }) + await internalHolderRepository.save(HolderPersistence.fromHolder(holder)) + + const executeDistributionResponse = { + failed: [], + succeeded: [holder.holderEvmAddress], + paidAmount: [(distribution.details as any).amount], + transactionId: "0.0.456@1234567891.987654321", + } as any + e2eTestApp.lifeCycleCashFlowMock.executeAmountSnapshotByAddresses.mockResolvedValue(executeDistributionResponse) + + const endpoint = `${baseEndpoint}/${distribution.id}/retry` + + await request(e2eTestApp.app.getHttpServer()).patch(endpoint).expect(HttpStatus.OK) + + const updatedDistribution = await internalDistributionRepository.findOneBy({ id: distribution.id }) + expect(updatedDistribution.status).toBe(DistributionStatus.COMPLETED) + const updatedbatchPayout = await internalBatchPayoutRepository.findOneBy({ id: batchPayout.id }) + expect(updatedbatchPayout.status).toBe(BatchPayoutStatus.COMPLETED) + const updatedHolder = await internalHolderRepository.findOneBy({ id: holder.id }) + expect(updatedHolder.status).toBe(HolderStatus.SUCCESS) + }, + TestConstants.TEST_TIMEOUT, + ) +}) diff --git a/apps/mass-payout/backend/test/e2e/import-asset/import-asset.e2e.spec.ts b/apps/mass-payout/backend/test/e2e/import-asset/import-asset.e2e.spec.ts new file mode 100644 index 000000000..8f47b2b16 --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/import-asset/import-asset.e2e.spec.ts @@ -0,0 +1,374 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetType } from "@domain/model/asset-type.enum" +import { LifeCycleCashFlowAddress } from "@domain/model/life-cycle-cash-flow-address.value-object" +import { GetAssetInfoResponse } from "@domain/ports/get-asset-info-response.interface" +import { faker } from "@faker-js/faker" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { HttpStatus } from "@nestjs/common" +import { E2eTestApp } from "@test/e2e/shared/e2e-test.app" +import { E2eUtils } from "@test/e2e/shared/e2e-utils" +import { TestConstants } from "@test/e2e/shared/test-constants" +import { fakeHederaAddress } from "@test/shared/utils" +import request from "supertest" +import { Repository } from "typeorm" + +describe("Import Asset", () => { + let e2eTestApp: E2eTestApp + let internalAssetRepository: Repository + const endpoint = "/assets/import" + + beforeAll(async () => { + e2eTestApp = await E2eTestApp.create() + internalAssetRepository = e2eTestApp.getRepository(AssetPersistence) + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + await e2eTestApp.stop() + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => await E2eUtils.purgeOrRecreate(internalAssetRepository), TestConstants.AFTER_EACH_TIMEOUT) + + it( + "should import the asset successfully", + async () => { + const payload = { + hederaTokenAddress: fakeHederaAddress(), + } + const getAssetInfoResponse: GetAssetInfoResponse = { + hederaTokenAddress: fakeHederaAddress(), + name: faker.commerce.productName(), + symbol: faker.finance.currencySymbol(), + assetType: AssetType.BOND, + } + e2eTestApp.assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(getAssetInfoResponse) + e2eTestApp.hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(faker.finance.ethereumAddress()) + e2eTestApp.hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(faker.finance.ethereumAddress()) + e2eTestApp.lifeCycleCashFlowMock.isPaused.mockResolvedValue(false) + e2eTestApp.lifeCycleCashFlowMock.deployContract.mockResolvedValue( + LifeCycleCashFlowAddress.create(fakeHederaAddress(), faker.finance.ethereumAddress()), + ) + + const response = await request((e2eTestApp as any).app.getHttpServer()) + .post(endpoint) + .send(payload) + .expect(HttpStatus.CREATED) + + const { body } = response + expect(body).toEqual( + expect.objectContaining({ + id: expect.any(String), + name: expect.any(String), + hederaTokenAddress: payload.hederaTokenAddress, + evmTokenAddress: expect.any(String), + createdAt: expect.any(String), + updatedAt: expect.any(String), + }), + ) + const persisted = await internalAssetRepository.findOneBy({ id: body.id }) + expect(persisted).not.toBeNull() + expect(persisted!.id).toBe(body.id) + expect(persisted!.hederaTokenAddress).toBe(body.hederaTokenAddress) + expect(persisted!.name).toBe(getAssetInfoResponse.name) + expect(persisted!.hederaTokenAddress).toBe(payload.hederaTokenAddress) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "returns 400 when hederaTokenAddress is empty", + async () => { + const payload = { hederaTokenAddress: "" } + + await request((e2eTestApp as any).app.getHttpServer()) + .post(endpoint) + .send(payload) + .expect(HttpStatus.BAD_REQUEST) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "returns 400 when hederaTokenAddress has an invalid format", + async () => { + const payload = { hederaTokenAddress: "invalid-address" } + + await request((e2eTestApp as any).app.getHttpServer()) + .post(endpoint) + .send(payload) + .expect(HttpStatus.BAD_REQUEST) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "returns 409 when duplicate hederaTokenAddress", + async () => { + const duplicatedHederaAddress = fakeHederaAddress() + const first = { hederaTokenAddress: duplicatedHederaAddress } + const second = { hederaTokenAddress: duplicatedHederaAddress } + + const getAssetInfoResponse: GetAssetInfoResponse = { + hederaTokenAddress: duplicatedHederaAddress, + name: faker.commerce.productName(), + symbol: faker.finance.currencySymbol(), + assetType: AssetType.BOND, + } + e2eTestApp.assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(getAssetInfoResponse) + e2eTestApp.hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(faker.finance.ethereumAddress()) + e2eTestApp.lifeCycleCashFlowMock.isPaused.mockResolvedValue(false) + e2eTestApp.lifeCycleCashFlowMock.deployContract.mockResolvedValue( + LifeCycleCashFlowAddress.create(fakeHederaAddress(), faker.finance.ethereumAddress()), + ) + + await request((e2eTestApp as any).app.getHttpServer()) + .post(endpoint) + .send(first) + .expect(HttpStatus.CREATED) + + await request((e2eTestApp as any).app.getHttpServer()) + .post(endpoint) + .send(second) + .expect(HttpStatus.CONFLICT) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "returns 500 when the database fails (e.g. missing table)", + async () => { + await internalAssetRepository.query('DROP TABLE IF EXISTS "Asset" CASCADE;') + const payload = { + hederaTokenAddress: fakeHederaAddress(), + } + + const getAssetInfoResponse: GetAssetInfoResponse = { + hederaTokenAddress: payload.hederaTokenAddress, + name: faker.commerce.productName(), + symbol: faker.finance.currencySymbol(), + assetType: AssetType.BOND, + } + e2eTestApp.assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(getAssetInfoResponse) + e2eTestApp.hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(faker.finance.ethereumAddress()) + e2eTestApp.lifeCycleCashFlowMock.isPaused.mockResolvedValue(false) + e2eTestApp.lifeCycleCashFlowMock.deployContract.mockResolvedValue( + LifeCycleCashFlowAddress.create(fakeHederaAddress(), faker.finance.ethereumAddress()), + ) + + const response = await request((e2eTestApp as any).app.getHttpServer()) + .post(endpoint) + .send(payload) + .expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(response.body).toEqual( + expect.objectContaining({ + statusCode: HttpStatus.INTERNAL_SERVER_ERROR, + message: expect.stringContaining("Internal server error"), + }), + ) + }, + TestConstants.TEST_TIMEOUT, + ) +}) diff --git a/apps/mass-payout/backend/test/e2e/scheduled-payouts/scheduled-payouts.e2e.spec.ts b/apps/mass-payout/backend/test/e2e/scheduled-payouts/scheduled-payouts.e2e.spec.ts new file mode 100644 index 000000000..85d7e0a1d --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/scheduled-payouts/scheduled-payouts.e2e.spec.ts @@ -0,0 +1,434 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Repository } from "typeorm" +import { E2eTestApp } from "@test/e2e/shared/e2e-test.app" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { BatchPayoutPersistence } from "@infrastructure/adapters/repositories/model/batch-payout.persistence" +import { MassPayoutCronService } from "@infrastructure/cron/mass-payout-cron.service" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { AssetUtils } from "@test/shared/asset.utils" +import { + Distribution, + DistributionStatus, + DistributionType, + PayoutSubtype, + Recurrency, +} from "@domain/model/distribution" +import { E2eUtils } from "@test/e2e/shared/e2e-utils" +import { TestConstants } from "@test/e2e/shared/test-constants" +import { Asset } from "@domain/model/asset" + +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { faker } from "@faker-js/faker/." +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { fakeHederaAddress } from "@test/shared/utils" + +describe("Scheduled Payouts Cron", () => { + let e2eTestApp: E2eTestApp + let internalDistributionRepository: Repository + let internalAssetRepository: Repository + let internalBatchPayoutRepository: Repository + let massPayoutCronService: MassPayoutCronService + + beforeAll(async () => { + e2eTestApp = await E2eTestApp.create() + internalDistributionRepository = e2eTestApp.getRepository(DistributionPersistence) + internalAssetRepository = e2eTestApp.getRepository(AssetPersistence) + internalBatchPayoutRepository = e2eTestApp.getRepository(BatchPayoutPersistence) + massPayoutCronService = e2eTestApp.app.get(MassPayoutCronService) + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + await e2eTestApp.stop() + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + e2eTestApp.onChainDistributionMock.clearMockData() + await E2eUtils.purgeOrRecreate(internalDistributionRepository) + await E2eUtils.purgeOrRecreate(internalBatchPayoutRepository) + }, TestConstants.AFTER_EACH_TIMEOUT) + + it( + "should process scheduled distributions for today when cron is triggered", + async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const pastDate = new Date(Date.now() - 2 * 60 * 60 * 1000) + const tomorrow = E2eUtils.getTomorrow() + const distributionTodayScheduled1 = await generateDistribution(pastDate) + const distributionTodayScheduled2 = await generateDistribution( + pastDate, + DistributionStatus.SCHEDULED, + DistributionType.PAYOUT, + ) + const distributionTomorrowScheduled = await generateDistribution(tomorrow) + const distributionTodayInProgress = await generateDistribution(pastDate, DistributionStatus.IN_PROGRESS) + const distributionTodayCompleted = await generateDistribution(pastDate, DistributionStatus.COMPLETED) + const executeDistributionResponseCorporateAction = { + failed: [], + succeeded: ["0x9876543210987654321098765432109876543210"], + paidAmount: ["1000.90"], + transactionId: "0.0.123@1234567890.123456789", + } as any + const executeDistributionResponsePayout = { + failed: ["0x1234567890123456789012345678901234567890"], + succeeded: [], + paidAmount: [], + transactionId: "0.0.456@1234567891.987654321", + } as any + + e2eTestApp.assetTokenizationStudioServiceMock.takeSnapshot.mockResolvedValueOnce(Number(snapshotId.value)) + e2eTestApp.hederaServiceMock.getHederaAddressFromEvm.mockImplementation((evmAddress: string) => { + if (evmAddress === "0x1234567890123456789012345678901234567890") { + return Promise.resolve("0.0.1001") + } else if (evmAddress === "0x9876543210987654321098765432109876543210") { + return Promise.resolve("0.0.1002") + } else { + return Promise.resolve(fakeHederaAddress()) + } + }) + e2eTestApp.hederaServiceMock.getParentHederaTransactionHash.mockResolvedValue({ + hederaTransactionHash: + "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", + isFromMirrorNode: true, + }) + e2eTestApp.lifeCycleCashFlowMock.executeDistribution.mockResolvedValue(executeDistributionResponseCorporateAction) + e2eTestApp.lifeCycleCashFlowMock.executeAmountSnapshot.mockResolvedValue(executeDistributionResponsePayout) + + await massPayoutCronService.handleScheduledPayouts() + + expect(e2eTestApp.lifeCycleCashFlowMock.executeDistribution).toHaveBeenCalled() + expect(e2eTestApp.lifeCycleCashFlowMock.executeAmountSnapshot).toHaveBeenCalled() + + const distributionsAfterCron = await internalDistributionRepository.find() + const processedDistribution1 = distributionsAfterCron.find((d) => d.id === distributionTodayScheduled1.id) + const processedDistribution2 = distributionsAfterCron.find((d) => d.id === distributionTodayScheduled2.id) + const unprocessedTomorrow = distributionsAfterCron.find((d) => d.id === distributionTomorrowScheduled.id) + const unprocessedInProgress = distributionsAfterCron.find((d) => d.id === distributionTodayInProgress.id) + const unprocessedCompleted = distributionsAfterCron.find((d) => d.id === distributionTodayCompleted.id) + const nextRecurring = distributionsAfterCron.find( + (d) => d.type === DistributionType.PAYOUT && d.id !== distributionTodayScheduled2.id, + ) + expect(processedDistribution1).toBeDefined() + expect(processedDistribution2).toBeDefined() + expect(processedDistribution1.status).toBe(DistributionStatus.COMPLETED) + expect(processedDistribution2.status).toBe(DistributionStatus.FAILED) + expect(processedDistribution2.snapshotId).toBe(snapshotId.value) + expect(unprocessedTomorrow?.status).toBe(DistributionStatus.SCHEDULED) + expect(unprocessedInProgress?.status).toBe(DistributionStatus.IN_PROGRESS) + expect(unprocessedCompleted?.status).toBe(DistributionStatus.COMPLETED) + expect(nextRecurring).toBeDefined() + expect(nextRecurring.status).toBe(DistributionStatus.SCHEDULED) + expect(nextRecurring.executionDate).toBeDefined() + expect(nextRecurring.type).toBe(DistributionType.PAYOUT) + expect(nextRecurring.subtype).toBe(PayoutSubtype.RECURRING) + expect(nextRecurring.amount).toBe(distributionTodayScheduled2.amount) + expect(nextRecurring.amountType).toBe(distributionTodayScheduled2.amountType) + expect(nextRecurring.recurrency).toBe(distributionTodayScheduled2.recurrency) + expect(distributionsAfterCron).toHaveLength(6) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "should handle empty distributions list when cron is triggered", + async () => { + await massPayoutCronService.handleScheduledPayouts() + + const distributions = await internalDistributionRepository.find() + expect(distributions).toHaveLength(0) + }, + TestConstants.TEST_TIMEOUT, + ) + + it( + "should process new distributions", + async () => { + const pastDate = new Date(Date.now() - 2 * 60 * 60 * 1000) + const futureDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) + const asset = await generateAndSaveAsset() + + await saveDistributionInMockedAts(asset, "corporateActionIdFuture", futureDate) + + const pastDistribution = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create("corporateActionIdToday"), + executionDate: pastDate, + }, + status: DistributionStatus.SCHEDULED, + }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(pastDistribution)) + + await massPayoutCronService.handleScheduledPayouts() + + const distributionsAfterCron = await internalDistributionRepository.find() + const pastDistributionAfter = distributionsAfterCron.find((d) => d.corporateActionID === "corporateActionIdToday") + const futureDistribution = distributionsAfterCron.find((d) => d.corporateActionID === "corporateActionIdFuture") + expect(pastDistributionAfter).toBeDefined() + expect(futureDistribution).toBeDefined() + expect(pastDistributionAfter?.status).toBe(DistributionStatus.COMPLETED) + expect(futureDistribution?.status).toBe(DistributionStatus.SCHEDULED) + expect(distributionsAfterCron).toHaveLength(2) + }, + TestConstants.TEST_TIMEOUT, + ) + + async function generateDistribution( + date: Date, + status: DistributionStatus = DistributionStatus.SCHEDULED, + type: DistributionType = DistributionType.CORPORATE_ACTION, + payoutSubtype: PayoutSubtype = PayoutSubtype.RECURRING, + ): Promise { + const asset = await generateAndSaveAsset() + const distribution = await generateAndSaveDistribution(asset, date, status, type, payoutSubtype) + if (distribution.details.type === DistributionType.CORPORATE_ACTION) { + await saveDistributionInMockedAts(asset, distribution.details.corporateActionId.value, date) + } + return DistributionPersistence.fromDistribution(distribution) + } + + async function generateAndSaveAsset(): Promise { + const asset = AssetUtils.newInstance() + let assetPersistence = AssetPersistence.fromAsset(asset) + assetPersistence = await internalAssetRepository.save(assetPersistence) + return assetPersistence.toAsset() + } + + async function generateAndSaveDistribution( + asset: Asset, + date: Date, + status: DistributionStatus, + type: DistributionType, + payoutSubtype: PayoutSubtype, + ): Promise { + const distribution = DistributionUtils.newInstance({ + asset, + details: { + type, + subtype: payoutSubtype, + corporateActionId: + type === DistributionType.CORPORATE_ACTION + ? CorporateActionId.create(faker.string.alpha({ length: 10 })) + : undefined, + executionDate: type === DistributionType.CORPORATE_ACTION ? date : undefined, + executeAt: type === DistributionType.PAYOUT ? date : undefined, + amount: type === DistributionType.PAYOUT ? faker.number.int({ min: 1, max: 1000 }).toString() : undefined, + recurrency: payoutSubtype === PayoutSubtype.RECURRING ? Recurrency.WEEKLY : undefined, + } as any, + status: status, + }) + + const distributionPersistence = await internalDistributionRepository.save( + DistributionPersistence.fromDistribution(distribution), + ) + return distributionPersistence.toDistribution() + } + + async function saveDistributionInMockedAts(asset: Asset, corporateActionID: string, date: Date): Promise { + e2eTestApp.onChainDistributionMock.addMockDistributionForAsset(asset, corporateActionID, date) + } +}) diff --git a/apps/mass-payout/backend/test/e2e/shared/e2e-test.app.ts b/apps/mass-payout/backend/test/e2e/shared/e2e-test.app.ts new file mode 100644 index 000000000..467e7b32f --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/shared/e2e-test.app.ts @@ -0,0 +1,305 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigurationModule } from "@config/configuration.module" +import { ENTITIES, PostgresModule } from "@config/postgres.module" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" +import { BlockchainEventListenerConfigRepository } from "@domain/ports/blockchain-event-config-repository.port" +import { BlockchainEventListenerService } from "@domain/ports/blockchain-event-listener.service" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { HederaService } from "@domain/ports/hedera.port" +import { createMock } from "@golevelup/ts-jest" +import { INestApplication } from "@nestjs/common" +import { Test, TestingModule } from "@nestjs/testing" +import { getRepositoryToken } from "@nestjs/typeorm" +import { EntityClassOrSchema } from "@nestjs/typeorm/dist/interfaces/entity-class-or-schema.type" +import { LifeCycleCashFlow } from "@mass-payout/sdk" +import { PostgreSqlContainer } from "@test/shared/containers/postgresql-container" +import { Repository } from "typeorm" +import { CONTROLLERS, PROVIDERS } from "../../../src/app.module-components" +import { MockOnChainDistributionRepository } from "./mocks/mock-on-chain-distribution.repository" + +export class E2eTestApp { + app: INestApplication + onChainDistributionMock: MockOnChainDistributionRepository + assetTokenizationStudioServiceMock = createMock() + lifeCycleCashFlowMock = createMock() + lifeCycleCashFlowSdkMock = createMock() + blockchainRepositoryMock = createMock() + blockchainConfigRepositoryMock = createMock() + hederaServiceMock = createMock() + + private appModule: TestingModule + private postgresqlContainer: PostgreSqlContainer + + public static async create(): Promise { + const e2eTestApp = new E2eTestApp() + await e2eTestApp.initContainers() + + e2eTestApp.appModule = await e2eTestApp.compileTestingModule() + e2eTestApp.app = e2eTestApp.appModule.createNestApplication() + e2eTestApp.onChainDistributionMock = e2eTestApp.app.get("OnChainDistributionRepositoryPort") + await e2eTestApp.app.init() + return e2eTestApp + } + + public async initContainers() { + this.postgresqlContainer = await PostgreSqlContainer.create() + } + + public async compileTestingModule() { + const metadata = { + imports: [ + ConfigurationModule.forRoot("/.env.test"), + PostgresModule.forRoot(this.postgresqlContainer.getConfig(), ENTITIES), + ], + controllers: [...CONTROLLERS], + providers: [ + ...PROVIDERS, + { + provide: "AssetTokenizationStudioService", + useValue: this.assetTokenizationStudioServiceMock, + }, + { + provide: "OnChainDistributionRepositoryPort", + useClass: MockOnChainDistributionRepository, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useValue: this.lifeCycleCashFlowMock, + }, + { + provide: LifeCycleCashFlow, + useValue: this.lifeCycleCashFlowSdkMock, + }, + { + provide: "BlockchainEventRepository", + useValue: this.blockchainRepositoryMock, + }, + { + provide: "BlockchainEventListenerConfigRepository", + useValue: this.blockchainConfigRepositoryMock, + }, + { + provide: "HederaService", + useValue: this.hederaServiceMock, + }, + ], + } + return await Test.createTestingModule(metadata).compile() + } + + public async stop() { + await this.app.close() + await this.stopContainers() + } + + public getRepository(entityClass: EntityClassOrSchema): Repository | any { + return this.app.get(getRepositoryToken(entityClass)) + } + + private async stopContainers() { + await this.postgresqlContainer.stop() + } +} diff --git a/apps/mass-payout/backend/test/e2e/shared/e2e-utils.ts b/apps/mass-payout/backend/test/e2e/shared/e2e-utils.ts new file mode 100644 index 000000000..7f39983c8 --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/shared/e2e-utils.ts @@ -0,0 +1,247 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { faker } from "@faker-js/faker" +import { Repository } from "typeorm" +import { TestConstants } from "@test/e2e/shared/test-constants" + +// https://www.postgresql.org/docs/current/errcodes-appendix.html +const PG_SQLSTATE_UNDEFINED_TABLE = "42P01" + +export class E2eUtils { + static getToday(): Date { + const now = new Date() + const nowPlusMargin = new Date(now.getTime() + TestConstants.TEST_TIMEOUT) + + const dayEnd = new Date(nowPlusMargin) + dayEnd.setHours(23, 59, 59, 999) + + return faker.date.between({ from: nowPlusMargin, to: dayEnd }) + } + + static getTomorrow(): Date { + const tomorrow = new Date(this.getToday()) + tomorrow.setDate(tomorrow.getDate() + 1) + return tomorrow + } + + static getOneWeekFromNow(): Date { + const oneWeekFromNow = new Date(this.getToday()) + oneWeekFromNow.setDate(oneWeekFromNow.getDate() + 7) + return oneWeekFromNow + } + + static async purgeOrRecreate(repository: Repository) { + try { + const tableName = repository.metadata.tableName + await repository.query(`TRUNCATE TABLE "${tableName}" CASCADE`) + } catch (error: any) { + const notAnUndefinedTableError = error.code !== PG_SQLSTATE_UNDEFINED_TABLE + if (notAnUndefinedTableError) { + throw error + } + await repository.manager.connection.synchronize() + } + } +} diff --git a/apps/mass-payout/backend/test/e2e/shared/mocks/mock-on-chain-distribution.repository.ts b/apps/mass-payout/backend/test/e2e/shared/mocks/mock-on-chain-distribution.repository.ts new file mode 100644 index 000000000..d4bcc1e10 --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/shared/mocks/mock-on-chain-distribution.repository.ts @@ -0,0 +1,276 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Injectable } from "@nestjs/common" +import { OnChainDistributionRepositoryPort } from "@domain/ports/on-chain-distribution-repository.port" +import { Distribution, DistributionStatus } from "@domain/model/distribution" +import { Asset } from "@domain/model/asset" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import * as crypto from "crypto" + +/** + * Mock implementation of OnChainDistributionRepositoryPort for E2E tests. + * This prevents real calls to the ATS SDK during testing while allowing + * configurable responses for different test scenarios. + */ +@Injectable() +export class MockOnChainDistributionRepository implements OnChainDistributionRepositoryPort { + private mockDistributions: Map = new Map() + private defaultHoldersCount = 1 + + addMockDistributionForAsset(asset: Asset, corporateActionId: string, executionDate: Date): void { + const existing = this.mockDistributions.get(asset.id) || [] + const corporateActionIdObj = CorporateActionId.create(corporateActionId) + const now = new Date() + + let distribution: Distribution + if (executionDate <= now) { + distribution = Distribution.createExistingCorporateAction( + crypto.randomUUID(), + asset, + corporateActionIdObj, + executionDate, + DistributionStatus.SCHEDULED, + new Date(), + new Date(), + ) + } else { + distribution = Distribution.createCorporateAction(asset, corporateActionIdObj, executionDate) + } + + existing.push(distribution) + this.mockDistributions.set(asset.id, existing) + } + + clearMockData(): void { + this.mockDistributions.clear() + this.defaultHoldersCount = 1 + } + + getAllDistributionsByAsset(asset: Asset): Promise { + const distributions = this.mockDistributions.get(asset.id) || [] + const now = new Date() + + const futureDistributions = distributions + .filter((distribution) => { + const details = distribution.details as any + return details.executionDate > now + }) + .sort((a, b) => { + const aDate = (a.details as any).executionDate + const bDate = (b.details as any).executionDate + return aDate.getTime() - bDate.getTime() + }) + + return Promise.resolve(futureDistributions) + } + + getHoldersCountForCorporateActionId(distribution: Distribution): Promise { + return Promise.resolve(this.defaultHoldersCount) + } + + getHoldersCountForSnapshotId(distribution: Distribution): Promise { + return Promise.resolve(this.defaultHoldersCount) + } +} diff --git a/apps/mass-payout/backend/test/e2e/shared/test-constants.ts b/apps/mass-payout/backend/test/e2e/shared/test-constants.ts new file mode 100644 index 000000000..578443199 --- /dev/null +++ b/apps/mass-payout/backend/test/e2e/shared/test-constants.ts @@ -0,0 +1,210 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export class TestConstants { + static BEFORE_ALL_TIMEOUT = 120_000 + static AFTER_ALL_TIMEOUT = 120_000 + static AFTER_EACH_TIMEOUT = 60_000 + static TEST_TIMEOUT = 30_000 +} diff --git a/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-asset.repository.spec.ts b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-asset.repository.spec.ts new file mode 100644 index 000000000..7d3d66cab --- /dev/null +++ b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-asset.repository.spec.ts @@ -0,0 +1,551 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigurationModule } from "@config/configuration.module" +import { ENTITIES, PostgresModule } from "@config/postgres.module" +import { CustomError } from "@domain/errors/shared/custom.error" +import { OrderPageOptions } from "@domain/model/page" +import { AssetRepositoryError } from "@infrastructure/adapters/repositories/errors/asset.repository.error" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { AssetTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-asset.repository" +import { Test, TestingModule } from "@nestjs/testing" +import { getRepositoryToken } from "@nestjs/typeorm" +import { AssetUtils } from "@test/shared/asset.utils" +import { PostgreSqlContainer } from "@test/shared/containers/postgresql-container" +import { fakeLifeCycleCashFlowAddress, TestConstants } from "@test/shared/utils" +import crypto from "crypto" +import { Repository } from "typeorm" + +// https://www.postgresql.org/docs/current/errcodes-appendix.html +export const PG_SQLSTATE_UNIQUE_VIOLATION = "23505" + +describe(AssetTypeOrmRepository.name, () => { + let assetRepository: AssetTypeOrmRepository + let internalAssetRepository: Repository + let container: PostgreSqlContainer + + beforeAll(async () => { + container = await PostgreSqlContainer.create() + const module: TestingModule = await Test.createTestingModule({ + imports: [ConfigurationModule.forRoot("/.env.test"), PostgresModule.forRoot(container.getConfig(), ENTITIES)], + providers: [AssetTypeOrmRepository], + }).compile() + + assetRepository = module.get(AssetTypeOrmRepository) + internalAssetRepository = module.get>(getRepositoryToken(AssetPersistence)) + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + await container.stop() + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + const assets = await internalAssetRepository.find() + await internalAssetRepository.remove(assets) + }) + + describe("saveAsset", () => { + it("should save an asset successfully", async () => { + const asset = AssetUtils.newInstanceWithLifeCycleCashFlow() + await expect(assetRepository.saveAsset(asset)).resolves.toEqual(asset) + }) + + it("should throw error if database error happens", async () => { + const asset = AssetUtils.newInstance() + const databaseError = new Error("Database error") + + jest.spyOn(internalAssetRepository, "insert").mockImplementationOnce(() => { + throw databaseError + }) + + let thrownError: CustomError + try { + await assetRepository.saveAsset(asset) + } catch (error) { + thrownError = error + } + + expect(thrownError).toBeInstanceOf(AssetRepositoryError) + expect(thrownError.originalError).toBe(databaseError) + expect(thrownError.message).toBe(AssetRepositoryError.ERRORS.SAVE_ASSET(asset)) + }) + }) + + describe("updateAsset", () => { + it("should update an asset successfully", async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset)) + + const initialSaved = await internalAssetRepository.findOne({ where: { id: asset.id } }) + expect(initialSaved.lifeCycleCashFlowHederaAddress).toBeNull() + expect(initialSaved.lifeCycleCashFlowEvmAddress).toBeNull() + const lifeCycleCashFlowAddress = fakeLifeCycleCashFlowAddress() + const assetWithLifeCycleCashFlow = asset.withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + await expect(assetRepository.updateAsset(assetWithLifeCycleCashFlow)).resolves.toEqual(assetWithLifeCycleCashFlow) + + const foundAsset = await assetRepository.getAsset(asset.id) + expect(foundAsset).toEqual(assetWithLifeCycleCashFlow) + }) + + it("should throw error if database error happens", async () => { + const asset = AssetUtils.newInstance() + const databaseError = new Error("Database error") + + jest.spyOn(internalAssetRepository, "update").mockImplementationOnce(() => { + throw databaseError + }) + + let thrownError: CustomError + try { + await assetRepository.updateAsset(asset) + } catch (error) { + thrownError = error + } + + expect(thrownError).toBeInstanceOf(AssetRepositoryError) + expect(thrownError.originalError).toBe(databaseError) + expect(thrownError.message).toBe(AssetRepositoryError.ERRORS.UPDATE_ASSET(asset.id)) + }) + }) + + describe("getAsset", () => { + it("should get an asset by id successfully", async () => { + const asset = AssetUtils.newInstanceWithLifeCycleCashFlow() + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset)) + const found = await assetRepository.getAsset(asset.id) + expect(found).toEqual(asset) + }) + + it("should return undefined if asset is not found by id", async () => { + const found = await assetRepository.getAsset(crypto.randomUUID()) + expect(found).toBeUndefined() + }) + + it("should throw error if database error happens", async () => { + const asset = AssetUtils.newInstance() + const databaseError = new Error("Database error") + + jest.spyOn(internalAssetRepository, "findOne").mockImplementationOnce(() => { + throw databaseError + }) + + let thrownError: CustomError + try { + await assetRepository.getAsset(asset.id) + } catch (error) { + thrownError = error + } + + expect(thrownError).toBeInstanceOf(AssetRepositoryError) + expect(thrownError.originalError).toBe(databaseError) + expect(thrownError.message).toBe(AssetRepositoryError.ERRORS.GET_ASSET(asset.id)) + }) + }) + + describe("getAssetByName", () => { + it("should find an asset by name", async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset)) + + const found = await assetRepository.getAssetByName(asset.name) + + expect(found).toEqual(asset) + }) + + it("should fail when duplicated name", async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset)) + const assetWithSameName = AssetUtils.newInstance({ name: asset.name }) + let error: Error + try { + await assetRepository.saveAsset(assetWithSameName) + } catch (e) { + error = e + } + + expect(error).toBeInstanceOf(AssetRepositoryError) + expect(error.message).toBe( + AssetRepositoryError.ERRORS.DUPLICATED_ASSET(assetWithSameName.name, assetWithSameName.hederaTokenAddress), + ) + expect((error as AssetRepositoryError).originalError.message).toContain( + "duplicate key value violates unique constraint", + ) + }) + + it("should throw error if database error happens", async () => { + const asset = AssetUtils.newInstance() + const databaseError = new Error("Database error") + + jest.spyOn(internalAssetRepository, "findOne").mockImplementationOnce(() => { + throw databaseError + }) + + let thrownError: CustomError + try { + await assetRepository.getAssetByName(asset.name) + } catch (error) { + thrownError = error + } + + expect(thrownError).toBeInstanceOf(AssetRepositoryError) + expect(thrownError.originalError).toBe(databaseError) + expect(thrownError.message).toBe(AssetRepositoryError.ERRORS.GET_ASSET_BY_NAME(asset.name)) + }) + }) + + describe("getAssetByHederaTokenAddress", () => { + it("should find an asset by hederaTokenAddress", async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset)) + + const found = await assetRepository.getAssetByHederaTokenAddress(asset.hederaTokenAddress) + + expect(found).toEqual(asset) + }) + + it("should fail with a duplicated hederaTokenAddress", async () => { + const asset = AssetUtils.newInstance() + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset)) + const assetWithSameHederaTokenAddress = AssetUtils.newInstance({ hederaTokenAddress: asset.hederaTokenAddress }) + let error: Error + + try { + await assetRepository.saveAsset(assetWithSameHederaTokenAddress) + } catch (e) { + error = e + } + + expect(error).toBeInstanceOf(AssetRepositoryError) + expect(error.message).toBe( + AssetRepositoryError.ERRORS.DUPLICATED_ASSET( + assetWithSameHederaTokenAddress.name, + assetWithSameHederaTokenAddress.hederaTokenAddress, + ), + ) + expect((error as AssetRepositoryError).originalError.message).toContain( + "duplicate key value violates unique constraint", + ) + }) + + it("should throw error if database error happens", async () => { + const asset = AssetUtils.newInstance() + const databaseError = new Error("Database error") + + jest.spyOn(internalAssetRepository, "findOne").mockImplementationOnce(() => { + throw databaseError + }) + + let thrownError: CustomError + try { + await assetRepository.getAssetByHederaTokenAddress(asset.hederaTokenAddress) + } catch (error) { + thrownError = error + } + + expect(thrownError).toBeInstanceOf(AssetRepositoryError) + expect(thrownError.originalError).toBe(databaseError) + expect(thrownError.message).toBe( + AssetRepositoryError.ERRORS.GET_ASSET_BY_HEDERA_TOKEN_ADDRESS(asset.hederaTokenAddress), + ) + }) + }) + + describe("deleteAssets", () => { + it("should delete assets by ids", async () => { + const asset1 = AssetUtils.newInstance() + const asset2 = AssetUtils.newInstance({ name: "Asset 2" }) + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset1)) + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset2)) + await assetRepository.deleteAssets([asset1.id, asset2.id]) + const all = await internalAssetRepository.find() + expect(all).toHaveLength(0) + }) + + it("should throw error if database error happens", async () => { + const asset = AssetUtils.newInstance() + const databaseError = new Error("Database error") + + jest.spyOn(internalAssetRepository, "delete").mockImplementationOnce(() => { + throw databaseError + }) + + let thrownError: CustomError + try { + await assetRepository.deleteAssets([asset.id]) + } catch (error) { + thrownError = error + } + + expect(thrownError).toBeInstanceOf(AssetRepositoryError) + expect(thrownError.originalError).toBe(databaseError) + expect(thrownError.message).toBe(AssetRepositoryError.ERRORS.DELETE_ASSETS([asset.id])) + }) + }) + + describe("getAllAssets", () => { + it("should get all assets", async () => { + const asset1 = AssetUtils.newInstance() + const asset2 = AssetUtils.newInstance({ name: "Asset 2" }) + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset1)) + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset2)) + const all = await assetRepository.getAllAssets() + expect(all).toHaveLength(2) + expect(all).toEqual( + expect.arrayContaining([ + expect.objectContaining({ name: asset1.name }), + expect.objectContaining({ name: asset2.name }), + ]), + ) + }) + + it("should throw error if database error happens", async () => { + const databaseError = new Error("Database error") + + jest.spyOn(internalAssetRepository, "find").mockImplementationOnce(() => { + throw databaseError + }) + + let thrownError: CustomError + try { + await assetRepository.getAllAssets() + } catch (error) { + thrownError = error + } + + expect(thrownError).toBeInstanceOf(AssetRepositoryError) + expect(thrownError.originalError).toBe(databaseError) + expect(thrownError.message).toBe(AssetRepositoryError.ERRORS.GET_ASSETS()) + }) + }) + + describe("getAssets", () => { + it("should return first page of assets with pagination", async () => { + // Given + const assets = [ + AssetUtils.newInstance({ name: "Asset 1" }), + AssetUtils.newInstance({ name: "Asset 2" }), + AssetUtils.newInstance({ name: "Asset 3" }), + ] + + for (const asset of assets) { + await internalAssetRepository.insert(AssetPersistence.fromAsset(asset)) + } + + // When + const pageOptions = { page: 1, limit: 2, order: OrderPageOptions.DEFAULT } + const result = await assetRepository.getAssets(pageOptions) + + // Then + expect(result.items).toHaveLength(2) + expect(result.total).toBe(3) + expect(result.page).toBe(1) + expect(result.limit).toBe(2) + expect(result.totalPages).toBe(2) + + const names = result.items.map((item) => item.name) + expect(names).toEqual(expect.arrayContaining([expect.stringMatching(/Asset [12]/)])) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-batch-payout.repository.spec.ts b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-batch-payout.repository.spec.ts new file mode 100644 index 000000000..a83206611 --- /dev/null +++ b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-batch-payout.repository.spec.ts @@ -0,0 +1,542 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigurationModule } from "@config/configuration.module" +import { ENTITIES, PostgresModule } from "@config/postgres.module" +import { Distribution } from "@domain/model/distribution" +import { faker } from "@faker-js/faker" +import { BatchPayoutPersistence } from "@infrastructure/adapters/repositories/model/batch-payout.persistence" +import { BatchPayoutTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-batch-payout.repository" +import { Test, TestingModule } from "@nestjs/testing" +import { getRepositoryToken } from "@nestjs/typeorm" +import { PostgreSqlContainer } from "@test/shared/containers/postgresql-container" +import { fakeHederaTxId, TestConstants } from "@test/shared/utils" +import crypto from "crypto" +import { Repository } from "typeorm" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { Asset } from "@domain/model/asset" +import { AssetUtils } from "@test/shared/asset.utils" +import { BatchPayout, BatchPayoutStatus } from "@domain/model/batch-payout" +import { BatchPayoutRepositoryError } from "@infrastructure/adapters/repositories/errors/batch-payout.repository.error" + +describe(BatchPayoutTypeOrmRepository.name, () => { + let batchPayoutRepository: BatchPayoutTypeOrmRepository + let internalBatchPayoutRepository: Repository + let internalDistributionRepository: Repository + let internalAssetRepository: Repository + let container: PostgreSqlContainer + + beforeAll(async () => { + container = await PostgreSqlContainer.create() + const module: TestingModule = await Test.createTestingModule({ + imports: [ConfigurationModule.forRoot("/.env.test"), PostgresModule.forRoot(container.getConfig(), ENTITIES)], + providers: [BatchPayoutTypeOrmRepository], + }).compile() + + batchPayoutRepository = module.get(BatchPayoutTypeOrmRepository) + internalAssetRepository = module.get>(getRepositoryToken(AssetPersistence)) + internalDistributionRepository = module.get>( + getRepositoryToken(DistributionPersistence), + ) + internalBatchPayoutRepository = module.get>( + getRepositoryToken(BatchPayoutPersistence), + ) + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterEach(async () => { + await internalBatchPayoutRepository.deleteAll() + await internalDistributionRepository.deleteAll() + await internalAssetRepository.deleteAll() + }) + + afterAll(async () => { + await container.stop() + }, TestConstants.AFTER_ALL_TIMEOUT) + + describe("saveBatchPayout", () => { + it("should save a batch payout", async () => { + const distribution = await saveDistribution() + const batchPayout = BatchPayoutUtils.newInstance({ distribution }) + + const savedBatchPayout = await batchPayoutRepository.saveBatchPayout(batchPayout) + + expect(savedBatchPayout).toBeDefined() + expect(savedBatchPayout.id).toStrictEqual(batchPayout.id) + expect(savedBatchPayout.distribution).toStrictEqual(batchPayout.distribution) + expect(savedBatchPayout.name).toStrictEqual(batchPayout.name) + expect(savedBatchPayout.hederaTransactionHash).toStrictEqual(batchPayout.hederaTransactionHash) + expect(savedBatchPayout.hederaTransactionId).toStrictEqual(batchPayout.hederaTransactionId) + expect(savedBatchPayout.hederaTransactionHash).toStrictEqual(batchPayout.hederaTransactionHash) + expect(savedBatchPayout.holdersNumber).toStrictEqual(batchPayout.holdersNumber) + expect(savedBatchPayout.status).toStrictEqual(batchPayout.status) + }) + + it("should throw BatchPayoutRepositoryError when saving fails", async () => { + const distribution = await saveDistribution() + const batchPayout = BatchPayoutUtils.newInstance({ distribution }) + jest.spyOn(internalBatchPayoutRepository, "insert").mockRejectedValueOnce(new Error("DB error")) + + await expect(batchPayoutRepository.saveBatchPayout(batchPayout)).rejects.toThrow( + new BatchPayoutRepositoryError(BatchPayoutRepositoryError.ERRORS.SAVE_BATCH_PAYOUT(batchPayout)), + ) + }) + }) + + describe("saveBatchPayouts", () => { + it("should save multiple batch payouts", async () => { + const distribution = await saveDistribution() + const name1 = faker.string.alpha({ length: 10 }) + const name2 = faker.string.alpha({ length: 10 }) + const batchPayouts = [ + BatchPayoutUtils.newInstance({ name: name1, distribution }), + BatchPayoutUtils.newInstance({ name: name2, distribution }), + ] + + const savedBatchPayouts = await batchPayoutRepository.saveBatchPayouts(batchPayouts) + + expect(savedBatchPayouts).toHaveLength(2) + const resultNames = savedBatchPayouts.map((b) => b.name) + expect(resultNames).toEqual(expect.arrayContaining([name1, name2])) + }) + + it("should throw BatchPayoutRepositoryError when saving multiple payouts fails", async () => { + const distribution = await saveDistribution() + const batchPayouts = [ + BatchPayoutUtils.newInstance({ distribution }), + BatchPayoutUtils.newInstance({ distribution }), + ] + jest.spyOn(internalBatchPayoutRepository, "insert").mockRejectedValueOnce(new Error("DB error")) + + await expect(batchPayoutRepository.saveBatchPayouts(batchPayouts)).rejects.toThrow( + new BatchPayoutRepositoryError(BatchPayoutRepositoryError.ERRORS.SAVE_BATCH_PAYOUTS(batchPayouts)), + ) + }) + }) + + describe("getBatchPayout", () => { + it("should return a batch payout by id", async () => { + const batchPayout = await saveBatchPayout() + + const foundBatchPayout = await batchPayoutRepository.getBatchPayout(batchPayout.id) + + expect(foundBatchPayout).toBeDefined() + expect(foundBatchPayout?.id).toStrictEqual(batchPayout.id) + expect(foundBatchPayout?.name).toStrictEqual(batchPayout.name) + expect(foundBatchPayout?.distribution).toStrictEqual(batchPayout.distribution) + expect(foundBatchPayout?.hederaTransactionHash).toStrictEqual(batchPayout.hederaTransactionHash) + expect(foundBatchPayout?.hederaTransactionId).toStrictEqual(batchPayout.hederaTransactionId) + expect(foundBatchPayout?.hederaTransactionHash).toStrictEqual(batchPayout.hederaTransactionHash) + expect(foundBatchPayout?.holdersNumber).toStrictEqual(batchPayout.holdersNumber) + expect(foundBatchPayout?.status).toStrictEqual(batchPayout.status) + }) + + it("should return undefined when batch payout not found", async () => { + const nonExistentId = crypto.randomUUID() + const foundBatchPayout = await batchPayoutRepository.getBatchPayout(nonExistentId) + expect(foundBatchPayout).toBeUndefined() + }) + + it("should throw BatchPayoutRepositoryError when getting batch payout fails", async () => { + const id = crypto.randomUUID() + jest.spyOn(internalBatchPayoutRepository, "findOne").mockRejectedValueOnce(new Error("DB error")) + + await expect(batchPayoutRepository.getBatchPayout(id)).rejects.toThrow( + new BatchPayoutRepositoryError(BatchPayoutRepositoryError.ERRORS.GET_BATCH_PAYOUT(id)), + ) + }) + }) + + describe("getBatchPayoutsByDistribution", () => { + it("should return batch payouts by distribution", async () => { + const distribution = await saveDistribution() + const good1 = await saveBatchPayout(distribution) + const good2 = await saveBatchPayout(distribution) + await saveBatchPayout() + const foundBatchPayouts = await batchPayoutRepository.getBatchPayoutsByDistribution(distribution) + + expect(foundBatchPayouts).toHaveLength(2) + expect(foundBatchPayouts.every((b) => b.distribution.id === distribution.id)).toBe(true) + const resultIds = foundBatchPayouts.map((b) => b.id) + expect(resultIds).toEqual(expect.arrayContaining([good1.id, good2.id])) + const sample = foundBatchPayouts.find((b) => b.id === good1.id)! + expect(sample).toMatchObject({ + name: good1.name, + hederaTransactionId: good1.hederaTransactionId, + hederaTransactionHash: good1.hederaTransactionHash, + holdersNumber: good1.holdersNumber, + status: good1.status, + }) + }) + + it("should return empty array when no batch payouts found for distribution", async () => { + const distribution = await saveDistribution() + + const foundBatchPayouts = await batchPayoutRepository.getBatchPayoutsByDistribution(distribution) + + expect(foundBatchPayouts).toHaveLength(0) + }) + + it("should throw BatchPayoutRepositoryError when getting batch payouts by distribution fails", async () => { + const distribution = await saveDistribution() + jest.spyOn(internalBatchPayoutRepository, "find").mockRejectedValueOnce(new Error("DB error")) + + await expect(batchPayoutRepository.getBatchPayoutsByDistribution(distribution)).rejects.toThrow( + new BatchPayoutRepositoryError( + BatchPayoutRepositoryError.ERRORS.GET_BATCH_PAYOUTS_BY_DISTRIBUTION(distribution.id), + ), + ) + }) + }) + + describe("updateBatchPayout", () => { + it("should update a batch payout successfully", async () => { + const distribution = await saveDistribution() + const originalBatchPayout = await saveBatchPayout(distribution) + const updatedHederaTransactionId = fakeHederaTxId() + const updatedHederaTransactionHash = `0x${faker.string.hexadecimal({ length: 96, prefix: "" })}` + const holdersNumber = originalBatchPayout.holdersNumber + 100 + const updatedBatchPayout = BatchPayout.createExisting( + originalBatchPayout.id, + distribution, + originalBatchPayout.name, + updatedHederaTransactionId, + updatedHederaTransactionHash, + holdersNumber, + BatchPayoutStatus.COMPLETED, + originalBatchPayout.createdAt, + new Date(), + ) + + await batchPayoutRepository.updateBatchPayout(updatedBatchPayout) + + const persistedBatchPayout = await internalBatchPayoutRepository.findOne({ + where: { id: originalBatchPayout.id }, + relations: ["distribution", "distribution.asset"], + }) + expect(persistedBatchPayout).toBeDefined() + expect(persistedBatchPayout.hederaTransactionHash).toBe(updatedHederaTransactionHash) + expect(persistedBatchPayout.hederaTransactionId).toBe(updatedHederaTransactionId) + expect(persistedBatchPayout.holdersNumber).toBe(holdersNumber) + expect(persistedBatchPayout.status).toBe(BatchPayoutStatus.COMPLETED) + }) + + it("should update only specific fields of a batch payout", async () => { + const distribution = await saveDistribution() + const originalBatchPayout = await saveBatchPayout(distribution) + const updatedBatchPayout = BatchPayout.createExisting( + originalBatchPayout.id, + originalBatchPayout.distribution, + originalBatchPayout.name, + originalBatchPayout.hederaTransactionId, + originalBatchPayout.hederaTransactionHash, + 250, + BatchPayoutStatus.IN_PROGRESS, + originalBatchPayout.createdAt, + new Date(), + ) + + const result = await batchPayoutRepository.updateBatchPayout(updatedBatchPayout) + + expect(result.holdersNumber).toBe(250) + expect(result.status).toBe(BatchPayoutStatus.IN_PROGRESS) + expect(result.name).toBe(originalBatchPayout.name) + expect(result.hederaTransactionHash).toBe(originalBatchPayout.hederaTransactionHash) + expect(result.hederaTransactionId).toBe(originalBatchPayout.hederaTransactionId) + expect(result.hederaTransactionHash).toBe(originalBatchPayout.hederaTransactionHash) + }) + + it("should throw BatchPayoutRepositoryError when updating non-existent batch payout", async () => { + const distribution = await saveDistribution() + const nonExistentBatchPayout = BatchPayoutUtils.newInstance({ + distribution, + id: crypto.randomUUID(), + }) + await expect(batchPayoutRepository.updateBatchPayout(nonExistentBatchPayout)).resolves.toBeDefined() + }) + + it("should throw BatchPayoutRepositoryError when updating batch payout fails", async () => { + const distribution = await saveDistribution() + const batchPayout = await saveBatchPayout(distribution) + const error = new Error("Database error") + jest.spyOn(internalBatchPayoutRepository, "save").mockRejectedValueOnce(error) + + await expect(batchPayoutRepository.updateBatchPayout(batchPayout)).rejects.toThrow( + new BatchPayoutRepositoryError(BatchPayoutRepositoryError.ERRORS.UPDATE_BATCH_PAYOUT(batchPayout), error), + ) + }) + + it("should preserve distribution relationship when updating batch payout", async () => { + const distribution = await saveDistribution() + const originalBatchPayout = await saveBatchPayout(distribution) + + const updatedBatchPayout = BatchPayout.createExisting( + originalBatchPayout.id, + originalBatchPayout.distribution, + "Updated Name", + originalBatchPayout.hederaTransactionId, + originalBatchPayout.hederaTransactionHash, + originalBatchPayout.holdersNumber, + BatchPayoutStatus.COMPLETED, + originalBatchPayout.createdAt, + new Date(), + ) + + const result = await batchPayoutRepository.updateBatchPayout(updatedBatchPayout) + + expect(result.distribution).toBeDefined() + expect(result.distribution.id).toBe(distribution.id) + expect(result.distribution.asset).toBeDefined() + expect(result.distribution.asset.id).toBe(distribution.asset.id) + }) + + it("should update timestamps correctly", async () => { + const distribution = await saveDistribution() + const originalBatchPayout = await saveBatchPayout(distribution) + const updatedName = faker.string.alpha({ length: 10 }) + const updatedBatchPayout = BatchPayout.createExisting( + originalBatchPayout.id, + originalBatchPayout.distribution, + updatedName, + originalBatchPayout.hederaTransactionId, + originalBatchPayout.hederaTransactionHash, + originalBatchPayout.holdersNumber, + originalBatchPayout.status, + originalBatchPayout.createdAt, + originalBatchPayout.updatedAt, + ) + + const result = await batchPayoutRepository.updateBatchPayout(updatedBatchPayout) + + expect(result.createdAt).toEqual(originalBatchPayout.createdAt) + expect(result.updatedAt).not.toEqual(originalBatchPayout.updatedAt) + }) + }) + + async function saveAsset(): Promise { + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + return asset + } + + async function saveDistribution(asset?: Asset): Promise { + if (!asset) { + asset = await saveAsset() + } + const distribution = DistributionUtils.newInstance({ asset }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(distribution)) + return distribution + } + + async function saveBatchPayout(distribution?: Distribution): Promise { + if (!distribution) { + distribution = await saveDistribution() + } + const batchPayout = BatchPayoutUtils.newInstance({ distribution }) + await internalBatchPayoutRepository.save(BatchPayoutPersistence.fromBatchPayout(batchPayout)) + return batchPayout + } +}) diff --git a/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-distribution.repository.spec.ts b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-distribution.repository.spec.ts new file mode 100644 index 000000000..baad6f84b --- /dev/null +++ b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-distribution.repository.spec.ts @@ -0,0 +1,852 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigurationModule } from "@config/configuration.module" +import { ENTITIES, PostgresModule } from "@config/postgres.module" +import { Asset } from "@domain/model/asset" +import { Distribution, DistributionStatus, DistributionType } from "@domain/model/distribution" +import { OrderPageOptions, PageOptions } from "@domain/model/page" +import { faker } from "@faker-js/faker" +import { DistributionRepositoryError } from "@infrastructure/adapters/repositories/errors/distribution.repository.error" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { DistributionTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-distribution.repository" +import { Test, TestingModule } from "@nestjs/testing" +import { getRepositoryToken } from "@nestjs/typeorm" +import { AssetUtils } from "@test/shared/asset.utils" +import { PostgreSqlContainer } from "@test/shared/containers/postgresql-container" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { TestConstants } from "@test/shared/utils" +import crypto from "crypto" +import { Repository } from "typeorm" + +const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000 +const TWO_DAYS_IN_MS = 2 * ONE_DAY_IN_MS + +describe(DistributionTypeOrmRepository.name, () => { + let distributionRepository: DistributionTypeOrmRepository + let internalDistributionRepository: Repository + let internalAssetRepository: Repository + let container: PostgreSqlContainer + + beforeAll(async () => { + container = await PostgreSqlContainer.create() + const module: TestingModule = await Test.createTestingModule({ + imports: [ConfigurationModule.forRoot("/.env.test"), PostgresModule.forRoot(container.getConfig(), ENTITIES)], + providers: [DistributionTypeOrmRepository], + }).compile() + + distributionRepository = module.get(DistributionTypeOrmRepository) + internalAssetRepository = module.get>(getRepositoryToken(AssetPersistence)) + internalDistributionRepository = module.get>( + getRepositoryToken(DistributionPersistence), + ) + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + await container.stop() + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + await internalDistributionRepository.deleteAll() + await internalAssetRepository.deleteAll() + }) + + describe("saveDistribution", () => { + it("should save a distribution successfully", async () => { + const asset = await saveAsset() + const distribution = DistributionUtils.newInstance({ asset }) + + await expect(distributionRepository.saveDistribution(distribution)).resolves.toEqual(distribution) + }) + + it("should throw DistributionRepositoryError when saving distribution fails", async () => { + const asset = await saveAsset() + const distribution = DistributionUtils.newInstance({ asset }) + const error = new Error("Database error") + jest.spyOn(internalDistributionRepository, "save").mockRejectedValueOnce(error) + + await expect(distributionRepository.saveDistribution(distribution)).rejects.toThrow( + new DistributionRepositoryError(DistributionRepositoryError.ERRORS.SAVE_DISTRIBUTION(distribution), error), + ) + }) + + it("should update a distribution successfully", async () => { + const asset = await saveAsset() + const distribution = DistributionUtils.newInstance({ asset }) + const twoDaysAfter = new Date(new Date().getTime() + TWO_DAYS_IN_MS) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distribution)) + const corporateActionId = (distribution.details as any).corporateActionId + const updatedDistribution = Distribution.createExistingCorporateAction( + distribution.id, + distribution.asset, + corporateActionId, + twoDaysAfter, + DistributionStatus.IN_PROGRESS, + distribution.createdAt, + new Date(), + ) + await expect(distributionRepository.saveDistribution(updatedDistribution)).resolves.toEqual(updatedDistribution) + const found = await internalDistributionRepository.findOne({ + where: { id: distribution.id }, + }) + expect(found.status).toBe(DistributionStatus.IN_PROGRESS) + expect(found.executionDate.toISOString()).toBe((updatedDistribution.details as any).executionDate.toISOString()) + }) + }) + + describe("getDistribution", () => { + it("should get a distribution by id successfully", async () => { + const asset = await saveAsset() + const distribution = DistributionUtils.newInstance({ asset }) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distribution)) + const found = await distributionRepository.getDistribution(distribution.id) + expect(found).toEqual(distribution) + }) + + it("should throw DistributionRepositoryError when getting distribution by id fails", async () => { + const id = crypto.randomUUID() + const error = new Error("Database error") + jest.spyOn(internalDistributionRepository, "findOne").mockRejectedValueOnce(error) + + await expect(distributionRepository.getDistribution(id)).rejects.toThrow( + new DistributionRepositoryError(DistributionRepositoryError.ERRORS.GET_DISTRIBUTION(id), error), + ) + }) + + it("should return null if distribution is not found by id", async () => { + const found = await distributionRepository.getDistribution(crypto.randomUUID()) + expect(found).toBeNull() + }) + }) + + describe("getAllDistributionsByAssetId", () => { + it("should get distributions by assetId successfully", async () => { + const asset = await saveAsset() + const distribution1 = DistributionUtils.newInstance({ asset }) + const distribution2 = DistributionUtils.newInstance({ asset }) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distribution1)) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distribution2)) + + const found = await distributionRepository.getAllDistributionsByAssetId(asset.id) + expect(found).toHaveLength(2) + expect(found).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: distribution1.id }), + expect.objectContaining({ id: distribution2.id }), + ]), + ) + }) + + it("should throw DistributionRepositoryError when getting distributions by assetId fails", async () => { + const assetId = crypto.randomUUID() + const error = new Error("Database error") + jest.spyOn(internalDistributionRepository, "find").mockRejectedValueOnce(error) + + await expect(distributionRepository.getAllDistributionsByAssetId(assetId)).rejects.toThrow( + new DistributionRepositoryError(DistributionRepositoryError.ERRORS.GET_DISTRIBUTIONS_BY_ASSET(assetId), error), + ) + }) + + it("should return an empty array if no distributions are found by assetId", async () => { + const found = await distributionRepository.getAllDistributionsByAssetId(crypto.randomUUID()) + expect(found).toEqual([]) + }) + }) + + describe("findByCorporateActionId", () => { + it("should return a distribution by assetId and corporate action ID", async () => { + const asset = await saveAsset() + const distribution = await saveDistribution(asset) + + const corporateActionId = (distribution.details as any).corporateActionId.value + const foundDistribution = await distributionRepository.findByCorporateActionId( + distribution.asset.id, + corporateActionId, + ) + + expect(foundDistribution).toEqual(distribution) + }) + + it("should return null when no distribution matches the assetId and corporate action ID", async () => { + const assetId = crypto.randomUUID() + const corporateActionId = faker.string.uuid() + + const found = await distributionRepository.findByCorporateActionId(assetId, corporateActionId) + + expect(found).toBeNull() + }) + + it("should return null when corporate action ID exists but for different asset", async () => { + const asset1 = await saveAsset() + const asset2 = await saveAsset() + const distribution = await saveDistribution(asset1) + + const corporateActionId = (distribution.details as any).corporateActionId.value + const found = await distributionRepository.findByCorporateActionId(asset2.id, corporateActionId) + + expect(found).toBeNull() + }) + + it("should throw DistributionRepositoryError when getting by corporate action ID fails", async () => { + const assetId = crypto.randomUUID() + const corporateActionId = crypto.randomUUID() + const error = new Error("Database error") + jest.spyOn(internalDistributionRepository, "findOne").mockRejectedValueOnce(error) + + await expect(distributionRepository.findByCorporateActionId(assetId, corporateActionId)).rejects.toThrow( + new DistributionRepositoryError( + DistributionRepositoryError.ERRORS.GET_DISTRIBUTION_BY_CORP_ACTION(assetId, corporateActionId), + error, + ), + ) + }) + }) + + describe("updateDistribution", () => { + it("should update a distribution successfully", async () => { + const asset = await saveAsset() + const distribution = await saveDistribution(asset) + const updatedExecutionDate = new Date(new Date().getTime() + TWO_DAYS_IN_MS) + const corporateActionId = (distribution.details as any).corporateActionId + const updatedDistribution = Distribution.createExistingCorporateAction( + distribution.id, + distribution.asset, + corporateActionId, + updatedExecutionDate, + DistributionStatus.IN_PROGRESS, + distribution.createdAt, + distribution.updatedAt, + ) + + await distributionRepository.updateDistribution(updatedDistribution) + + const found = await internalDistributionRepository.findOne({ + where: { id: distribution.id }, + }) + expect(found).toBeDefined() + const originalCorporateActionId = (distribution.details as any).corporateActionId.value + expect(found.corporateActionID).toEqual(originalCorporateActionId) + expect(found.status).toEqual(DistributionStatus.IN_PROGRESS) + expect(found.executionDate).toEqual(updatedExecutionDate) + }) + + it("should throw DistributionRepositoryError when updating distribution fails", async () => { + const asset = await saveAsset() + const distribution = DistributionUtils.newInstance({ asset }) + const error = new Error("Database error") + jest.spyOn(internalDistributionRepository, "save").mockRejectedValueOnce(error) + + await expect(distributionRepository.updateDistribution(distribution)).rejects.toThrow( + new DistributionRepositoryError(DistributionRepositoryError.ERRORS.UPDATE_DISTRIBUTION(distribution), error), + ) + }) + + it("should update distribution status from SCHEDULED to COMPLETED", async () => { + const asset = await saveAsset() + const distribution = DistributionUtils.newInstance({ + asset, + status: DistributionStatus.SCHEDULED, + }) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distribution)) + const corporateActionId = (distribution.details as any).corporateActionId + const executionDate = (distribution.details as any).executionDate + const updatedDistribution = Distribution.createExistingCorporateAction( + distribution.id, + distribution.asset, + corporateActionId, + executionDate, + DistributionStatus.COMPLETED, + distribution.createdAt, + new Date(), + ) + + await distributionRepository.updateDistribution(updatedDistribution) + + const found = await internalDistributionRepository.findOne({ + where: { id: distribution.id }, + }) + expect(found.status).toBe(DistributionStatus.COMPLETED) + }) + + it("should preserve original createdAt when updating distribution", async () => { + const asset = await saveAsset() + const distribution = await saveDistribution(asset) + const originalCreatedAt = distribution.createdAt + const corporateActionId = (distribution.details as any).corporateActionId + const executionDate = (distribution.details as any).executionDate + const updatedDistribution = Distribution.createExistingCorporateAction( + distribution.id, + distribution.asset, + corporateActionId, + executionDate, + DistributionStatus.COMPLETED, + distribution.createdAt, + new Date(), + ) + + await distributionRepository.updateDistribution(updatedDistribution) + + const found = await internalDistributionRepository.findOne({ + where: { id: distribution.id }, + }) + expect(found.createdAt).toEqual(originalCreatedAt) + expect(found.updatedAt).not.toEqual(found.createdAt) + }) + }) + + describe("findByExecutionDateRange", () => { + it("should return all distributions within the execution date range", async () => { + const asset = await saveAsset() + const baseDate = faker.date.future({ years: 9 }) + const startDate = new Date(baseDate.getTime() - ONE_DAY_IN_MS) + const middleDate = new Date(baseDate.getTime()) + const endDate = new Date(baseDate.getTime() + ONE_DAY_IN_MS) + const outsideDate = new Date(baseDate.getTime() + TWO_DAYS_IN_MS) + const distributionInRange1 = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + executionDate: middleDate, + } as any, + }) + const distributionInRange2 = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + executionDate: startDate, + } as any, + }) + const distributionInRange3 = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + executionDate: endDate, + } as any, + }) + const distributionOutOfRange = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + executionDate: outsideDate, + } as any, + }) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distributionInRange1)) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distributionInRange2)) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distributionInRange3)) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distributionOutOfRange)) + + const found = await distributionRepository.findByExecutionDateRange(startDate, endDate) + + expect(found).toHaveLength(3) + expect(found).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: distributionInRange1.id }), + expect.objectContaining({ id: distributionInRange2.id }), + expect.objectContaining({ id: distributionInRange3.id }), + ]), + ) + expect(found).not.toContainEqual(expect.objectContaining({ id: distributionOutOfRange.id })) + }) + + it("should return distributions within the execution date range filtered by status", async () => { + const asset = await saveAsset() + const baseDate = faker.date.future({ years: 9 }) + const startDate = new Date(baseDate.getTime() - ONE_DAY_IN_MS) + const endDate = new Date(baseDate.getTime() + ONE_DAY_IN_MS) + const distributionScheduled = DistributionUtils.newInstance({ + asset, + status: DistributionStatus.SCHEDULED, + details: { + type: DistributionType.CORPORATE_ACTION, + executionDate: new Date(baseDate.getTime()), + } as any, + }) + const distributionInProgress = DistributionUtils.newInstance({ + asset, + status: DistributionStatus.IN_PROGRESS, + details: { + type: DistributionType.CORPORATE_ACTION, + executionDate: new Date(baseDate.getTime()), + } as any, + }) + const distributionCompleted = DistributionUtils.newInstance({ + asset, + status: DistributionStatus.COMPLETED, + details: { + type: DistributionType.CORPORATE_ACTION, + executionDate: new Date(baseDate.getTime()), + } as any, + }) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distributionScheduled)) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distributionInProgress)) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distributionCompleted)) + + const found = await distributionRepository.findByExecutionDateRange( + startDate, + endDate, + DistributionStatus.SCHEDULED, + ) + + expect(found).toHaveLength(1) + expect(found).toContainEqual(distributionScheduled) + expect(found).not.toContainEqual(distributionInProgress) + expect(found).not.toContainEqual(distributionCompleted) + }) + + it("should throw DistributionRepositoryError if getting distributions by execution date range fails", async () => { + const startDate = new Date() + const endDate = new Date(startDate.getTime() + ONE_DAY_IN_MS) + const error = new Error("Database error") + jest.spyOn(internalDistributionRepository, "find").mockRejectedValueOnce(error) + await expect(distributionRepository.findByExecutionDateRange(startDate, endDate)).rejects.toThrow( + new DistributionRepositoryError( + DistributionRepositoryError.ERRORS.GET_DISTRIBUTIONS_BY_EXECUTION_DATE(startDate, endDate), + error, + ), + ) + }) + + it("should return an empty array when no distributions are found within the execution date range", async () => { + const startDate = new Date() + const endDate = new Date(startDate.getTime() + ONE_DAY_IN_MS) + + const found = await distributionRepository.findByExecutionDateRange(startDate, endDate) + + expect(found).toEqual([]) + }) + + it("should return empty array if no distributions match the execution date range and status filter", async () => { + const asset = await saveAsset() + const baseDate = faker.date.future({ years: 9 }) + const startDate = new Date(baseDate.getTime() - ONE_DAY_IN_MS) + const endDate = new Date(baseDate.getTime() + ONE_DAY_IN_MS) + const distribution = DistributionUtils.newInstance({ + asset, + status: DistributionStatus.COMPLETED, + }) + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distribution)) + + const found = await distributionRepository.findByExecutionDateRange( + startDate, + endDate, + DistributionStatus.SCHEDULED, + ) + + expect(found).toHaveLength(0) + }) + }) + + describe("getDistributions", () => { + it("should return paginated distributions with associated assets", async () => { + const asset1 = await saveAsset() + const asset2 = await saveAsset() + + const distribution1 = DistributionUtils.newInstance({ + asset: asset1, + status: DistributionStatus.SCHEDULED, + }) + const distribution2 = DistributionUtils.newInstance({ + asset: asset2, + status: DistributionStatus.COMPLETED, + }) + + await internalDistributionRepository.insert([ + DistributionPersistence.fromDistribution(distribution1), + DistributionPersistence.fromDistribution(distribution2), + ]) + + const pageOptions: PageOptions = { page: 1, limit: 10, order: { order: "DESC", orderBy: "createdAt" } } + const result = await distributionRepository.getDistributions(pageOptions) + + expect(result.items).toHaveLength(2) + expect(result.total).toBe(2) + expect(result.page).toBe(1) + expect(result.limit).toBe(10) + + const foundDistribution1 = result.items.find((d) => d.id === distribution1.id) + expect(foundDistribution1).toBeDefined() + expect(foundDistribution1?.asset.id).toBe(asset1.id) + expect(foundDistribution1?.asset.name).toBe(asset1.name) + + const foundDistribution2 = result.items.find((d) => d.id === distribution2.id) + expect(foundDistribution2).toBeDefined() + expect(foundDistribution2?.asset.id).toBe(asset2.id) + expect(foundDistribution2?.asset.name).toBe(asset2.name) + }) + + it("should return paginated distributions with correct pagination", async () => { + const asset = await saveAsset() + const distributions = Array.from({ length: 15 }, () => DistributionUtils.newInstance({ asset })) + + await internalDistributionRepository.insert(distributions.map((d) => DistributionPersistence.fromDistribution(d))) + + const pageOptions: PageOptions = { page: 2, limit: 5, order: { order: "DESC", orderBy: "createdAt" } } + const result = await distributionRepository.getDistributions(pageOptions) + + expect(result.items).toHaveLength(5) + expect(result.total).toBe(15) + expect(result.page).toBe(2) + expect(result.limit).toBe(5) + }) + + it("should respect order options", async () => { + const asset = await saveAsset() + const now = new Date() + const date1 = new Date(now.getTime() + ONE_DAY_IN_MS) + const date2 = new Date(now.getTime() + TWO_DAYS_IN_MS) + const date3 = new Date(now.getTime() + 3 * ONE_DAY_IN_MS) + + const distribution1 = DistributionUtils.newInstance({ + asset, + createdAt: date1, + updatedAt: date1, + }) + const distribution2 = DistributionUtils.newInstance({ + asset, + createdAt: date2, + updatedAt: date2, + }) + const distribution3 = DistributionUtils.newInstance({ + asset, + createdAt: date3, + updatedAt: date3, + }) + + await internalDistributionRepository.insert([ + DistributionPersistence.fromDistribution(distribution1), + DistributionPersistence.fromDistribution(distribution2), + DistributionPersistence.fromDistribution(distribution3), + ]) + + const pageOptions: PageOptions = { page: 1, limit: 10, order: { order: "ASC", orderBy: "createdAt" } } + const result = await distributionRepository.getDistributions(pageOptions) + + expect(result.items).toHaveLength(3) + expect(result.items[0].createdAt).toEqual(date1) + expect(result.items[1].createdAt).toEqual(date2) + expect(result.items[2].createdAt).toEqual(date3) + }) + + it("should throw DistributionRepositoryError when getting distributions fails", async () => { + const error = new Error("Database error") + jest.spyOn(internalDistributionRepository, "findAndCount").mockRejectedValueOnce(error) + + const pageOptions: PageOptions = { page: 1, limit: 10, order: { order: "DESC", orderBy: "createdAt" } } + await expect(distributionRepository.getDistributions(pageOptions)).rejects.toThrow( + new DistributionRepositoryError(DistributionRepositoryError.ERRORS.GET_DISTRIBUTIONS(), error), + ) + }) + }) + + describe("getDistributionsByAssetId", () => { + it("should return first page of distributions with pagination", async () => { + const asset = await saveAsset() + const distributions = [ + DistributionUtils.newInstance({ asset }), + DistributionUtils.newInstance({ asset }), + DistributionUtils.newInstance({ asset }), + ] + + for (const distribution of distributions) { + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distribution)) + } + + const pageOptions = { page: 1, limit: 2, order: OrderPageOptions.DEFAULT } + const result = await distributionRepository.getDistributionsByAssetId(asset.id, pageOptions) + + expect(result.items).toHaveLength(2) + expect(result.total).toBe(3) + expect(result.page).toBe(1) + expect(result.limit).toBe(2) + expect(result.totalPages).toBe(2) + }) + + it("should return empty page when no distributions exist for asset", async () => { + const asset = await saveAsset() + const pageOptions = PageOptions.DEFAULT + + const result = await distributionRepository.getDistributionsByAssetId(asset.id, pageOptions) + + expect(result.items).toHaveLength(0) + expect(result.total).toBe(0) + expect(result.page).toBe(1) + expect(result.limit).toBe(10) + expect(result.totalPages).toBe(0) + }) + + it("should return second page of distributions", async () => { + const asset = await saveAsset() + const distributions = [ + DistributionUtils.newInstance({ asset }), + DistributionUtils.newInstance({ asset }), + DistributionUtils.newInstance({ asset }), + ] + + for (const distribution of distributions) { + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distribution)) + } + + const pageOptions = { page: 2, limit: 2, order: OrderPageOptions.DEFAULT } + const result = await distributionRepository.getDistributionsByAssetId(asset.id, pageOptions) + + expect(result.items).toHaveLength(1) + expect(result.total).toBe(3) + expect(result.page).toBe(2) + expect(result.limit).toBe(2) + expect(result.totalPages).toBe(2) + }) + + it("should throw error when database fails", async () => { + const asset = await saveAsset() + const pageOptions = PageOptions.DEFAULT + const error = new Error("Database error") + jest.spyOn(internalDistributionRepository, "findAndCount").mockRejectedValueOnce(error) + + await expect(distributionRepository.getDistributionsByAssetId(asset.id, pageOptions)).rejects.toThrow( + new DistributionRepositoryError(DistributionRepositoryError.ERRORS.GET_DISTRIBUTIONS_BY_ASSET(asset.id), error), + ) + }) + + it("should order distributions by createdAt DESC by default", async () => { + const asset = await saveAsset() + const distributions = [ + DistributionUtils.newInstance({ asset }), + DistributionUtils.newInstance({ asset }), + DistributionUtils.newInstance({ asset }), + ] + + for (let i = 0; i < distributions.length; i++) { + await internalDistributionRepository.insert(DistributionPersistence.fromDistribution(distributions[i])) + if (i < distributions.length - 1) { + await new Promise((resolve) => setTimeout(resolve, 10)) + } + } + + const pageOptions = PageOptions.DEFAULT + const result = await distributionRepository.getDistributionsByAssetId(asset.id, pageOptions) + + expect(result.items).toHaveLength(3) + const corporateActionIds = result.items.map((item) => (item.details as any).corporateActionId.value) + const expectedIds = distributions.map((d) => (d.details as any).corporateActionId.value) + expect(corporateActionIds).toEqual(expect.arrayContaining(expectedIds)) + expect(expectedIds).toEqual(expect.arrayContaining(corporateActionIds)) + }) + }) + + async function saveAsset(): Promise { + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + return asset + } + + async function saveDistribution(asset?: Asset): Promise { + if (!asset) { + asset = await saveAsset() + } + const distribution = DistributionUtils.newInstance({ asset }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(distribution)) + return distribution + } +}) diff --git a/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-holder.repository.spec.ts b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-holder.repository.spec.ts new file mode 100644 index 000000000..05798a18a --- /dev/null +++ b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-holder.repository.spec.ts @@ -0,0 +1,625 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigurationModule } from "@config/configuration.module" +import { ENTITIES, PostgresModule } from "@config/postgres.module" +import { Asset } from "@domain/model/asset" +import { BatchPayout } from "@domain/model/batch-payout" +import { Distribution } from "@domain/model/distribution" +import { Holder, HolderStatus } from "@domain/model/holder" +import { PageOptions } from "@domain/model/page" +import { faker } from "@faker-js/faker" +import { HolderRepositoryError } from "@infrastructure/adapters/repositories/errors/holder.repository.error" +import { AssetPersistence } from "@infrastructure/adapters/repositories/model/asset.persistence" +import { BatchPayoutPersistence } from "@infrastructure/adapters/repositories/model/batch-payout.persistence" +import { DistributionPersistence } from "@infrastructure/adapters/repositories/model/distribution.persistence" +import { HolderPersistence } from "@infrastructure/adapters/repositories/model/holder.persistence" +import { HolderTypeOrmRepository } from "@infrastructure/adapters/repositories/typeorm-holder.repository" +import { Test, TestingModule } from "@nestjs/testing" +import { getRepositoryToken } from "@nestjs/typeorm" +import { AssetUtils } from "@test/shared/asset.utils" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { PostgreSqlContainer } from "@test/shared/containers/postgresql-container" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { HolderUtils } from "@test/shared/holder.utils" +import { TestConstants } from "@test/shared/utils" +import { Repository } from "typeorm" + +describe(HolderTypeOrmRepository.name, () => { + let holderRepository: HolderTypeOrmRepository + let internalRepository: Repository + let internalAssetRepository: Repository + let internalDistributionRepository: Repository + let internalBatchPayoutRepository: Repository + let container: PostgreSqlContainer + + beforeAll(async () => { + container = await PostgreSqlContainer.create() + const module: TestingModule = await Test.createTestingModule({ + imports: [ConfigurationModule.forRoot("/.env.test"), PostgresModule.forRoot(container.getConfig(), ENTITIES)], + providers: [HolderTypeOrmRepository], + }).compile() + + holderRepository = module.get(HolderTypeOrmRepository) + internalRepository = module.get>(getRepositoryToken(HolderPersistence)) + internalAssetRepository = module.get>(getRepositoryToken(AssetPersistence)) + internalDistributionRepository = module.get>( + getRepositoryToken(DistributionPersistence), + ) + internalBatchPayoutRepository = module.get>( + getRepositoryToken(BatchPayoutPersistence), + ) + }, TestConstants.BEFORE_ALL_TIMEOUT) + + afterAll(async () => { + await container.stop() + }, TestConstants.AFTER_ALL_TIMEOUT) + + afterEach(async () => { + await internalRepository.deleteAll() + await internalBatchPayoutRepository.deleteAll() + await internalDistributionRepository.deleteAll() + await internalAssetRepository.deleteAll() + }) + + describe("saveHolder", () => { + it("should save a holder successfully", async () => { + const distribution = await saveDistribution() + const batchPayout = await saveBatchPayout(distribution) + const holder = HolderUtils.newInstance({ batchPayout }) + + const savedHolder = await holderRepository.saveHolder(holder) + + expect(savedHolder).toStrictEqual(holder) + }) + + it("should throw HolderRepositoryError when saving holder fails", async () => { + const distribution = await saveDistribution() + const batchPayout = await saveBatchPayout(distribution) + const holder = HolderUtils.newInstance({ batchPayout }) + const error = new Error("Database error") + jest.spyOn(internalRepository, "save").mockRejectedValueOnce(error) + + await expect(holderRepository.saveHolder(holder)).rejects.toThrow( + new HolderRepositoryError(HolderRepositoryError.ERRORS.SAVE_HOLDER(holder), error), + ) + }) + }) + + describe("saveHolders", () => { + it("should save multiple holders successfully", async () => { + const distribution = await saveDistribution() + const batchPayout = await saveBatchPayout(distribution) + const holder1 = HolderUtils.newInstance({ batchPayout }) + const holder2 = HolderUtils.newInstance({ batchPayout }) + const holders = [holder1, holder2] + + const savedHolders = await holderRepository.saveHolders(holders) + + expect(savedHolders).toHaveLength(2) + + const savedHolder1 = savedHolders.find((h) => h.id === holder1.id) + const savedHolder2 = savedHolders.find((h) => h.id === holder2.id) + + expect(savedHolder1).toMatchObject({ + id: holder1.id, + holderEvmAddress: holder1.holderEvmAddress, + holderHederaAddress: holder1.holderHederaAddress, + status: holder1.status, + }) + expect(savedHolder2).toMatchObject({ + id: holder2.id, + holderEvmAddress: holder2.holderEvmAddress, + holderHederaAddress: holder2.holderHederaAddress, + status: holder2.status, + }) + }) + + it("should throw HolderRepositoryError when saving multiple holders fails", async () => { + const distribution = await saveDistribution() + const batchPayout = await saveBatchPayout(distribution) + const holder1 = HolderUtils.newInstance({ batchPayout }) + const holder2 = HolderUtils.newInstance({ batchPayout }) + const holders = [holder1, holder2] + const error = new Error("Database error") + jest.spyOn(internalRepository, "save").mockRejectedValueOnce(error) + + await expect(holderRepository.saveHolders(holders)).rejects.toThrow( + new HolderRepositoryError(HolderRepositoryError.ERRORS.SAVE_HOLDERS(holders), error), + ) + }) + }) + + describe("getHoldersByDistributionId", () => { + it("should return paginated holders for a distribution", async () => { + const distribution = await saveDistribution() + const batchPayout1 = await saveBatchPayout(distribution) + const batchPayout2 = await saveBatchPayout(distribution) + const holder1 = await saveHolder(batchPayout1) + const holder2 = await saveHolder(batchPayout2) + const otherDistribution = await saveDistribution() + const otherBatchPayout = await saveBatchPayout(otherDistribution) + await saveHolder(otherBatchPayout) + const pageOptions = PageOptions.DEFAULT + + const result = await holderRepository.getHoldersByDistributionId(distribution.id, pageOptions) + + // Assertions + expect(result.items).toHaveLength(2) + expect(result.total).toBe(2) + expect(result.page).toBe(pageOptions.page) + expect(result.limit).toBe(pageOptions.limit) + expect(result.totalPages).toBe(1) + + // Verify the returned items have the correct structure + const returnedIds = result.items.map((item) => item.id) + expect(returnedIds).toContain(holder1.id) + expect(returnedIds).toContain(holder2.id) + }) + + it("should return empty result when no holders exist for distribution", async () => { + const distribution = await saveDistribution() + const pageOptions = PageOptions.DEFAULT + + const result = await holderRepository.getHoldersByDistributionId(distribution.id, pageOptions) + + expect(result.items).toHaveLength(0) + expect(result.total).toBe(0) + expect(result.totalPages).toBe(0) + }) + + it("should respect pagination parameters", async () => { + const distribution = await saveDistribution() + const batchPayout = await saveBatchPayout(distribution) + + const holders = [] + for (let i = 0; i < 5; i++) { + holders.push(await saveHolder(batchPayout)) + } + const page1 = await holderRepository.getHoldersByDistributionId(distribution.id, { + page: 1, + limit: 2, + order: { order: "ASC" as const, orderBy: "createdAt" as const }, + }) + + // Second page with 2 items + const page2 = await holderRepository.getHoldersByDistributionId(distribution.id, { + page: 2, + limit: 2, + order: { order: "ASC" as const, orderBy: "createdAt" as const }, + }) + + expect(page1.items).toHaveLength(2) + expect(page2.items).toHaveLength(2) + expect(page1.total).toBe(5) + expect(page2.total).toBe(5) + expect(page1.totalPages).toBe(3) // 5 items / 2 per page = 3 pages + + // Verify no overlap between pages + const page1Ids = page1.items.map((item) => item.id) + const page2Ids = page2.items.map((item) => item.id) + const intersection = page1Ids.filter((id) => page2Ids.includes(id)) + expect(intersection).toHaveLength(0) + }) + + it("should respect ordering", async () => { + const distribution = await saveDistribution() + const batchPayout = await saveBatchPayout(distribution) + for (let i = 0; i < 3; i++) { + await saveHolder(batchPayout) + } + const pageOptionsAsc: PageOptions = { + page: 1, + limit: 10, + order: { order: "ASC" as const, orderBy: "createdAt" as const }, + } + const pageOptionsDesc: PageOptions = { + page: 1, + limit: 10, + order: { order: "DESC" as const, orderBy: "createdAt" as const }, + } + + // Test ascending order (oldest first) + const ascResult = await holderRepository.getHoldersByDistributionId(distribution.id, pageOptionsAsc) + + // Test descending order (newest first) + const descResult = await holderRepository.getHoldersByDistributionId(distribution.id, pageOptionsDesc) + + // Verify order + const ascTimestamps = ascResult.items.map((item) => item.createdAt.getTime()) + const descTimestamps = descResult.items.map((item) => item.createdAt.getTime()) + + // Check if timestamps are in correct order + for (let i = 1; i < ascTimestamps.length; i++) { + expect(ascTimestamps[i]).toBeGreaterThanOrEqual(ascTimestamps[i - 1]) + } + + for (let i = 1; i < descTimestamps.length; i++) { + expect(descTimestamps[i]).toBeLessThanOrEqual(descTimestamps[i - 1]) + } + }) + }) + + describe("updateHolder", () => { + it("should update a holder successfully", async () => { + const holder = await saveHolder() + const updatedHolder = Holder.createExisting( + holder.id, + holder.batchPayout, + holder.holderHederaAddress, + holder.holderEvmAddress, + 1, + HolderStatus.RETRYING, + new Date(), + "New Error", + holder.amount, + holder.createdAt, + new Date(), + ) + + await expect(holderRepository.updateHolder(updatedHolder)).resolves.toEqual(updatedHolder) + + const found = await internalRepository.findOneBy({ id: holder.id }) + expect(found.retryCounter).toBe(1) + expect(found.status).toBe(HolderStatus.RETRYING) + }) + + it("should throw HolderRepositoryError when updating holder fails", async () => { + const holder = await saveHolder() + const error = new Error("Database error") + jest.spyOn(internalRepository, "update").mockRejectedValueOnce(error) + + await expect(holderRepository.updateHolder(holder)).rejects.toThrow( + new HolderRepositoryError(HolderRepositoryError.ERRORS.UPDATE_HOLDER(holder), error), + ) + }) + }) + + describe("getHoldersByBatchPayout", () => { + it("returns all holders for a specific batch payout", async () => { + const distribution = await saveDistribution() + const goodBatch = await saveBatchPayout(distribution) + const noiseBatch = await saveBatchPayout() + const goodHolder = await saveHolder(goodBatch) + const goodHolder2 = await saveHolder(goodBatch) + await saveHolder(noiseBatch) + + const result = await holderRepository.getHoldersByBatchPayout(goodBatch.id) + + const expectedIds = [goodHolder.id, goodHolder2.id] + const resultIds = result.map((holder) => holder.id) + expect(result).toHaveLength(2) + expect(resultIds.sort()).toEqual(expectedIds.sort()) + expect(result).toEqual( + expect.arrayContaining([ + expect.objectContaining({ ...goodHolder }), + expect.objectContaining({ ...goodHolder2 }), + ]), + ) + }) + + it("should throw HolderRepositoryError when getting holders by batch payout fails", async () => { + const batchPayoutId = faker.string.uuid() + const error = new Error("Database error") + jest.spyOn(internalRepository, "find").mockRejectedValueOnce(error) + + await expect(holderRepository.getHoldersByBatchPayout(batchPayoutId)).rejects.toThrow( + new HolderRepositoryError(HolderRepositoryError.ERRORS.GET_HOLDERS_BY_BATCH_PAYOUT(batchPayoutId), error), + ) + }) + }) + + describe("getHoldersByDistributionId", () => { + it("returns all holders for a specific distribution", async () => { + const distribution = await saveDistribution() + const goodBatch = await saveBatchPayout(distribution) + const noiseBatch = await saveBatchPayout() + const goodHolder = await saveHolder(goodBatch) + + await saveHolder(noiseBatch) + + const result = await holderRepository.getAllHoldersByDistributionId(distribution.id) + + expect(result).toHaveLength(1) + expect(result[0]).toStrictEqual(goodHolder) + }) + + it("should throw HolderRepositoryError when getting holders by distribution fails", async () => { + const distributionId = faker.string.uuid() + const error = new Error("Database error") + jest.spyOn(internalRepository, "find").mockRejectedValueOnce(error) + + await expect(holderRepository.getAllHoldersByDistributionId(distributionId)).rejects.toThrow( + new HolderRepositoryError(HolderRepositoryError.ERRORS.GET_HOLDERS_BY_DISTRIBUTION(distributionId), error), + ) + }) + }) + + describe("countHoldersByDistributionId", () => { + it("returns holders count for a specific distribution", async () => { + const distribution = await saveDistribution() + const distribution2 = await saveDistribution() + const goodBatch = await saveBatchPayout(distribution) + await saveHolder(goodBatch) + + const result = await holderRepository.countHoldersByDistributionId(distribution.id) + + expect(result).toBe(1) + expect(await holderRepository.countHoldersByDistributionId(distribution2.id)).toBe(0) + }) + + it("should throw HolderRepositoryError when getting holders count by distribution fails", async () => { + const distributionId = faker.string.uuid() + const error = new Error("Database error") + jest.spyOn(internalRepository, "count").mockRejectedValueOnce(error) + + await expect(holderRepository.countHoldersByDistributionId(distributionId)).rejects.toThrow( + new HolderRepositoryError(HolderRepositoryError.ERRORS.GET_HOLDER_COUNT_BY_DISTRIBUTION(distributionId), error), + ) + }) + }) + + describe("getHoldersByDistributionIdAndStatus", () => { + it("returns holders for a specific distribution and status", async () => { + const distribution = await saveDistribution() + const batchPayout = await saveBatchPayout(distribution) + const holder = await saveHolder(batchPayout, HolderStatus.FAILED) + await saveHolder(batchPayout, HolderStatus.SUCCESS) + + const holders = await holderRepository.getHoldersByDistributionIdAndStatus(distribution.id, HolderStatus.FAILED) + + expect(holders.length).toBe(1) + expect(holders[0]).toStrictEqual(holder) + }) + + it("should throw HolderRepositoryError when getting holders by distribution and status fails", async () => { + const distributionId = faker.string.uuid() + const status = HolderStatus.FAILED + const error = new Error("Database error") + jest.spyOn(internalRepository, "find").mockRejectedValueOnce(error) + + await expect( + holderRepository.getHoldersByDistributionIdAndStatus(distributionId, HolderStatus.FAILED), + ).rejects.toThrow( + new HolderRepositoryError( + HolderRepositoryError.ERRORS.GET_HOLDERS_BY_DISTRIBUTION_AND_STATUS(distributionId, status), + error, + ), + ) + }) + }) + + async function saveAsset(): Promise { + const asset = AssetUtils.newInstance() + await internalAssetRepository.save(AssetPersistence.fromAsset(asset)) + return asset + } + + async function saveDistribution(asset?: Asset): Promise { + if (!asset) { + asset = await saveAsset() + } + const distribution = DistributionUtils.newInstance({ asset }) + await internalDistributionRepository.save(DistributionPersistence.fromDistribution(distribution)) + return distribution + } + + async function saveBatchPayout(distribution?: Distribution): Promise { + if (!distribution) { + distribution = await saveDistribution() + } + const batchPayout = BatchPayoutUtils.newInstance({ distribution }) + await internalBatchPayoutRepository.save(BatchPayoutPersistence.fromBatchPayout(batchPayout)) + return batchPayout + } + + async function saveHolder(batchPayout?: BatchPayout, status: HolderStatus = undefined): Promise { + if (!batchPayout) { + batchPayout = await saveBatchPayout() + } + const holder = HolderUtils.newInstance({ batchPayout, status }) + await internalRepository.save(HolderPersistence.fromHolder(holder)) + return holder + } +}) diff --git a/apps/mass-payout/backend/test/integration/rest/asset/asset.controller.spec.ts b/apps/mass-payout/backend/test/integration/rest/asset/asset.controller.spec.ts new file mode 100644 index 000000000..5453a5412 --- /dev/null +++ b/apps/mass-payout/backend/test/integration/rest/asset/asset.controller.spec.ts @@ -0,0 +1,963 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { DisableAssetSyncUseCase } from "@application/use-cases/disable-asset-sync.use-case" +import { EnableAssetSyncUseCase } from "@application/use-cases/enable-asset-sync.use-case" +import { ExecutePayoutUseCase } from "@application/use-cases/execute-payout.use-case" +import { GetAssetDistributionsUseCase } from "@application/use-cases/get-asset-distributions.use-case" +import { GetAssetUseCase } from "@application/use-cases/get-asset.use-case" +import { GetAssetsUseCase } from "@application/use-cases/get-assets.use-case" +import { GetBasicAssetInformationUseCase } from "@application/use-cases/get-basic-asset-information.use-case" +import { ImportAssetUseCase } from "@application/use-cases/import-asset.use-case" +import { PauseAssetUseCase } from "@application/use-cases/pause-asset.use-case" +import { UnpauseAssetUseCase } from "@application/use-cases/unpause-asset.use-case" +import { AssetNotFoundError } from "@domain/errors/asset.error" +import { AssetType } from "@domain/model/asset-type.enum" +import { AmountType, CorporateActionDetails, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { OrderPageOptions, PageOptions } from "@domain/model/page" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { AssetController } from "@infrastructure/rest/asset/asset.controller" +import { AssetResponse } from "@infrastructure/rest/asset/asset.response" +import { CreatePayoutRequest } from "@infrastructure/rest/asset/create-payout.request" +import { ImportAssetRequest } from "@infrastructure/rest/asset/import-asset.request" +import { DistributionResponse } from "@infrastructure/rest/distribution/distribution.response" +import { HttpStatus, INestApplication } from "@nestjs/common" +import { Test, TestingModule } from "@nestjs/testing" +import { AssetUtils } from "@test/shared/asset.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { fakeHederaAddress, fakeLifeCycleCashFlowAddress } from "@test/shared/utils" +import request from "supertest" +import { GetDistributionHolderCountUseCase } from "@application/use-cases/get-distribution-holder-count.use-case" + +describe(AssetController.name, () => { + let app: INestApplication + const createAssetUseCaseMock = createMock() + const getAssetUseCaseMock = createMock() + const getAssetsUseCaseMock = createMock() + const pauseAssetUseCaseMock = createMock() + const unpauseAssetUseCaseMock = createMock() + const getBasicAssetInformationUseCaseMock = createMock() + const getAssetDistributionsUseCaseMock = createMock() + const getDistributionHolderCountUseCaseMock = createMock() + const executePayoutUseCaseMock = createMock() + const enableAssetSyncUseCaseMock = createMock() + const disableAssetSyncUseCaseMock = createMock() + + beforeAll(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + controllers: [AssetController], + providers: [ + { + provide: ImportAssetUseCase, + useValue: createAssetUseCaseMock, + }, + { + provide: GetAssetUseCase, + useValue: getAssetUseCaseMock, + }, + { + provide: GetAssetsUseCase, + useValue: getAssetsUseCaseMock, + }, + { + provide: PauseAssetUseCase, + useValue: pauseAssetUseCaseMock, + }, + { + provide: UnpauseAssetUseCase, + useValue: unpauseAssetUseCaseMock, + }, + { + provide: GetBasicAssetInformationUseCase, + useValue: getBasicAssetInformationUseCaseMock, + }, + { + provide: GetAssetDistributionsUseCase, + useValue: getAssetDistributionsUseCaseMock, + }, + { + provide: ExecutePayoutUseCase, + useValue: executePayoutUseCaseMock, + }, + { + provide: EnableAssetSyncUseCase, + useValue: enableAssetSyncUseCaseMock, + }, + { + provide: DisableAssetSyncUseCase, + useValue: disableAssetSyncUseCaseMock, + }, + { + provide: GetDistributionHolderCountUseCase, + useValue: getDistributionHolderCountUseCaseMock, + }, + ], + }).compile() + + app = moduleFixture.createNestApplication() + await app.init() + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + afterAll(async () => { + await app.close() + }) + + describe("POST /assets", () => { + it("should create an asset", async () => { + const lifeCycleCashFlowAddress = fakeLifeCycleCashFlowAddress() + const requestPayload: ImportAssetRequest = { + hederaTokenAddress: lifeCycleCashFlowAddress.hederaAddress, + } + + const createdAsset = AssetUtils.newInstance({ + hederaTokenAddress: requestPayload.hederaTokenAddress, + }).withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + createAssetUseCaseMock.execute.mockResolvedValue(createdAsset) + + const response = await request(app.getHttpServer()) + .post("/assets/import") + .send(requestPayload) + .expect(HttpStatus.CREATED) + + const expectedResponse = { + ...AssetResponse.fromAsset(createdAsset), + createdAt: createdAsset.createdAt.toISOString(), + updatedAt: createdAsset.updatedAt.toISOString(), + } + + expect(response.body).toEqual(expectedResponse) + expect(createAssetUseCaseMock.execute).toHaveBeenCalledWith(requestPayload.hederaTokenAddress) + }) + + it("should return 400 for invalid request payload", async () => { + const invalidPayload = { + name: "", + hederaTokenAddress: "invalid-address", + } + + const response = await request(app.getHttpServer()) + .post("/assets/import") + .send(invalidPayload) + .expect(HttpStatus.BAD_REQUEST) + + expect(response.body.message).toEqual( + expect.stringContaining("hederaTokenAddress must be a valid Hedera address format"), + ) + }) + + it("should return 500 if use case fails", async () => { + const requestPayload: ImportAssetRequest = { + hederaTokenAddress: `0.0.${faker.number.int({ min: 10000, max: 99999 })}`, + } + + createAssetUseCaseMock.execute.mockRejectedValue(new Error("Service error")) + + await request(app.getHttpServer()) + .post("/assets/import") + .send(requestPayload) + .expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(createAssetUseCaseMock.execute).toHaveBeenCalled() + }) + }) + + describe("GET /assets", () => { + it("should return all assets successfully", async () => { + const asset1 = AssetUtils.newInstance() + const asset2 = AssetUtils.newInstance() + const assets = { + items: [asset1, asset2], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + + getAssetsUseCaseMock.execute.mockResolvedValue(assets) + + const response = await request(app.getHttpServer()).get("/assets").expect(HttpStatus.OK) + + const expectedResponse = { + items: assets.items.map((asset) => ({ + ...AssetResponse.fromAsset(asset), + createdAt: asset.createdAt.toISOString(), + updatedAt: asset.updatedAt.toISOString(), + })), + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + + expect(response.body).toEqual(expectedResponse) + expect(response.body.items).toHaveLength(2) + expect(getAssetsUseCaseMock.execute).toHaveBeenCalledWith(PageOptions.DEFAULT) + }) + + it("should return empty page when no assets exist", async () => { + const emptyPage = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + + getAssetsUseCaseMock.execute.mockResolvedValue(emptyPage) + + const response = await request(app.getHttpServer()).get("/assets").expect(HttpStatus.OK) + + expect(response.body).toEqual(emptyPage) + expect(response.body.items).toHaveLength(0) + expect(getAssetsUseCaseMock.execute).toHaveBeenCalledWith(PageOptions.DEFAULT) + }) + + it("should return 500 if use case fails", async () => { + getAssetsUseCaseMock.execute.mockRejectedValue(new Error("Database connection error")) + + await request(app.getHttpServer()).get("/assets").expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(getAssetsUseCaseMock.execute).toHaveBeenCalledWith(PageOptions.DEFAULT) + }) + + it("should accept pagination parameters", async () => { + const asset1 = AssetUtils.newInstance() + const assets = { + items: [asset1], + total: 1, + page: 2, + limit: 5, + totalPages: 1, + } + + getAssetsUseCaseMock.execute.mockResolvedValue(assets) + + const response = await request(app.getHttpServer()) + .get("/assets?page=2&limit=5&orderBy=updatedAt&order=asc") + .expect(HttpStatus.OK) + + const expectedResponse = { + items: assets.items.map((asset) => ({ + ...AssetResponse.fromAsset(asset), + createdAt: asset.createdAt.toISOString(), + updatedAt: asset.updatedAt.toISOString(), + })), + total: 1, + page: 2, + limit: 5, + totalPages: 1, + } + + expect(response.body).toEqual(expectedResponse) + expect(getAssetsUseCaseMock.execute).toHaveBeenCalledWith({ + page: 2, + limit: 5, + order: { orderBy: "updatedAt", order: "asc" }, + }) + }) + }) + + describe("GET /assets/:id", () => { + it("should return an asset successfully", async () => { + const assetId = faker.string.uuid() + const asset = AssetUtils.newInstance({ id: assetId }) + + getAssetUseCaseMock.execute.mockResolvedValue(asset) + + const response = await request(app.getHttpServer()).get(`/assets/${assetId}`).expect(HttpStatus.OK) + + const expectedResponse = { + ...AssetResponse.fromAsset(asset), + createdAt: asset.createdAt.toISOString(), + updatedAt: asset.updatedAt.toISOString(), + } + + expect(response.body).toEqual(expectedResponse) + expect(response.body.type).toBe(asset.type) + expect(response.body.isPaused).toBe(asset.isPaused) + expect(getAssetUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return 404 when asset is not found", async () => { + const assetId = faker.string.uuid() + + getAssetUseCaseMock.execute.mockRejectedValue(new AssetNotFoundError(assetId)) + + await request(app.getHttpServer()).get(`/assets/${assetId}`).expect(HttpStatus.NOT_FOUND) + + expect(getAssetUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return 500 if use case fails with unexpected error", async () => { + const assetId = faker.string.uuid() + + getAssetUseCaseMock.execute.mockRejectedValue(new Error("Database connection error")) + + await request(app.getHttpServer()).get(`/assets/${assetId}`).expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(getAssetUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + }) + + describe("PATCH /assets/:assetId/pause", () => { + it("should pause an asset successfully", async () => { + const assetId = faker.string.uuid() + const asset = AssetUtils.newInstance({ id: assetId }) + + pauseAssetUseCaseMock.execute.mockResolvedValue(asset) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/pause`).expect(HttpStatus.OK) + + expect(pauseAssetUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return 500 if pause use case fails", async () => { + const assetId = faker.string.uuid() + + pauseAssetUseCaseMock.execute.mockRejectedValue(new Error("Pause service error")) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/pause`).expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(pauseAssetUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + }) + + describe("PATCH /assets/:assetId/unpause", () => { + it("should unpause an asset successfully", async () => { + const assetId = faker.string.uuid() + const asset = AssetUtils.newInstance({ id: assetId }) + + unpauseAssetUseCaseMock.execute.mockResolvedValue(asset) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/unpause`).expect(HttpStatus.OK) + + expect(unpauseAssetUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return 500 if unpause use case fails", async () => { + const assetId = faker.string.uuid() + + unpauseAssetUseCaseMock.execute.mockRejectedValue(new Error("Unpause service error")) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/unpause`).expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(unpauseAssetUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + }) + + describe("GET /assets/:hederaTokenAddress/metadata", () => { + it("should return basic asset information successfully without maturity date", async () => { + const hederaTokenAddress = fakeHederaAddress() + const expectedBasicInfo = { + hederaTokenAddress, + name: faker.finance.accountName(), + symbol: faker.finance.currencyCode(), + assetType: AssetType.EQUITY, + } + + getBasicAssetInformationUseCaseMock.execute.mockResolvedValue(expectedBasicInfo) + + const response = await request(app.getHttpServer()) + .get(`/assets/${hederaTokenAddress}/metadata`) + .expect(HttpStatus.OK) + + expect(response.body).toEqual(expectedBasicInfo) + expect(response.body.hederaTokenAddress).toBe(hederaTokenAddress) + expect(response.body.name).toBe(expectedBasicInfo.name) + expect(response.body.symbol).toBe(expectedBasicInfo.symbol) + expect(response.body.assetType).toBe(AssetType.EQUITY) + expect(response.body.maturityDate).toBeUndefined() + expect(getBasicAssetInformationUseCaseMock.execute).toHaveBeenCalledWith(hederaTokenAddress) + }) + + it("should return basic asset information successfully with maturity date", async () => { + const hederaTokenAddress = fakeHederaAddress() + const maturityDate = faker.date.future() + const expectedBasicInfo = { + hederaTokenAddress, + name: faker.finance.accountName(), + symbol: faker.finance.currencyCode(), + assetType: AssetType.BOND, + maturityDate, + } + + getBasicAssetInformationUseCaseMock.execute.mockResolvedValue(expectedBasicInfo) + + const response = await request(app.getHttpServer()) + .get(`/assets/${hederaTokenAddress}/metadata`) + .expect(HttpStatus.OK) + + expect(response.body).toEqual({ + ...expectedBasicInfo, + maturityDate: maturityDate.toISOString(), + }) + expect(response.body.hederaTokenAddress).toBe(hederaTokenAddress) + expect(response.body.name).toBe(expectedBasicInfo.name) + expect(response.body.symbol).toBe(expectedBasicInfo.symbol) + expect(response.body.assetType).toBe(AssetType.BOND) + expect(response.body.maturityDate).toBe(maturityDate.toISOString()) + expect(getBasicAssetInformationUseCaseMock.execute).toHaveBeenCalledWith(hederaTokenAddress) + }) + + it("should return 400 for invalid asset ID format", async () => { + const invalidAssetId = "invalid-uuid" + + await request(app.getHttpServer()).get(`/assets/${invalidAssetId}/metadata`).expect(HttpStatus.BAD_REQUEST) + + expect(getBasicAssetInformationUseCaseMock.execute).not.toHaveBeenCalled() + }) + + it("should return 404 when asset is not found", async () => { + const hederaTokenAddress = fakeHederaAddress() + + getBasicAssetInformationUseCaseMock.execute.mockRejectedValue(new AssetNotFoundError(hederaTokenAddress)) + + await request(app.getHttpServer()).get(`/assets/${hederaTokenAddress}/metadata`).expect(HttpStatus.NOT_FOUND) + + expect(getBasicAssetInformationUseCaseMock.execute).toHaveBeenCalledWith(hederaTokenAddress) + }) + + it("should return 500 if use case fails with unexpected error", async () => { + const hederaTokenAddress = fakeHederaAddress() + + getBasicAssetInformationUseCaseMock.execute.mockRejectedValue(new Error("On-chain repository error")) + + await request(app.getHttpServer()) + .get(`/assets/${hederaTokenAddress}/metadata`) + .expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(getBasicAssetInformationUseCaseMock.execute).toHaveBeenCalledWith(hederaTokenAddress) + }) + }) + + describe("GET /assets/:assetId/distributions", () => { + it("should return paginated distributions for an asset", async () => { + // Given + const asset = AssetUtils.newInstance() + const distribution1 = DistributionUtils.newInstance({ asset }) + const distribution2 = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.RECURRING, + } as any, + }) + const distributions = { + items: [distribution1, distribution2], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + const holdersNumber = 2 + + getAssetDistributionsUseCaseMock.execute.mockResolvedValue(distributions) + getDistributionHolderCountUseCaseMock.execute.mockResolvedValue(holdersNumber) + + // When + const response = await request(app.getHttpServer()).get(`/assets/${asset.id}/distributions`).expect(HttpStatus.OK) + + // Then + const expectedResponse = { + items: distributions.items.map((distribution) => ({ + ...DistributionResponse.fromDistribution(distribution), + createdAt: distribution.createdAt.toISOString(), + updatedAt: distribution.updatedAt.toISOString(), + executionDate: ( + (distribution.details as CorporateActionDetails).executionDate || (distribution.details as any).executeAt + ).toISOString(), + holdersNumber, + asset: { + ...AssetResponse.fromAsset(distribution.asset), + createdAt: distribution.asset.createdAt.toISOString(), + updatedAt: distribution.asset.updatedAt.toISOString(), + }, + })), + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + + expect(response.body).toEqual(expectedResponse) + expect(getAssetDistributionsUseCaseMock.execute).toHaveBeenCalledWith(asset.id, PageOptions.DEFAULT) + }) + + it("should return empty page when no distributions exist", async () => { + // Given + const asset = AssetUtils.newInstance() + const emptyPage = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + + getAssetDistributionsUseCaseMock.execute.mockResolvedValue(emptyPage) + + // When + const response = await request(app.getHttpServer()).get(`/assets/${asset.id}/distributions`).expect(HttpStatus.OK) + + // Then + expect(response.body).toEqual(emptyPage) + expect(getAssetDistributionsUseCaseMock.execute).toHaveBeenCalledWith(asset.id, PageOptions.DEFAULT) + }) + + it("should accept custom pagination parameters", async () => { + // Given + const asset = AssetUtils.newInstance() + const distribution = DistributionUtils.newInstance({ asset }) + const distributions = { + items: [distribution], + total: 1, + page: 2, + limit: 5, + totalPages: 1, + } + const holdersNumber = 3 + + getAssetDistributionsUseCaseMock.execute.mockResolvedValue(distributions) + getDistributionHolderCountUseCaseMock.execute.mockResolvedValue(holdersNumber) + + // When + const response = await request(app.getHttpServer()) + .get(`/assets/${asset.id}/distributions`) + .query({ page: 2, limit: 5 }) + .expect(HttpStatus.OK) + + // Then + const expectedResponse = { + items: distributions.items.map((distribution) => ({ + ...DistributionResponse.fromDistribution(distribution), + createdAt: distribution.createdAt.toISOString(), + updatedAt: distribution.updatedAt.toISOString(), + executionDate: (distribution.details as CorporateActionDetails).executionDate.toISOString(), + holdersNumber, + asset: { + ...AssetResponse.fromAsset(distribution.asset), + createdAt: distribution.asset.createdAt.toISOString(), + updatedAt: distribution.asset.updatedAt.toISOString(), + }, + })), + total: 1, + page: 2, + limit: 5, + totalPages: 1, + } + + expect(response.body).toEqual(expectedResponse) + expect(getAssetDistributionsUseCaseMock.execute).toHaveBeenCalledWith(asset.id, { + page: 2, + limit: 5, + order: OrderPageOptions.DEFAULT, + }) + }) + + it("should return 500 if use case fails", async () => { + // Given + const asset = AssetUtils.newInstance() + getAssetDistributionsUseCaseMock.execute.mockRejectedValue(new Error("Service error")) + + // When/Then + await request(app.getHttpServer()) + .get(`/assets/${asset.id}/distributions`) + .expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(getAssetDistributionsUseCaseMock.execute).toHaveBeenCalledWith(asset.id, PageOptions.DEFAULT) + }) + }) + + describe("POST /assets/:assetId/distributions/payout", () => { + const assetId = faker.string.uuid() + const payload: CreatePayoutRequest = { + subtype: PayoutSubtype.ONE_OFF, + executeAt: faker.date.future().toISOString(), + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: faker.helpers.objectValue(AmountType), + concept: faker.string.alpha({ length: 10 }), + } + + it("should execute payout successfully", async () => { + executePayoutUseCaseMock.execute.mockResolvedValue(undefined) + const expected = { + ...payload, + executeAt: new Date(payload.executeAt), + assetId, + } + + await request(app.getHttpServer()) + .post(`/assets/${assetId}/distributions/payout`) + .send(payload) + .expect(HttpStatus.CREATED) + + expect(executePayoutUseCaseMock.execute).toHaveBeenCalledWith(expected) + }) + + it("should return 404 when asset is not found", async () => { + executePayoutUseCaseMock.execute.mockRejectedValue(new AssetNotFoundError(assetId)) + const expected = { + ...payload, + executeAt: new Date(payload.executeAt), + assetId, + } + + await request(app.getHttpServer()) + .post(`/assets/${assetId}/distributions/payout`) + .send(payload) + .expect(HttpStatus.NOT_FOUND) + + expect(executePayoutUseCaseMock.execute).toHaveBeenCalledWith(expected) + }) + + it("should return 500 when use case throws unexpected error", async () => { + executePayoutUseCaseMock.execute.mockRejectedValue(new Error("Unexpected error")) + const expected = { + ...payload, + executeAt: new Date(payload.executeAt), + assetId, + } + + await request(app.getHttpServer()) + .post(`/assets/${assetId}/distributions/payout`) + .send(payload) + .expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(executePayoutUseCaseMock.execute).toHaveBeenCalledWith(expected) + }) + + it("should handle special characters in assetId", async () => { + const specialAssetId = "asset-123-test" + executePayoutUseCaseMock.execute.mockResolvedValue(undefined) + const expected = { + ...payload, + executeAt: new Date(payload.executeAt), + assetId: specialAssetId, + } + + await request(app.getHttpServer()) + .post(`/assets/${specialAssetId}/distributions/payout`) + .send(payload) + .expect(HttpStatus.CREATED) + + expect(executePayoutUseCaseMock.execute).toHaveBeenCalledWith(expected) + }) + }) + + describe("Patch /assets/:assetId/enable-sync", () => { + it("should enable the synchronization of an asset successfully", async () => { + const assetId = faker.string.uuid() + const syncEnabledAsset = AssetUtils.newInstance({ id: assetId, syncEnabled: true }) + enableAssetSyncUseCaseMock.execute.mockResolvedValue(syncEnabledAsset) + await request(app.getHttpServer()).patch(`/assets/${assetId}/enable-sync`).expect(HttpStatus.OK) + + expect(enableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return 404 when asset does not exist", async () => { + const assetId = faker.string.uuid() + enableAssetSyncUseCaseMock.execute.mockRejectedValue(new AssetNotFoundError(assetId)) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/enable-sync`).expect(HttpStatus.NOT_FOUND) + + expect(enableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return asset without changes when synchronization already enabled", async () => { + const assetId = faker.string.uuid() + const alreadySyncEnabledAsset = AssetUtils.newInstance({ id: assetId, syncEnabled: true }) + enableAssetSyncUseCaseMock.execute.mockResolvedValue(alreadySyncEnabledAsset) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/enable-sync`).expect(HttpStatus.OK) + + expect(enableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return 500 when use case throws unexpected error", async () => { + const assetId = faker.string.uuid() + enableAssetSyncUseCaseMock.execute.mockRejectedValue(new Error("Repository update failed")) + + await request(app.getHttpServer()) + .patch(`/assets/${assetId}/enable-sync`) + .expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(enableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should enable the synchronization of a BOND type asset successfully", async () => { + const assetId = faker.string.uuid() + const syncEnabledAsset = AssetUtils.newInstance({ + id: assetId, + type: AssetType.BOND, + syncEnabled: true, + }) + enableAssetSyncUseCaseMock.execute.mockResolvedValue(syncEnabledAsset) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/enable-sync`).expect(HttpStatus.OK) + + expect(enableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + }) + + describe("Patch /assets/:assetId/disable-sync", () => { + it("should disable the synchronization of an asset successfully", async () => { + const assetId = faker.string.uuid() + const syncEnabledAsset = AssetUtils.newInstance({ id: assetId, syncEnabled: true }) + disableAssetSyncUseCaseMock.execute.mockResolvedValue(syncEnabledAsset) + await request(app.getHttpServer()).patch(`/assets/${assetId}/disable-sync`).expect(HttpStatus.OK) + + expect(disableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return 404 when asset does not exist", async () => { + const assetId = faker.string.uuid() + disableAssetSyncUseCaseMock.execute.mockRejectedValue(new AssetNotFoundError(assetId)) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/disable-sync`).expect(HttpStatus.NOT_FOUND) + + expect(disableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return asset without changes when synchronization already disabled", async () => { + const assetId = faker.string.uuid() + const alreadySyncDisabledAsset = AssetUtils.newInstance({ id: assetId, syncEnabled: false }) + disableAssetSyncUseCaseMock.execute.mockResolvedValue(alreadySyncDisabledAsset) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/disable-sync`).expect(HttpStatus.OK) + + expect(disableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should return 500 when use case throws unexpected error", async () => { + const assetId = faker.string.uuid() + disableAssetSyncUseCaseMock.execute.mockRejectedValue(new Error("Repository update failed")) + + await request(app.getHttpServer()) + .patch(`/assets/${assetId}/disable-sync`) + .expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(disableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + + it("should disable the synchronization of a BOND type asset successfully", async () => { + const assetId = faker.string.uuid() + const syncEnabledAsset = AssetUtils.newInstance({ + id: assetId, + type: AssetType.BOND, + syncEnabled: true, + }) + disableAssetSyncUseCaseMock.execute.mockResolvedValue(syncEnabledAsset) + + await request(app.getHttpServer()).patch(`/assets/${assetId}/disable-sync`).expect(HttpStatus.OK) + + expect(disableAssetSyncUseCaseMock.execute).toHaveBeenCalledWith(assetId) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/integration/rest/distribution/distribution.controller.spec.ts b/apps/mass-payout/backend/test/integration/rest/distribution/distribution.controller.spec.ts new file mode 100644 index 000000000..d3f3b2140 --- /dev/null +++ b/apps/mass-payout/backend/test/integration/rest/distribution/distribution.controller.spec.ts @@ -0,0 +1,608 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetDistributionHoldersUseCase } from "@application/use-cases/get-distribution-holders.use-case" +import { GetDistributionUseCase } from "@application/use-cases/get-distribution.use-case" +import { GetDistributionsUseCase } from "@application/use-cases/get-distributions.use-case" +import { + DistributionNotFoundError, + DistributionNotInStatusError, + DistributionNotPayoutError, +} from "@domain/errors/distribution.error" +import { + CorporateActionDetails, + DistributionStatus, + PayoutDetails, + DistributionType, + PayoutSubtype, + AmountType, +} from "@domain/model/distribution" +import { PageOptions } from "@domain/model/page" +import { createMock } from "@golevelup/ts-jest" +import { DistributionController } from "@infrastructure/rest/distribution/distribution.controller" +import { HttpStatus, INestApplication } from "@nestjs/common" +import { Test, TestingModule } from "@nestjs/testing" +import { DistributionUtils } from "@test/shared/distribution.utils" +import request from "supertest" +import { CancelDistributionUseCase } from "@application/use-cases/cancel-distribution.use-case" +import { RetryFailedHoldersUseCase } from "@application/use-cases/retry-failed-holders.use-case" + +describe(DistributionController.name, () => { + let app: INestApplication + const getDistributionUseCaseMock = createMock() + const getDistributionsUseCaseMock = createMock() + const getDistributionHoldersUseCaseMock = createMock() + const cancelDistributionUseCaseMock = createMock() + const retryFailedHoldersUseCaseMock = createMock() + + beforeAll(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + controllers: [DistributionController], + providers: [ + { + provide: GetDistributionUseCase, + useValue: getDistributionUseCaseMock, + }, + { + provide: GetDistributionsUseCase, + useValue: getDistributionsUseCaseMock, + }, + { + provide: GetDistributionHoldersUseCase, + useValue: getDistributionHoldersUseCaseMock, + }, + { + provide: CancelDistributionUseCase, + useValue: cancelDistributionUseCaseMock, + }, + { + provide: RetryFailedHoldersUseCase, + useValue: retryFailedHoldersUseCaseMock, + }, + ], + }).compile() + + app = moduleFixture.createNestApplication() + await app.init() + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + afterAll(async () => { + await app.close() + }) + + describe("GET /distributions", () => { + it("should return paginated distributions successfully", async () => { + const distribution1 = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + }) + const distribution2 = DistributionUtils.newInstance({ + status: DistributionStatus.COMPLETED, + }) + + const pageOptions: PageOptions = { page: 1, limit: 10, order: { order: "DESC", orderBy: "createdAt" } } + const expectedPage = { + items: [distribution1, distribution2], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + + getDistributionsUseCaseMock.execute.mockResolvedValue(expectedPage) + + const response = await request(app.getHttpServer()) + .get("/distributions") + .query({ page: 1, limit: 10 }) + .expect(HttpStatus.OK) + + expect(response.body).toEqual({ + items: [ + { + id: distribution1.id, + asset: { + id: distribution1.asset.id, + name: distribution1.asset.name, + type: distribution1.asset.type, + hederaTokenAddress: distribution1.asset.hederaTokenAddress, + evmTokenAddress: distribution1.asset.evmTokenAddress, + symbol: distribution1.asset.symbol, + lifeCycleCashFlowHederaAddress: distribution1.asset.lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: distribution1.asset.lifeCycleCashFlowEvmAddress, + maturityDate: distribution1.asset.maturityDate?.toISOString(), + isPaused: distribution1.asset.isPaused, + syncEnabled: distribution1.asset.syncEnabled, + createdAt: distribution1.asset.createdAt.toISOString(), + updatedAt: distribution1.asset.updatedAt.toISOString(), + }, + corporateActionID: (distribution1.details as any).corporateActionId.value, + executionDate: (distribution1.details as any).executionDate.toISOString(), + status: distribution1.status, + type: distribution1.details.type, + createdAt: distribution1.createdAt.toISOString(), + updatedAt: distribution1.updatedAt.toISOString(), + }, + { + id: distribution2.id, + asset: { + id: distribution2.asset.id, + name: distribution2.asset.name, + type: distribution2.asset.type, + hederaTokenAddress: distribution2.asset.hederaTokenAddress, + evmTokenAddress: distribution2.asset.evmTokenAddress, + symbol: distribution2.asset.symbol, + lifeCycleCashFlowHederaAddress: distribution2.asset.lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: distribution2.asset.lifeCycleCashFlowEvmAddress, + maturityDate: distribution2.asset.maturityDate?.toISOString(), + isPaused: distribution2.asset.isPaused, + syncEnabled: distribution2.asset.syncEnabled, + createdAt: distribution2.asset.createdAt.toISOString(), + updatedAt: distribution2.asset.updatedAt.toISOString(), + }, + corporateActionID: (distribution2.details as any).corporateActionId.value, + executionDate: (distribution2.details as any).executionDate.toISOString(), + status: distribution2.status, + type: distribution2.details.type, + createdAt: distribution2.createdAt.toISOString(), + updatedAt: distribution2.updatedAt.toISOString(), + }, + ], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + }) + expect(getDistributionsUseCaseMock.execute).toHaveBeenCalledWith(pageOptions) + }) + + it("should return empty page when no distributions exist", async () => { + const pageOptions: PageOptions = { page: 1, limit: 10, order: { order: "DESC", orderBy: "createdAt" } } + const expectedPage = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + + getDistributionsUseCaseMock.execute.mockResolvedValue(expectedPage) + + const response = await request(app.getHttpServer()) + .get("/distributions") + .query({ page: 1, limit: 10 }) + .expect(HttpStatus.OK) + + expect(response.body).toEqual({ + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + }) + expect(getDistributionsUseCaseMock.execute).toHaveBeenCalledWith(pageOptions) + }) + + it("should use default pagination when no query parameters provided", async () => { + const pageOptions: PageOptions = { page: 1, limit: 10, order: { order: "DESC", orderBy: "createdAt" } } + const expectedPage = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + + getDistributionsUseCaseMock.execute.mockResolvedValue(expectedPage) + + await request(app.getHttpServer()).get("/distributions").expect(HttpStatus.OK) + + expect(getDistributionsUseCaseMock.execute).toHaveBeenCalledWith(pageOptions) + }) + + it("should handle custom pagination parameters", async () => { + const pageOptions: PageOptions = { page: 2, limit: 5, order: { order: "DESC", orderBy: "createdAt" } } + const expectedPage = { + items: [], + total: 0, + page: 2, + limit: 5, + totalPages: 0, + } + + getDistributionsUseCaseMock.execute.mockResolvedValue(expectedPage) + + const response = await request(app.getHttpServer()) + .get("/distributions") + .query({ page: 2, limit: 5 }) + .expect(HttpStatus.OK) + + expect(response.body.page).toBe(2) + expect(response.body.limit).toBe(5) + expect(getDistributionsUseCaseMock.execute).toHaveBeenCalledWith(pageOptions) + }) + }) + + describe("GET /distributions/:distributionId", () => { + it("should return corporate action distribution when found", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + }) + + getDistributionUseCaseMock.execute.mockResolvedValue(distribution) + + const response = await request(app.getHttpServer()).get(`/distributions/${distribution.id}`).expect(HttpStatus.OK) + + expect(response.body).toEqual({ + id: distribution.id, + asset: { + id: distribution.asset.id, + name: distribution.asset.name, + type: distribution.asset.type, + hederaTokenAddress: distribution.asset.hederaTokenAddress, + evmTokenAddress: distribution.asset.evmTokenAddress, + symbol: distribution.asset.symbol, + lifeCycleCashFlowHederaAddress: distribution.asset.lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: distribution.asset.lifeCycleCashFlowEvmAddress, + maturityDate: distribution.asset.maturityDate?.toISOString(), + isPaused: distribution.asset.isPaused, + syncEnabled: distribution.asset.syncEnabled, + createdAt: distribution.asset.createdAt.toISOString(), + updatedAt: distribution.asset.updatedAt.toISOString(), + }, + corporateActionID: (distribution.details as CorporateActionDetails).corporateActionId.value, + executionDate: (distribution.details as CorporateActionDetails).executionDate.toISOString(), + status: distribution.status, + type: distribution.details.type, + createdAt: distribution.createdAt.toISOString(), + updatedAt: distribution.updatedAt.toISOString(), + }) + expect(getDistributionUseCaseMock.execute).toHaveBeenCalledWith(distribution.id) + }) + + it("should return payout distribution with amount and subtype when found", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.ONE_OFF, + amount: "100", + amountType: AmountType.FIXED, + } as any, + }) + + getDistributionUseCaseMock.execute.mockResolvedValue(distribution) + + const response = await request(app.getHttpServer()).get(`/distributions/${distribution.id}`).expect(HttpStatus.OK) + + expect(response.body).toEqual({ + id: distribution.id, + asset: { + id: distribution.asset.id, + name: distribution.asset.name, + type: distribution.asset.type, + hederaTokenAddress: distribution.asset.hederaTokenAddress, + evmTokenAddress: distribution.asset.evmTokenAddress, + symbol: distribution.asset.symbol, + lifeCycleCashFlowHederaAddress: distribution.asset.lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: distribution.asset.lifeCycleCashFlowEvmAddress, + maturityDate: distribution.asset.maturityDate?.toISOString(), + isPaused: distribution.asset.isPaused, + syncEnabled: distribution.asset.syncEnabled, + createdAt: distribution.asset.createdAt.toISOString(), + updatedAt: distribution.asset.updatedAt.toISOString(), + }, + concept: (distribution.details as PayoutDetails).concept, + amount: (distribution.details as PayoutDetails).amount, + amountType: (distribution.details as PayoutDetails).amountType, + subtype: (distribution.details as PayoutDetails).subtype, + executionDate: (distribution.details as any).executeAt.toISOString(), + status: distribution.status, + type: distribution.details.type, + createdAt: distribution.createdAt.toISOString(), + updatedAt: distribution.updatedAt.toISOString(), + }) + expect(getDistributionUseCaseMock.execute).toHaveBeenCalledWith(distribution.id) + }) + + it("should return 404 when distribution is not found", async () => { + const distributionId = "non-existent-id" + getDistributionUseCaseMock.execute.mockRejectedValue(new DistributionNotFoundError(distributionId)) + + await request(app.getHttpServer()).get(`/distributions/${distributionId}`).expect(HttpStatus.NOT_FOUND) + + expect(getDistributionUseCaseMock.execute).toHaveBeenCalledWith(distributionId) + }) + + it("should return 500 if use case fails with unexpected error", async () => { + const distributionId = "some-id" + getDistributionUseCaseMock.execute.mockRejectedValue(new Error("Repository error")) + + await request(app.getHttpServer()) + .get(`/distributions/${distributionId}`) + .expect(HttpStatus.INTERNAL_SERVER_ERROR) + + expect(getDistributionUseCaseMock.execute).toHaveBeenCalledWith(distributionId) + }) + }) + + describe("PATCH /distributions/:distributionId/cancel", () => { + it("should cancel distribution", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + }) + + cancelDistributionUseCaseMock.execute.mockResolvedValue(undefined) + + await request(app.getHttpServer()).patch(`/distributions/${distribution.id}/cancel`).expect(HttpStatus.OK) + + expect(cancelDistributionUseCaseMock.execute).toHaveBeenCalledWith({ distributionId: distribution.id }) + }) + + it("should return 404 when distribution is not found", async () => { + const distributionId = "non-existent-id" + cancelDistributionUseCaseMock.execute.mockRejectedValue(new DistributionNotFoundError(distributionId)) + + await request(app.getHttpServer()).patch(`/distributions/${distributionId}/cancel`).expect(HttpStatus.NOT_FOUND) + + expect(cancelDistributionUseCaseMock.execute).toHaveBeenCalledWith({ distributionId: distributionId }) + }) + + it("should return 409 if distribution is not a payout", async () => { + const distributionId = "some-id" + cancelDistributionUseCaseMock.execute.mockRejectedValue(new DistributionNotPayoutError(distributionId)) + + await request(app.getHttpServer()).patch(`/distributions/${distributionId}/cancel`).expect(HttpStatus.CONFLICT) + + expect(cancelDistributionUseCaseMock.execute).toHaveBeenCalledWith({ distributionId: distributionId }) + }) + + it("should return 409 if distribution is not in SCHEDULED status", async () => { + const distributionId = "some-id" + cancelDistributionUseCaseMock.execute.mockRejectedValue( + new DistributionNotInStatusError(distributionId, DistributionStatus.SCHEDULED), + ) + + await request(app.getHttpServer()).patch(`/distributions/${distributionId}/cancel`).expect(HttpStatus.CONFLICT) + + expect(cancelDistributionUseCaseMock.execute).toHaveBeenCalledWith({ distributionId: distributionId }) + }) + }) + + describe("PATCH /distributions/:distributionId/retry", () => { + it("should retry distribution", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.FAILED, + }) + + retryFailedHoldersUseCaseMock.execute.mockResolvedValue(undefined) + + await request(app.getHttpServer()).patch(`/distributions/${distribution.id}/retry`).expect(HttpStatus.OK) + + expect(retryFailedHoldersUseCaseMock.execute).toHaveBeenCalledWith({ distributionId: distribution.id }) + }) + + it("should return 404 when distribution is not found", async () => { + const distributionId = "non-existent-id" + retryFailedHoldersUseCaseMock.execute.mockRejectedValue(new DistributionNotFoundError(distributionId)) + + await request(app.getHttpServer()).patch(`/distributions/${distributionId}/retry`).expect(HttpStatus.NOT_FOUND) + + expect(retryFailedHoldersUseCaseMock.execute).toHaveBeenCalledWith({ distributionId: distributionId }) + }) + + it("should return 409 if distribution is not in FAILED status", async () => { + const distributionId = "some-id" + retryFailedHoldersUseCaseMock.execute.mockRejectedValue( + new DistributionNotInStatusError(distributionId, DistributionStatus.FAILED), + ) + + await request(app.getHttpServer()).patch(`/distributions/${distributionId}/retry`).expect(HttpStatus.CONFLICT) + + expect(retryFailedHoldersUseCaseMock.execute).toHaveBeenCalledWith({ distributionId: distributionId }) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/shared/asset.utils.ts b/apps/mass-payout/backend/test/shared/asset.utils.ts new file mode 100644 index 000000000..a15301d73 --- /dev/null +++ b/apps/mass-payout/backend/test/shared/asset.utils.ts @@ -0,0 +1,228 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { LifeCycleCashFlowAddress } from "@domain/model/life-cycle-cash-flow-address.value-object" +import { faker } from "@faker-js/faker" +import { fakeHederaAddress, fakeLifeCycleCashFlowAddress } from "@test/shared/utils" + +export const AssetUtils = { + newInstance: (props: Partial = {}): Asset => { + return Asset.create( + props.name ?? faker.string.alphanumeric({ length: 10 }), + props.type ?? AssetType.EQUITY, + props.hederaTokenAddress ?? fakeHederaAddress(), + props.evmTokenAddress ?? faker.finance.ethereumAddress(), + props.symbol ?? faker.string.alpha({ length: 4 }).toUpperCase(), + props.maturityDate, + props.isPaused ?? false, + ) + }, + + newInstanceWithLifeCycleCashFlow: (lifeCycleCashFlowAddress?: LifeCycleCashFlowAddress): Asset => { + const asset = AssetUtils.newInstance() + return asset.withLifeCycleCashFlow(lifeCycleCashFlowAddress ?? fakeLifeCycleCashFlowAddress()) + }, +} diff --git a/apps/mass-payout/backend/test/shared/batch-payout.utils.ts b/apps/mass-payout/backend/test/shared/batch-payout.utils.ts new file mode 100644 index 000000000..a327c2523 --- /dev/null +++ b/apps/mass-payout/backend/test/shared/batch-payout.utils.ts @@ -0,0 +1,229 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { faker } from "@faker-js/faker/." +import crypto from "crypto" +import { BatchPayout, BatchPayoutStatus } from "@domain/model/batch-payout" +import { fakeHederaTxId } from "@test/shared/utils" +import { DistributionUtils } from "@test/shared/distribution.utils" + +export class BatchPayoutUtils { + static newInstance(partial?: Partial): BatchPayout { + return BatchPayout.createExisting( + partial?.id ?? crypto.randomUUID(), + partial?.distribution ?? DistributionUtils.newInstance(), + partial?.name ?? faker.string.alpha({ length: 10 }), + partial?.hederaTransactionId ?? fakeHederaTxId(), + partial?.hederaTransactionHash ?? BatchPayoutUtils.generateHederaTransactionHash(), + partial?.holdersNumber ?? faker.number.int({ min: 1, max: 100 }), + partial?.status ?? BatchPayoutStatus.IN_PROGRESS, + partial?.createdAt ?? faker.date.past(), + partial?.updatedAt ?? new Date(), + ) + } + + private static generateHederaTransactionHash(): string { + return `0x${crypto.randomBytes(48).toString("hex")}` + } +} diff --git a/apps/mass-payout/backend/test/shared/containers/postgresql-container.ts b/apps/mass-payout/backend/test/shared/containers/postgresql-container.ts new file mode 100644 index 000000000..520cb79b6 --- /dev/null +++ b/apps/mass-payout/backend/test/shared/containers/postgresql-container.ts @@ -0,0 +1,247 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GenericContainer, StartedTestContainer } from "testcontainers" +import process from "process" +import { TypeOrmModuleOptions } from "@nestjs/typeorm" + +export class PostgreSqlContainer { + private static INTERNAL_PORT = 5432 + private static DATABASE = process.env.POSTGRESQL_DB || "test" + private static USER = process.env.POSTGRESQL_USER || "test" + private static PASSWORD = process.env.POSTGRESQL_PASSWORD || "test" + private container: StartedTestContainer + + static async create(): Promise { + const postgresqlContainer = new PostgreSqlContainer() + + postgresqlContainer.container = await new GenericContainer("postgres") + .withExposedPorts(this.INTERNAL_PORT) + .withEnvironment({ + POSTGRES_DB: this.DATABASE, + POSTGRES_USER: this.USER, + POSTGRES_PASSWORD: this.PASSWORD, + }) + .start() + + return postgresqlContainer + } + + public getConfig(): TypeOrmModuleOptions { + return { + host: this.container.getHost(), + port: this.container.getMappedPort(PostgreSqlContainer.INTERNAL_PORT), + username: PostgreSqlContainer.USER, + password: PostgreSqlContainer.PASSWORD, + database: PostgreSqlContainer.DATABASE, + synchronize: true, + migrationsRun: false, + logging: false, + } + } + + async stop(): Promise { + await this.container.stop() + } +} diff --git a/apps/mass-payout/backend/test/shared/distribution.utils.ts b/apps/mass-payout/backend/test/shared/distribution.utils.ts new file mode 100644 index 000000000..bc760cc52 --- /dev/null +++ b/apps/mass-payout/backend/test/shared/distribution.utils.ts @@ -0,0 +1,315 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { + AmountType, + CorporateActionDetails, + Distribution, + DistributionStatus, + DistributionType, + PayoutDetails, + PayoutSubtype, + Recurrency, +} from "@domain/model/distribution" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { faker } from "@faker-js/faker/." +import { AssetUtils } from "@test/shared/asset.utils" + +export class DistributionUtils { + static newInstance(partial?: Partial): Distribution { + const type = partial?.details?.type ?? DistributionType.CORPORATE_ACTION + const asset = partial?.asset ?? AssetUtils.newInstance() + const status = partial?.status ?? DistributionStatus.SCHEDULED + const createdAt = partial?.createdAt ?? new Date() + const updatedAt = partial?.updatedAt ?? new Date() + + if (type === DistributionType.CORPORATE_ACTION) { + const corporateActionIDValue = + (partial?.details as CorporateActionDetails)?.corporateActionId?.value ?? faker.string.alpha({ length: 10 }) + const corporateActionID = CorporateActionId.create(corporateActionIDValue) + const executionDate = (partial?.details as any)?.executionDate ?? faker.date.future({ years: 2 }) + + if (executionDate.getTime() <= new Date().getTime()) { + return Distribution.createExistingCorporateAction( + partial?.id ?? faker.string.uuid(), + asset, + corporateActionID, + executionDate, + status, + createdAt, + updatedAt, + ) + } + + return Distribution.createCorporateAction(asset, corporateActionID, executionDate, status, createdAt, updatedAt) + } else if (type === DistributionType.PAYOUT) { + const subtype = (partial?.details as any)?.subtype ?? PayoutSubtype.IMMEDIATE + const amount = (partial?.details as PayoutDetails)?.amount ?? "10" + const amountType = (partial?.details as PayoutDetails)?.amountType ?? AmountType.FIXED + const concept = (partial?.details as PayoutDetails)?.concept ?? "test" + + if (subtype === PayoutSubtype.ONE_OFF) { + const executeAt = (partial?.details as any)?.executeAt ?? faker.date.future({ years: 1 }) + const snapshotId = (partial?.details as any)?.snapshotId ?? SnapshotId.create(faker.string.uuid()) + return Distribution.createOneOff( + asset, + executeAt, + amount, + amountType, + snapshotId, + status, + concept, + createdAt, + updatedAt, + ) + } else if (subtype === PayoutSubtype.RECURRING) { + const executeAt = (partial?.details as any)?.executeAt ?? faker.date.future({ years: 1 }) + const snapshotId = (partial?.details as any)?.snapshotId ?? SnapshotId.create(faker.string.uuid()) + if (executeAt.getTime() <= new Date().getTime()) { + return Distribution.createExistingRecurring( + partial?.id ?? faker.string.uuid(), + asset, + executeAt, + (partial?.details as any)?.recurrency ?? faker.helpers.objectValue(Recurrency), + amount, + amountType, + snapshotId, + status, + createdAt, + updatedAt, + concept, + ) + } + + return Distribution.createRecurring( + asset, + executeAt, + (partial?.details as any)?.recurrency ?? faker.helpers.objectValue(Recurrency), + amount, + amountType, + snapshotId, + status, + concept, + createdAt, + updatedAt, + ) + } else { + const snapshotId = (partial?.details as any)?.snapshotId ?? SnapshotId.create(faker.string.uuid()) + return Distribution.createImmediate( + asset, + amount, + amountType, + snapshotId, + status, + concept, + createdAt, + updatedAt, + ) + } + } + + throw new Error("Invalid distribution type provided for newInstance") + } +} diff --git a/apps/mass-payout/backend/test/shared/holder.utils.ts b/apps/mass-payout/backend/test/shared/holder.utils.ts new file mode 100644 index 000000000..5f75eaaf1 --- /dev/null +++ b/apps/mass-payout/backend/test/shared/holder.utils.ts @@ -0,0 +1,226 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { faker } from "@faker-js/faker" +import { Holder, HolderStatus } from "@domain/model/holder" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" + +const fakeHederaId = () => `${faker.number.int()}.${faker.number.int()}.${faker.number.int({ min: 1 })}` + +export class HolderUtils { + static newInstance(data?: Partial): Holder { + return Holder.create( + data?.batchPayout ?? BatchPayoutUtils.newInstance(), + data?.holderHederaAddress ?? fakeHederaId(), + data?.holderEvmAddress ?? faker.finance.ethereumAddress(), + data?.retryCounter ?? 0, + data?.status ?? HolderStatus.PENDING, + data?.nextRetryAt ?? new Date(), + data?.lastError, + data?.amount ?? null, + data?.createdAt, + data?.updatedAt, + ) + } +} diff --git a/apps/mass-payout/backend/test/shared/utils.ts b/apps/mass-payout/backend/test/shared/utils.ts new file mode 100644 index 000000000..f3ef57c4e --- /dev/null +++ b/apps/mass-payout/backend/test/shared/utils.ts @@ -0,0 +1,228 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { faker } from "@faker-js/faker" +import { LifeCycleCashFlowAddress } from "@domain/model/life-cycle-cash-flow-address.value-object" +import { AccountId, TransactionId } from "@hashgraph/sdk" + +export const fakeHederaTxId = (): string => { + const account = AccountId.fromString(`0.0.${faker.number.int({ min: 1, max: 10_000_000 })}`) + return TransactionId.generate(account).toString() +} + +export class TestConstants { + static BEFORE_ALL_TIMEOUT = 30000 + static AFTER_ALL_TIMEOUT = 30000 +} + +export const fakeHederaAddress = () => { + const a = Math.floor(Math.random() * 100) + const b = Math.floor(Math.random() * 100) + const c = Math.floor(Math.random() * 1000) + 1 + return `${a}.${b}.${c}` +} + +export const fakeLifeCycleCashFlowAddress = (): LifeCycleCashFlowAddress => { + return LifeCycleCashFlowAddress.create(fakeHederaAddress(), faker.finance.ethereumAddress()) +} diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/cancel-distribution.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/cancel-distribution.use-case.spec.ts new file mode 100644 index 000000000..8f4c3e008 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/cancel-distribution.use-case.spec.ts @@ -0,0 +1,299 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ +import { Distribution, DistributionStatus, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { + CancelDistributionCommand, + CancelDistributionUseCase, +} from "@application/use-cases/cancel-distribution.use-case" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { faker } from "@faker-js/faker" +import { + DistributionNotFoundError, + DistributionNotInStatusError, + DistributionNotPayoutError, +} from "@domain/errors/distribution.error" + +describe("CancelDistributionUseCase", () => { + let useCase: CancelDistributionUseCase + const distributionRepositoryMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + CancelDistributionUseCase, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + ], + }).compile() + + useCase = module.get(CancelDistributionUseCase) + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should cancel payout distribution", async () => { + const distribution: Distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.ONE_OFF, + } as any, + }) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + const command: CancelDistributionCommand = { + distributionId: distribution.id, + } + + await useCase.execute(command) + + expect(distributionRepositoryMock.getDistribution).toHaveBeenCalledWith(distribution.id) + expect(distributionRepositoryMock.getDistribution).toHaveBeenCalledTimes(1) + expect(distributionRepositoryMock.updateDistribution).toHaveBeenCalledWith( + expect.objectContaining({ + status: DistributionStatus.CANCELLED, + }), + ) + expect(distributionRepositoryMock.updateDistribution).toHaveBeenCalledTimes(1) + }) + + it("should throw DistributionNotFoundError when distribution does not exist", async () => { + distributionRepositoryMock.getDistribution.mockResolvedValue(undefined) + const command: CancelDistributionCommand = { + distributionId: faker.string.uuid(), + } + + await expect(useCase.execute(command)).rejects.toThrow(DistributionNotFoundError) + }) + + it("should throw DistributionNotPayoutError when distribution is not a payout", async () => { + const distribution: Distribution = DistributionUtils.newInstance() + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + const command: CancelDistributionCommand = { + distributionId: distribution.id, + } + + await expect(useCase.execute(command)).rejects.toThrow(DistributionNotPayoutError) + }) + + it("should throw DistributionNotInStatusError when distribution is not in SCHEDULED status", async () => { + const distribution: Distribution = DistributionUtils.newInstance({ + status: DistributionStatus.IN_PROGRESS, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.ONE_OFF, + } as any, + }) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + const command: CancelDistributionCommand = { + distributionId: distribution.id, + } + + await expect(useCase.execute(command)).rejects.toThrow(DistributionNotInStatusError) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/execute-payout.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/execute-payout.use-case.spec.ts new file mode 100644 index 000000000..8b2d87b19 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/execute-payout.use-case.spec.ts @@ -0,0 +1,410 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ +import { ExecutePayoutCommand, ExecutePayoutUseCase } from "@application/use-cases/execute-payout.use-case" +import { AssetNotFoundError } from "@domain/errors/asset.error" +import { Asset } from "@domain/model/asset" +import { AmountType, DistributionType, PayoutSubtype, Recurrency } from "@domain/model/distribution" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { ExecutePayoutDistributionDomainService } from "@domain/services/execute-payout-distribution.domain-service" +import { createMock } from "@golevelup/ts-jest" +import { ConfigService } from "@nestjs/config" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" + +describe("ExecutePayoutUseCase", () => { + let useCase: ExecutePayoutUseCase + const executePayoutDistributionDomainServiceMock = createMock() + const configServiceMock = createMock() + const assetRepositoryMock = createMock() + const distributionRepositoryMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ExecutePayoutUseCase, + { + provide: "AssetRepository", + useValue: assetRepositoryMock, + }, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + { + provide: ExecutePayoutDistributionDomainService, + useValue: executePayoutDistributionDomainServiceMock, + }, + { + provide: ConfigService, + useValue: configServiceMock, + }, + ], + }).compile() + + useCase = module.get(ExecutePayoutUseCase) + jest.clearAllMocks() + }) + + describe("execute", () => { + const assetId = "test-asset-id" + const command: ExecutePayoutCommand = { + assetId, + amount: "100", + amountType: AmountType.FIXED, + executeAt: new Date(Date.now() + 1000 * 60 * 60), + subtype: PayoutSubtype.IMMEDIATE, + concept: "test concept", + } + const mockAsset = { + id: assetId, + name: "Test Asset", + hederaTokenAddress: fakeHederaAddress(), + } as Asset + + it("should propagate errors from AssetRepository", async () => { + const error = new Error("Asset not found") + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockRejectedValue(error) + + await expect(useCase.execute(command)).rejects.toThrow(error) + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(executePayoutDistributionDomainServiceMock.execute).not.toHaveBeenCalled() + }) + + it("should propagate errors from ExecutePayoutDomainService", async () => { + const error = new Error("Domain service error") + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockResolvedValue(mockAsset) + executePayoutDistributionDomainServiceMock.execute.mockRejectedValue(error) + + await expect(useCase.execute(command)).rejects.toThrow(error) + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(executePayoutDistributionDomainServiceMock.execute).toHaveBeenCalledWith(expect.any(Object)) + }) + + it("should call services in correct order", async () => { + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockResolvedValue(mockAsset) + executePayoutDistributionDomainServiceMock.execute.mockResolvedValue(undefined) + + await useCase.execute(command) + + const assetCall = assetRepositoryMock.getAsset.mock.invocationCallOrder[0] + const domainServiceCall = executePayoutDistributionDomainServiceMock.execute.mock.invocationCallOrder[0] + expect(assetCall).toBeLessThan(domainServiceCall) + }) + + it("should return undefined on successful execution", async () => { + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockResolvedValue(mockAsset) + executePayoutDistributionDomainServiceMock.execute.mockResolvedValue(undefined) + + const result = await useCase.execute(command) + + expect(result).toBeUndefined() + }) + + it("should call executePayoutDomainService with correct parameters for immediate payout", async () => { + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockResolvedValue(mockAsset) + executePayoutDistributionDomainServiceMock.execute.mockResolvedValue(undefined) + + await useCase.execute(command) + + expect(executePayoutDistributionDomainServiceMock.execute).toHaveBeenCalledWith( + expect.objectContaining({ + asset: mockAsset, + }), + ) + + expect(executePayoutDistributionDomainServiceMock.execute).toHaveBeenCalledTimes(1) + }) + + it("should call distributionRepository with correct parameters for one-off payout", async () => { + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockResolvedValue(mockAsset) + distributionRepositoryMock.saveDistribution.mockResolvedValue(undefined) + command.subtype = PayoutSubtype.ONE_OFF + + await useCase.execute(command) + + expect(distributionRepositoryMock.saveDistribution).toHaveBeenCalledWith( + expect.objectContaining({ + asset: mockAsset, + details: { + executeAt: command.executeAt, + amount: command.amount, + amountType: command.amountType, + type: DistributionType.PAYOUT, + subtype: command.subtype, + concept: command.concept, + }, + }), + ) + + expect(distributionRepositoryMock.saveDistribution).toHaveBeenCalledTimes(1) + }) + + it("should call distributionRepository with correct parameters for recurring payout", async () => { + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockResolvedValue(mockAsset) + distributionRepositoryMock.saveDistribution.mockResolvedValue(undefined) + command.subtype = PayoutSubtype.RECURRING + command.recurrency = Recurrency.DAILY + + await useCase.execute(command) + + expect(distributionRepositoryMock.saveDistribution).toHaveBeenCalledWith( + expect.objectContaining({ + asset: mockAsset, + details: { + executeAt: command.executeAt, + recurrency: command.recurrency, + amount: command.amount, + amountType: command.amountType, + type: DistributionType.PAYOUT, + subtype: command.subtype, + concept: command.concept, + }, + }), + ) + + expect(distributionRepositoryMock.saveDistribution).toHaveBeenCalledTimes(1) + }) + + it("should call distributionRepository with correct parameters for automated payout", async () => { + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockResolvedValue(mockAsset) + distributionRepositoryMock.saveDistribution.mockResolvedValue(undefined) + command.subtype = PayoutSubtype.AUTOMATED + + await useCase.execute(command) + + expect(distributionRepositoryMock.saveDistribution).toHaveBeenCalledWith( + expect.objectContaining({ + asset: mockAsset, + details: { + amount: command.amount, + amountType: command.amountType, + type: DistributionType.PAYOUT, + subtype: command.subtype, + concept: command.concept, + }, + }), + ) + + expect(distributionRepositoryMock.saveDistribution).toHaveBeenCalledTimes(1) + }) + + it("should throw AssetNotFoundError when asset is not found", async () => { + configServiceMock.get.mockReturnValue(100) + assetRepositoryMock.getAsset.mockResolvedValue(null) + + await expect(useCase.execute(command)).rejects.toThrow(AssetNotFoundError) + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(executePayoutDistributionDomainServiceMock.execute).not.toHaveBeenCalled() + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-asset-distributions.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-asset-distributions.use-case.spec.ts new file mode 100644 index 000000000..7af270a7a --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-asset-distributions.use-case.spec.ts @@ -0,0 +1,330 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetAssetDistributionsUseCase } from "@application/use-cases/get-asset-distributions.use-case" +import { Distribution } from "@domain/model/distribution" +import { OrderPageOptions, Page, PageOptions } from "@domain/model/page" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { DistributionUtils } from "@test/shared/distribution.utils" + +describe(GetAssetDistributionsUseCase.name, () => { + let getAssetDistributionsUseCase: GetAssetDistributionsUseCase + const distributionRepositoryMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + GetAssetDistributionsUseCase, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + ], + }).compile() + + getAssetDistributionsUseCase = module.get(GetAssetDistributionsUseCase) + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should return paginated distributions when distributions exist", async () => { + // Given + const assetId = faker.string.uuid() + const distribution1 = DistributionUtils.newInstance() + const distribution2 = DistributionUtils.newInstance() + + const expectedPage: Page = { + items: [distribution1, distribution2], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + + distributionRepositoryMock.getDistributionsByAssetId.mockResolvedValue(expectedPage) + + // When + const result = await getAssetDistributionsUseCase.execute(assetId, PageOptions.DEFAULT) + + // Then + expect(distributionRepositoryMock.getDistributionsByAssetId).toHaveBeenCalledWith(assetId, PageOptions.DEFAULT) + expect(result).toEqual(expectedPage) + expect(result.items).toHaveLength(2) + }) + + it("should return empty page when no distributions exist", async () => { + // Given + const assetId = faker.string.uuid() + const emptyPage: Page = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + + distributionRepositoryMock.getDistributionsByAssetId.mockResolvedValue(emptyPage) + + // When + const result = await getAssetDistributionsUseCase.execute(assetId) + + // Then + expect(distributionRepositoryMock.getDistributionsByAssetId).toHaveBeenCalledWith(assetId, PageOptions.DEFAULT) + expect(result).toEqual(emptyPage) + expect(result.items).toHaveLength(0) + }) + + it("should use custom pagination options when provided", async () => { + // Given + const assetId = faker.string.uuid() + const customPageOptions = { page: 2, limit: 5, order: OrderPageOptions.DEFAULT } + const distribution = DistributionUtils.newInstance() + + const expectedPage: Page = { + items: [distribution], + total: 1, + page: 2, + limit: 5, + totalPages: 1, + } + + distributionRepositoryMock.getDistributionsByAssetId.mockResolvedValue(expectedPage) + + // When + const result = await getAssetDistributionsUseCase.execute(assetId, customPageOptions) + + // Then + expect(distributionRepositoryMock.getDistributionsByAssetId).toHaveBeenCalledWith(assetId, customPageOptions) + expect(result).toEqual(expectedPage) + expect(result.page).toBe(2) + expect(result.limit).toBe(5) + }) + + it("should use default pagination when no options provided", async () => { + // Given + const assetId = faker.string.uuid() + const defaultPage: Page = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + + distributionRepositoryMock.getDistributionsByAssetId.mockResolvedValue(defaultPage) + + // When + const result = await getAssetDistributionsUseCase.execute(assetId) + + // Then + expect(distributionRepositoryMock.getDistributionsByAssetId).toHaveBeenCalledWith(assetId, PageOptions.DEFAULT) + expect(result).toEqual(defaultPage) + expect(result.page).toBe(1) + expect(result.limit).toBe(10) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-asset.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-asset.use-case.spec.ts new file mode 100644 index 000000000..42cb9e3d8 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-asset.use-case.spec.ts @@ -0,0 +1,277 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetAssetUseCase } from "@application/use-cases/get-asset.use-case" +import { AssetNotFoundError } from "@domain/errors/asset.error" +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" + +describe(GetAssetUseCase.name, () => { + let getAssetUseCase: GetAssetUseCase + const assetRepositoryMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + GetAssetUseCase, + { + provide: "AssetRepository", + useValue: assetRepositoryMock, + }, + ], + }).compile() + + getAssetUseCase = module.get(GetAssetUseCase) + + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should return asset when found", async () => { + const id = faker.string.uuid() + const name = faker.commerce.productName() + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const expectedAsset = new Asset( + id, + name, + AssetType.EQUITY, + hederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + undefined, + undefined, + false, + true, + new Date(), + new Date(), + ) + + assetRepositoryMock.getAsset.mockResolvedValue(expectedAsset) + + const result = await getAssetUseCase.execute(id) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(id) + expect(result).toBe(expectedAsset) + }) + + it("should throw AssetNotFoundError when asset is not found", async () => { + const id = faker.string.uuid() + + assetRepositoryMock.getAsset.mockResolvedValue(null) + + await expect(getAssetUseCase.execute(id)).rejects.toThrow(new AssetNotFoundError(id)) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(id) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-assets.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-assets.use-case.spec.ts new file mode 100644 index 000000000..013a5ad05 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-assets.use-case.spec.ts @@ -0,0 +1,360 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetAssetsUseCase } from "@application/use-cases/get-assets.use-case" +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { OrderPageOptions, Page, PageOptions } from "@domain/model/page" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" + +describe(GetAssetsUseCase.name, () => { + let getAssetsUseCase: GetAssetsUseCase + const assetRepositoryMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + GetAssetsUseCase, + { + provide: "AssetRepository", + useValue: assetRepositoryMock, + }, + ], + }).compile() + + getAssetsUseCase = module.get(GetAssetsUseCase) + + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should return paginated assets when assets exist", async () => { + const symbol1 = faker.string.alpha({ length: 3 }) + const asset1 = new Asset( + faker.string.uuid(), + faker.commerce.productName(), + AssetType.EQUITY, + fakeHederaAddress(), + faker.finance.ethereumAddress(), + symbol1, + undefined, + undefined, + undefined, + false, + true, + new Date(), + new Date(), + ) + + const symbol2 = faker.string.alpha({ length: 3 }) + const asset2 = new Asset( + faker.string.uuid(), + faker.commerce.productName(), + AssetType.EQUITY, + fakeHederaAddress(), + faker.finance.ethereumAddress(), + symbol2, + undefined, + undefined, + undefined, + true, + true, + new Date(), + new Date(), + ) + + const expectedPage: Page = { + items: [asset1, asset2], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + + assetRepositoryMock.getAssets.mockResolvedValue(expectedPage) + + const result = await getAssetsUseCase.execute(PageOptions.DEFAULT) + + expect(assetRepositoryMock.getAssets).toHaveBeenCalledWith(PageOptions.DEFAULT) + expect(result).toEqual(expectedPage) + expect(result.items).toHaveLength(2) + expect(result.total).toBe(2) + expect(result.totalPages).toBe(1) + }) + + it("should return empty page when no assets exist", async () => { + const emptyPage: Page = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + + assetRepositoryMock.getAssets.mockResolvedValue(emptyPage) + + const result = await getAssetsUseCase.execute(PageOptions.DEFAULT) + + expect(assetRepositoryMock.getAssets).toHaveBeenCalledWith(PageOptions.DEFAULT) + expect(result).toEqual(emptyPage) + expect(result.items).toHaveLength(0) + expect(result.total).toBe(0) + expect(result.totalPages).toBe(0) + }) + + it("should use default pagination when no options provided", async () => { + // Given + const defaultPage: Page = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + assetRepositoryMock.getAssets.mockResolvedValue(defaultPage) + + // When + const result = await getAssetsUseCase.execute() + + // Then + expect(assetRepositoryMock.getAssets).toHaveBeenCalledWith({ + page: 1, + limit: 10, + order: OrderPageOptions.DEFAULT, + }) + expect(result).toEqual(defaultPage) + expect(result.page).toBe(1) + expect(result.limit).toBe(10) + }) + + it("should use custom pagination options when provided", async () => { + const customPage: Page = { + items: [], + total: 0, + page: 2, + limit: 5, + totalPages: 0, + } + + assetRepositoryMock.getAssets.mockResolvedValue(customPage) + + const result = await getAssetsUseCase.execute({ + page: 2, + limit: 5, + order: OrderPageOptions.DEFAULT, + }) + + expect(assetRepositoryMock.getAssets).toHaveBeenCalledWith({ + page: 2, + limit: 5, + order: OrderPageOptions.DEFAULT, + }) + expect(result).toEqual(customPage) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-basic-asset-information.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-basic-asset-information.use-case.spec.ts new file mode 100644 index 000000000..eeb838da7 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-basic-asset-information.use-case.spec.ts @@ -0,0 +1,336 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Test, TestingModule } from "@nestjs/testing" +import { GetBasicAssetInformationUseCase } from "@application/use-cases/get-basic-asset-information.use-case" +import { AssetType } from "@domain/model/asset-type.enum" +import { createMock } from "@golevelup/ts-jest" +import { faker } from "@faker-js/faker" +import { fakeHederaAddress } from "@test/shared/utils" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" + +describe(GetBasicAssetInformationUseCase.name, () => { + let getBasicAssetInformationUseCase: GetBasicAssetInformationUseCase + const assetTokenizationStudioServiceMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + GetBasicAssetInformationUseCase, + { + provide: "AssetTokenizationStudioService", + useValue: assetTokenizationStudioServiceMock, + }, + ], + }).compile() + + getBasicAssetInformationUseCase = module.get(GetBasicAssetInformationUseCase) + }) + + afterEach(async () => { + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should return basic asset information without maturity date for equity", async () => { + const hederaTokenAddress = fakeHederaAddress() + const name = faker.finance.accountName() + const symbol = faker.finance.currencyCode() + + const mockAssetInfo = { + hederaTokenAddress, + name, + symbol, + assetType: AssetType.EQUITY, + } + assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(mockAssetInfo) + + const result = await getBasicAssetInformationUseCase.execute(hederaTokenAddress) + + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalledWith(hederaTokenAddress) + expect(result).toEqual({ + hederaTokenAddress, + name, + symbol, + assetType: AssetType.EQUITY, + maturityDate: undefined, + }) + }) + + it("should return basic asset information with maturity date for bond", async () => { + const hederaTokenAddress = fakeHederaAddress() + const name = faker.finance.accountName() + const symbol = faker.finance.currencyCode() + const maturityDate = faker.date.future() + + const mockAssetInfo = { + hederaTokenAddress, + name, + symbol, + assetType: AssetType.BOND, + maturityDate, + } + assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(mockAssetInfo) + + const result = await getBasicAssetInformationUseCase.execute(hederaTokenAddress) + + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalledWith(hederaTokenAddress) + expect(result).toEqual({ + hederaTokenAddress, + name, + symbol, + assetType: AssetType.BOND, + maturityDate, + }) + }) + + it("should throw error when repository fails", async () => { + const hederaTokenAddress = fakeHederaAddress() + const errorMessage = "Failed to get asset info from blockchain" + assetTokenizationStudioServiceMock.getAssetInfo.mockRejectedValue(new Error(errorMessage)) + + await expect(getBasicAssetInformationUseCase.execute(hederaTokenAddress)).rejects.toThrow(errorMessage) + + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalledWith(hederaTokenAddress) + }) + + it("should propagate asset not found error from repository", async () => { + const hederaTokenAddress = fakeHederaAddress() + const notFoundError = new Error("Asset not found on blockchain") + assetTokenizationStudioServiceMock.getAssetInfo.mockRejectedValue(notFoundError) + + await expect(getBasicAssetInformationUseCase.execute(hederaTokenAddress)).rejects.toThrow(notFoundError) + + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalledWith(hederaTokenAddress) + }) + + it("should handle all asset types correctly", async () => { + const hederaTokenAddress = fakeHederaAddress() + const name = faker.finance.accountName() + const symbol = faker.finance.currencyCode() + const assetTypes = [AssetType.EQUITY, AssetType.BOND] + + for (const assetType of assetTypes) { + const mockAssetInfo = { + hederaTokenAddress, + name, + symbol, + assetType, + maturityDate: assetType === AssetType.BOND ? faker.date.future() : undefined, + } + assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(mockAssetInfo) + + const result = await getBasicAssetInformationUseCase.execute(hederaTokenAddress) + + expect(result.assetType).toBe(assetType) + expect(result.hederaTokenAddress).toBe(hederaTokenAddress) + expect(result.name).toBe(name) + expect(result.symbol).toBe(symbol) + if (assetType === AssetType.BOND) { + expect(result.maturityDate).toBeDefined() + } + } + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-blockchain-event-listener-config.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-blockchain-event-listener-config.use-case.spec.ts new file mode 100644 index 000000000..1830be07f --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-blockchain-event-listener-config.use-case.spec.ts @@ -0,0 +1,301 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetBlockchainEventListenerConfigUseCase } from "@application/use-cases/get-blockchain-event-listener-config.use-case" +import { ConfigKeys } from "@config/config-keys" +import { BlockchainEventListenerConfig } from "@domain/model/blockchain-listener" +import { BlockchainEventListenerConfigRepository } from "@domain/ports/blockchain-event-config-repository.port" +import { createMock } from "@golevelup/ts-jest" +import { ConfigService } from "@nestjs/config" +import { Test, TestingModule } from "@nestjs/testing" + +describe(GetBlockchainEventListenerConfigUseCase.name, () => { + let useCase: GetBlockchainEventListenerConfigUseCase + const repositoryMock = createMock() + const configServiceMock = createMock() + const envConfigMock = { + id: crypto.randomUUID(), + mirrorNodeUrl: "http://localhost:5551", + contractId: "0.0.004", + startTimestamp: "2025-08-26T00:00:00.000Z", + tokenDecimals: 6, + } + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + GetBlockchainEventListenerConfigUseCase, + { + provide: "BlockchainEventListenerConfigRepository", + useValue: repositoryMock, + }, + { + provide: ConfigService, + useValue: configServiceMock, + }, + ], + }).compile() + + useCase = module.get(GetBlockchainEventListenerConfigUseCase) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should return the blockchain event listener config", async () => { + configServiceMock.get.mockImplementation((key: string) => { + const values: Record = { + [ConfigKeys.BLOCKCHAIN_MIRROR_NODE_URL]: envConfigMock.mirrorNodeUrl, + [ConfigKeys.BLOCKCHAIN_CONTRACT_ID]: envConfigMock.contractId, + [ConfigKeys.BLOCKCHAIN_LISTENER_START_TIMESTAMP]: envConfigMock.startTimestamp, + [ConfigKeys.BLOCKCHAIN_TOKEN_DECIMALS]: envConfigMock.tokenDecimals, + } + return values[key] + }) + const mockConfig: BlockchainEventListenerConfig = new BlockchainEventListenerConfig() + mockConfig.id = crypto.randomUUID() + mockConfig.mirrorNodeUrl = "0x123" + mockConfig.contractId = "0x456" + mockConfig.startTimestamp = "1651356000000" + mockConfig.tokenDecimals = 2 + repositoryMock.getConfig.mockResolvedValue(mockConfig) + + const result = await useCase.execute() + + expect(repositoryMock.getConfig).toHaveBeenCalled() + expect(result).toEqual(mockConfig) + }) + + it("should return default config if config not found", async () => { + repositoryMock.getConfig.mockResolvedValue(undefined) + configServiceMock.get.mockImplementation((key: string) => { + const values: Record = { + [ConfigKeys.BLOCKCHAIN_MIRROR_NODE_URL]: envConfigMock.mirrorNodeUrl, + [ConfigKeys.BLOCKCHAIN_CONTRACT_ID]: envConfigMock.contractId, + [ConfigKeys.BLOCKCHAIN_LISTENER_START_TIMESTAMP]: envConfigMock.startTimestamp, + [ConfigKeys.BLOCKCHAIN_TOKEN_DECIMALS]: envConfigMock.tokenDecimals, + } + return values[key] + }) + + await expect(useCase.execute()).resolves.toEqual({ + mirrorNodeUrl: expect.any(String), + contractId: expect.any(String), + startTimestamp: expect.any(String), + tokenDecimals: expect.any(Number), + }) + expect(repositoryMock.getConfig).toHaveBeenCalled() + }) + + it("should propagate repository errors", async () => { + const error = new Error("DB error") + repositoryMock.getConfig.mockRejectedValue(error) + + await expect(useCase.execute()).rejects.toThrow(error) + expect(repositoryMock.getConfig).toHaveBeenCalled() + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution-holder-count.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution-holder-count.use-case.spec.ts new file mode 100644 index 000000000..c059093d1 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution-holder-count.use-case.spec.ts @@ -0,0 +1,266 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetDistributionHoldersUseCase } from "@application/use-cases/get-distribution-holders.use-case" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { GetDistributionHolderCountUseCase } from "@application/use-cases/get-distribution-holder-count.use-case" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { DistributionNotFoundError } from "@domain/errors/distribution.error" + +describe(GetDistributionHoldersUseCase.name, () => { + let getDistributionHolderCountUseCase: GetDistributionHolderCountUseCase + const holderRepositoryMock = createMock() + const distributionRepositoryMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: GetDistributionHolderCountUseCase, + useFactory: (distributionRepository: DistributionRepository, holderRepository: HolderRepository) => { + return new GetDistributionHolderCountUseCase(distributionRepository, holderRepository) + }, + inject: ["DistributionRepository", "HolderRepository"], + }, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + { + provide: "HolderRepository", + useValue: holderRepositoryMock, + }, + ], + }).compile() + + getDistributionHolderCountUseCase = module.get(GetDistributionHolderCountUseCase) + + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should return holder count", async () => { + const distribution = DistributionUtils.newInstance() + const expectedCount = 2 + + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + holderRepositoryMock.countHoldersByDistributionId.mockResolvedValue(expectedCount) + + const result = await getDistributionHolderCountUseCase.execute(distribution.id) + + expect(result).toEqual(expectedCount) + }) + + it("should throw DistributionNotFoundError when distribution does not exist", async () => { + distributionRepositoryMock.getDistribution.mockResolvedValue(null) + + const result = await await expect( + getDistributionHolderCountUseCase.execute("testDistributionId"), + ).rejects.toThrow(DistributionNotFoundError) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution-holders.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution-holders.use-case.spec.ts new file mode 100644 index 000000000..491297a93 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution-holders.use-case.spec.ts @@ -0,0 +1,357 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetDistributionHoldersUseCase } from "@application/use-cases/get-distribution-holders.use-case" +import { GetDistributionUseCase } from "@application/use-cases/get-distribution.use-case" +import { BatchPayout, BatchPayoutStatus } from "@domain/model/batch-payout" +import { Holder, HolderStatus } from "@domain/model/holder" +import { Page, PageOptions } from "@domain/model/page" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { faker } from "@faker-js/faker/." +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { fakeHederaTxId } from "@test/shared/utils" + +describe(GetDistributionHoldersUseCase.name, () => { + let getDistributionHoldersUseCase: GetDistributionHoldersUseCase + const holderRepositoryMock = createMock() + const getDistributionUseCaseMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: GetDistributionHoldersUseCase, + useFactory: (getDistributionUseCase: GetDistributionUseCase, holderRepository: HolderRepository) => { + return new GetDistributionHoldersUseCase(getDistributionUseCase, holderRepository) + }, + inject: ["GetDistributionUseCase", "HolderRepository"], + }, + { + provide: "HolderRepository", + useValue: holderRepositoryMock, + }, + { + provide: "GetDistributionUseCase", + useValue: getDistributionUseCaseMock, + }, + ], + }).compile() + + getDistributionHoldersUseCase = module.get(GetDistributionHoldersUseCase) + + jest.clearAllMocks() + }) + + describe("execute", () => { + const distributionId = "distribution-123" + + const mockHolder = (overrides?: Partial): Holder => { + const hederaTxId = fakeHederaTxId() + + const mockBatchPayout = BatchPayout.create( + DistributionUtils.newInstance(), + faker.string.alpha({ length: 10 }), + hederaTxId, + `0x${faker.string.hexadecimal({ length: 96, prefix: "" })}`, + 2, + BatchPayoutStatus.FAILED, + ) + + const hederaAccountId = `0.0.${Math.floor(Math.random() * 1000)}` + + const holder = Holder.create( + mockBatchPayout, + hederaAccountId, + faker.finance.ethereumAddress(), + 2, + HolderStatus.FAILED, + new Date(Date.now() + 3600000), + "Some error occurred", + faker.number.int({ min: 1, max: 1000 }).toString(), + new Date(), + new Date(), + ) + + if (overrides) { + Object.assign(holder, overrides) + } + + return holder + } + + it("should return paginated failed holders when they exist", async () => { + const holder1 = mockHolder({ id: "fh-1" }) + const holder2 = mockHolder({ id: "fh-2" }) + + const pageOptions: PageOptions = { + page: 1, + limit: 10, + order: { order: "DESC", orderBy: "createdAt" }, + } + + const expectedPage: Page = { + items: [holder1, holder2], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + + holderRepositoryMock.getHoldersByDistributionId.mockResolvedValue(expectedPage) + + const result = await getDistributionHoldersUseCase.execute(distributionId, pageOptions) + + expect(result).toEqual(expectedPage) + expect(holderRepositoryMock.getHoldersByDistributionId).toHaveBeenCalledWith(distributionId, pageOptions) + }) + + it("should return empty page when no failed holders exist", async () => { + const pageOptions: PageOptions = { + page: 1, + limit: 10, + order: { order: "DESC", orderBy: "createdAt" }, + } + + const expectedPage: Page = { + items: [], + total: 0, + page: 1, + limit: 10, + totalPages: 0, + } + + holderRepositoryMock.getHoldersByDistributionId.mockResolvedValue(expectedPage) + + const result = await getDistributionHoldersUseCase.execute(distributionId, pageOptions) + + expect(result).toEqual(expectedPage) + expect(holderRepositoryMock.getHoldersByDistributionId).toHaveBeenCalledWith(distributionId, pageOptions) + }) + + it("should handle different page options", async () => { + const pageOptions: PageOptions = { + page: 2, + limit: 5, + order: { order: "ASC", orderBy: "status" }, + } + + const expectedPage: Page = { + items: [], + total: 0, + page: 2, + limit: 5, + totalPages: 0, + } + + holderRepositoryMock.getHoldersByDistributionId.mockResolvedValue(expectedPage) + + const result = await getDistributionHoldersUseCase.execute(distributionId, pageOptions) + + expect(result).toEqual(expectedPage) + expect(holderRepositoryMock.getHoldersByDistributionId).toHaveBeenCalledWith(distributionId, pageOptions) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution.use-case.spec.ts new file mode 100644 index 000000000..cc8598ed1 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-distribution.use-case.spec.ts @@ -0,0 +1,272 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { GetDistributionUseCase } from "@application/use-cases/get-distribution.use-case" +import { DistributionNotFoundError } from "@domain/errors/distribution.error" +import { AssetUtils } from "@test/shared/asset.utils" + +describe(GetDistributionUseCase.name, () => { + let getDistributionUseCase: GetDistributionUseCase + const distributionRepositoryMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: GetDistributionUseCase, + useFactory: (distributionRepository: DistributionRepository) => { + return new GetDistributionUseCase(distributionRepository) + }, + inject: ["DistributionRepository"], + }, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + ], + }).compile() + + getDistributionUseCase = module.get(GetDistributionUseCase) + }) + + afterEach(async () => { + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should return distribution when found", async () => { + const asset = AssetUtils.newInstance() + const distribution = DistributionUtils.newInstance({ asset }) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + + const result = await getDistributionUseCase.execute(distribution.id) + + expect(result).toBe(distribution) + expect(distributionRepositoryMock.getDistribution).toHaveBeenCalledWith(distribution.id) + }) + + it("should throw DistributionNotFoundError when distribution is not found", async () => { + const distributionId = "non-existent-id" + distributionRepositoryMock.getDistribution.mockResolvedValue(null) + + await expect(getDistributionUseCase.execute(distributionId)).rejects.toThrow( + new DistributionNotFoundError(distributionId), + ) + expect(distributionRepositoryMock.getDistribution).toHaveBeenCalledWith(distributionId) + }) + + it("should propagate repository errors", async () => { + const distributionId = "some-id" + const repositoryError = new Error("Repository error") + distributionRepositoryMock.getDistribution.mockRejectedValue(repositoryError) + + await expect(getDistributionUseCase.execute(distributionId)).rejects.toThrow(repositoryError) + expect(distributionRepositoryMock.getDistribution).toHaveBeenCalledWith(distributionId) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/get-distributions.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/get-distributions.use-case.spec.ts new file mode 100644 index 000000000..48a3f841a --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/get-distributions.use-case.spec.ts @@ -0,0 +1,291 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { GetDistributionsUseCase } from "@application/use-cases/get-distributions.use-case" +import { Distribution } from "@domain/model/distribution" +import { DistributionStatus } from "@domain/model/distribution" +import { Page } from "@domain/model/page" +import { PageOptions } from "@domain/model/page" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" + +describe(GetDistributionsUseCase.name, () => { + let getDistributionsUseCase: GetDistributionsUseCase + const distributionRepositoryMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + { + provide: GetDistributionsUseCase, + useFactory: (distributionRepository: DistributionRepository) => { + return new GetDistributionsUseCase(distributionRepository) + }, + inject: ["DistributionRepository"], + }, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + ], + }).compile() + + getDistributionsUseCase = module.get(GetDistributionsUseCase) + + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should return paginated distributions when distributions exist", async () => { + const distribution1 = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + }) + const distribution2 = DistributionUtils.newInstance({ + status: DistributionStatus.COMPLETED, + }) + + const pageOptions: PageOptions = { page: 1, limit: 10, order: { order: "DESC", orderBy: "createdAt" } } + const expectedPage: Page = { + items: [distribution1, distribution2], + total: 2, + page: 1, + limit: 10, + totalPages: 1, + } + + distributionRepositoryMock.getDistributions.mockResolvedValue(expectedPage) + + const result = await getDistributionsUseCase.execute(pageOptions) + + expect(result).toEqual(expectedPage) + expect(distributionRepositoryMock.getDistributions).toHaveBeenCalledWith(pageOptions) + }) + + it("should return empty page when no distributions exist", async () => { + const pageOptions: PageOptions = { page: 1, limit: 10, order: { order: "DESC", orderBy: "createdAt" } } + const expectedPage: Page = { items: [], total: 0, page: 1, limit: 10, totalPages: 0 } + + distributionRepositoryMock.getDistributions.mockResolvedValue(expectedPage) + + const result = await getDistributionsUseCase.execute(pageOptions) + + expect(result).toEqual(expectedPage) + expect(distributionRepositoryMock.getDistributions).toHaveBeenCalledWith(pageOptions) + }) + + it("should forward different page options to repository", async () => { + const pageOptions: PageOptions = { page: 2, limit: 5, order: { order: "ASC", orderBy: "executionDate" } } + const expectedPage: Page = { items: [], total: 0, page: 2, limit: 5, totalPages: 0 } + + distributionRepositoryMock.getDistributions.mockResolvedValue(expectedPage) + + const result = await getDistributionsUseCase.execute(pageOptions) + + expect(result).toEqual(expectedPage) + expect(distributionRepositoryMock.getDistributions).toHaveBeenCalledWith(pageOptions) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/import-asset.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/import-asset.use-case.spec.ts new file mode 100644 index 000000000..c1165447a --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/import-asset.use-case.spec.ts @@ -0,0 +1,346 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ImportAssetUseCase } from "@application/use-cases/import-asset.use-case" +import { + AssetEvmTokenAddressInvalidError, + AssetHederaTokenAddressInvalidError, + AssetLifeCycleCashFlowEvmAddressInvalidError, + AssetLifeCycleCashFlowHederaAddressInvalidError, + AssetNameMissingError, +} from "@domain/errors/asset.error" +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { ImportAssetDomainService } from "@domain/services/import-asset.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress, fakeLifeCycleCashFlowAddress } from "@test/shared/utils" + +describe(ImportAssetUseCase.name, () => { + let importAssetUseCase: ImportAssetUseCase + const importAssetDomainServiceMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ImportAssetUseCase, + { + provide: ImportAssetDomainService, + useValue: importAssetDomainServiceMock, + }, + ], + }).compile() + + importAssetUseCase = module.get(ImportAssetUseCase) + }) + + describe("execute", () => { + it("should call domain service with correct parameters and return the result", async () => { + const name = faker.commerce.productName() + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const lifeCycleCashFlowAddress = fakeLifeCycleCashFlowAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const expectedAsset = new Asset( + faker.string.uuid(), + name, + AssetType.EQUITY, + hederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + lifeCycleCashFlowAddress.hederaAddress, + lifeCycleCashFlowAddress.evmAddress, + false, + true, + new Date(), + new Date(), + ) + + importAssetDomainServiceMock.importAsset.mockResolvedValue(expectedAsset) + + const result = await importAssetUseCase.execute(hederaTokenAddress) + + expect(importAssetDomainServiceMock.importAsset).toHaveBeenCalledWith(hederaTokenAddress) + expect(result).toBe(expectedAsset) + }) + + it("should throw error when name is empty", async () => { + try { + const symbol = faker.string.alpha({ length: 3 }) + Asset.create(undefined, AssetType.EQUITY, fakeHederaAddress(), faker.finance.ethereumAddress(), symbol) + } catch (error) { + expect(error).toBeInstanceOf(AssetNameMissingError) + } + }) + + it("should throw error when hederaTokenAddress is not in format 0.0.X", async () => { + try { + const symbol = faker.string.alpha({ length: 3 }) + Asset.create( + faker.commerce.productName(), + AssetType.EQUITY, + fakeHederaAddress(), + faker.finance.ethereumAddress(), + symbol, + ) + } catch (error) { + expect(error).toBeInstanceOf(AssetHederaTokenAddressInvalidError) + } + }) + + it("should throw error when evmTokenAddress is not a valid Ethereum address", async () => { + try { + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = faker.date.future() + Asset.create( + faker.commerce.productName(), + AssetType.BOND, + fakeHederaAddress(), + faker.finance.ethereumAddress(), + symbol, + maturityDate, + ) + } catch (error) { + expect(error).toBeInstanceOf(AssetEvmTokenAddressInvalidError) + } + }) + + it("should throw error when lifeCycleCashFlowHederaAddress is not in format 0.0.X", async () => { + try { + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = faker.date.future() + Asset.create( + faker.commerce.productName(), + AssetType.BOND, + fakeHederaAddress(), + faker.finance.ethereumAddress(), + symbol, + maturityDate, + ) + } catch (error) { + expect(error).toBeInstanceOf(AssetLifeCycleCashFlowHederaAddressInvalidError) + } + }) + + it("should throw error when lifeCycleCashFlowEvmAddress is not a valid Ethereum address", async () => { + try { + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = faker.date.future() + Asset.create( + faker.commerce.productName(), + AssetType.BOND, + fakeHederaAddress(), + faker.finance.ethereumAddress(), + symbol, + maturityDate, + ) + } catch (error) { + expect(error).toBeInstanceOf(AssetLifeCycleCashFlowEvmAddressInvalidError) + } + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/pause-asset.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/pause-asset.use-case.spec.ts new file mode 100644 index 000000000..2a9b434b9 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/pause-asset.use-case.spec.ts @@ -0,0 +1,266 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { PauseAssetUseCase } from "@application/use-cases/pause-asset.use-case" +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { PauseAssetDomainService } from "@domain/services/pause-asset.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" + +describe(PauseAssetUseCase.name, () => { + let pauseAssetUseCase: PauseAssetUseCase + const pauseAssetDomainServiceMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + PauseAssetUseCase, + { + provide: PauseAssetDomainService, + useValue: pauseAssetDomainServiceMock, + }, + ], + }).compile() + + pauseAssetUseCase = module.get(PauseAssetUseCase) + + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should call domain service with correct parameters and return the result", async () => { + const id = faker.string.uuid() + const name = faker.commerce.productName() + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const expectedAsset = new Asset( + id, + name, + AssetType.EQUITY, + hederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + undefined, + undefined, + true, + true, + new Date(), + new Date(), + ) + + pauseAssetDomainServiceMock.pause.mockResolvedValue(expectedAsset) + + const result = await pauseAssetUseCase.execute(id) + + expect(pauseAssetDomainServiceMock.pause).toHaveBeenCalledWith(id) + expect(result).toBe(expectedAsset) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/process-scheduled-payouts.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/process-scheduled-payouts.use-case.spec.ts new file mode 100644 index 000000000..a9723ac11 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/process-scheduled-payouts.use-case.spec.ts @@ -0,0 +1,425 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ProcessScheduledPayoutsUseCase } from "@application/use-cases/process-scheduled-payouts.use-case" +import { AmountType, DistributionStatus, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { ExecuteCorporateActionDistributionDomainService } from "@domain/services/execute-corporate-action-distribution.domain-service" +import { ExecutePayoutDistributionDomainService } from "@domain/services/execute-payout-distribution.domain-service" +import { SyncFromOnChainDomainService } from "@domain/services/sync-from-onchain.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { ConfigService } from "@nestjs/config" +import { Test, TestingModule } from "@nestjs/testing" +import { DistributionUtils } from "@test/shared/distribution.utils" + +describe(ProcessScheduledPayoutsUseCase.name, () => { + let processScheduledPayoutsUseCase: ProcessScheduledPayoutsUseCase + const distributionRepositoryMock = createMock() + const syncFromOnChainDomainServiceMock = createMock() + const executeCorporateActionDistributionDomainServiceMock = + createMock() + const executePayoutDistributionDomainServiceMock = createMock() + const configServiceMock = createMock() + const DEFAULT_BATCH_SIZE = 100 + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ProcessScheduledPayoutsUseCase, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + { + provide: SyncFromOnChainDomainService, + useValue: syncFromOnChainDomainServiceMock, + }, + { + provide: ExecuteCorporateActionDistributionDomainService, + useValue: executeCorporateActionDistributionDomainServiceMock, + }, + { + provide: ExecutePayoutDistributionDomainService, + useValue: executePayoutDistributionDomainServiceMock, + }, + { + provide: ConfigService, + useValue: configServiceMock, + }, + ], + }).compile() + + processScheduledPayoutsUseCase = module.get(ProcessScheduledPayoutsUseCase) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should sync from on-chain, find scheduled distributions for today and process them", async () => { + const distribution1 = DistributionUtils.newInstance({ status: DistributionStatus.SCHEDULED }) + const distribution2 = DistributionUtils.newInstance({ status: DistributionStatus.SCHEDULED }) + const scheduledDistributions = [distribution1, distribution2] + distributionRepositoryMock.findByExecutionDateRange.mockResolvedValue(scheduledDistributions) + configServiceMock.get.mockReturnValueOnce(DEFAULT_BATCH_SIZE) + + await processScheduledPayoutsUseCase.execute() + + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(distributionRepositoryMock.findByExecutionDateRange).toHaveBeenCalledTimes(1) + expect(executeCorporateActionDistributionDomainServiceMock.execute).toHaveBeenCalledTimes(2) + expect(executeCorporateActionDistributionDomainServiceMock.execute).toHaveBeenCalledWith(distribution1) + expect(executeCorporateActionDistributionDomainServiceMock.execute).toHaveBeenCalledWith(distribution2) + }) + + it("should sync from on-chain and handle empty distributions list", async () => { + distributionRepositoryMock.findByExecutionDateRange.mockResolvedValue([]) + configServiceMock.get.mockReturnValue(DEFAULT_BATCH_SIZE) + + await processScheduledPayoutsUseCase.execute() + + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(distributionRepositoryMock.findByExecutionDateRange).toHaveBeenCalledTimes(1) + expect(executeCorporateActionDistributionDomainServiceMock.execute).not.toHaveBeenCalled() + expect(executePayoutDistributionDomainServiceMock.execute).not.toHaveBeenCalled() + }) + + it("should process single distribution when only one is scheduled for today", async () => { + const distribution = DistributionUtils.newInstance({ status: DistributionStatus.SCHEDULED }) + const scheduledDistributions = [distribution] + distributionRepositoryMock.findByExecutionDateRange.mockResolvedValue(scheduledDistributions) + configServiceMock.get.mockReturnValue(DEFAULT_BATCH_SIZE) + + await processScheduledPayoutsUseCase.execute() + + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(distributionRepositoryMock.findByExecutionDateRange).toHaveBeenCalledTimes(1) + expect(executeCorporateActionDistributionDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(executeCorporateActionDistributionDomainServiceMock.execute).toHaveBeenCalledWith(distribution) + }) + + it("should handle manual distributions correctly", async () => { + const manualDistribution = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + details: { + type: DistributionType.PAYOUT, + snapshotId: SnapshotId.create(faker.string.numeric()), + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + const scheduledDistributions = [manualDistribution] + distributionRepositoryMock.findByExecutionDateRange.mockResolvedValue(scheduledDistributions) + configServiceMock.get.mockReturnValue(DEFAULT_BATCH_SIZE) + + await processScheduledPayoutsUseCase.execute() + + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(distributionRepositoryMock.findByExecutionDateRange).toHaveBeenCalledTimes(1) + expect(executePayoutDistributionDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(executePayoutDistributionDomainServiceMock.execute).toHaveBeenCalledWith(manualDistribution) + expect(executeCorporateActionDistributionDomainServiceMock.execute).not.toHaveBeenCalled() + }) + + it("should handle mixed distribution types correctly", async () => { + const corporateActionDistribution = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.numeric()), + executionDate: faker.date.future(), + }, + }) + const manualDistribution = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + details: { + type: DistributionType.PAYOUT, + snapshotId: SnapshotId.create(faker.string.numeric()), + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + const scheduledDistributions = [corporateActionDistribution, manualDistribution] + distributionRepositoryMock.findByExecutionDateRange.mockResolvedValue(scheduledDistributions) + configServiceMock.get.mockReturnValue(DEFAULT_BATCH_SIZE) + + await processScheduledPayoutsUseCase.execute() + + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(distributionRepositoryMock.findByExecutionDateRange).toHaveBeenCalledTimes(1) + expect(executeCorporateActionDistributionDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(executeCorporateActionDistributionDomainServiceMock.execute).toHaveBeenCalledWith( + corporateActionDistribution, + ) + expect(executePayoutDistributionDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(executePayoutDistributionDomainServiceMock.execute).toHaveBeenCalledWith(manualDistribution) + }) + + it("should propagate errors from sync service", async () => { + const error = new Error("Sync failed") + syncFromOnChainDomainServiceMock.execute.mockRejectedValueOnce(error) + + await expect(processScheduledPayoutsUseCase.execute()).rejects.toThrow("Sync failed") + + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(distributionRepositoryMock.findByExecutionDateRange).not.toHaveBeenCalled() + }) + + it("should propagate errors from distribution repository", async () => { + const error = new Error("Database error") + distributionRepositoryMock.findByExecutionDateRange.mockRejectedValueOnce(error) + + await expect(processScheduledPayoutsUseCase.execute()).rejects.toThrow("Database error") + + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalledTimes(1) + expect(distributionRepositoryMock.findByExecutionDateRange).toHaveBeenCalledTimes(1) + }) + + it("should propagate errors from mass payout execution", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.numeric()), + executionDate: faker.date.future(), + }, + }) + const error = new Error("Mass payout failed") + distributionRepositoryMock.findByExecutionDateRange.mockResolvedValue([distribution]) + configServiceMock.get.mockReturnValue(DEFAULT_BATCH_SIZE) + executeCorporateActionDistributionDomainServiceMock.execute.mockRejectedValueOnce(error) + + await expect(processScheduledPayoutsUseCase.execute()).rejects.toThrow("Mass payout failed") + + expect(executeCorporateActionDistributionDomainServiceMock.execute).toHaveBeenCalledTimes(1) + }) + + it("should propagate errors from manual payout execution", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.SCHEDULED, + details: { + type: DistributionType.PAYOUT, + snapshotId: SnapshotId.create(faker.string.numeric()), + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + const error = new Error("Payout failed") + distributionRepositoryMock.findByExecutionDateRange.mockResolvedValue([distribution]) + configServiceMock.get.mockReturnValue(DEFAULT_BATCH_SIZE) + executePayoutDistributionDomainServiceMock.execute.mockRejectedValueOnce(error) + + await expect(processScheduledPayoutsUseCase.execute()).rejects.toThrow("Payout failed") + + expect(executePayoutDistributionDomainServiceMock.execute).toHaveBeenCalledTimes(1) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/retry-failed-holders.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/retry-failed-holders.use-case.spec.ts new file mode 100644 index 000000000..e40cb7386 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/retry-failed-holders.use-case.spec.ts @@ -0,0 +1,243 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { + RetryFailedHoldersCommand, + RetryFailedHoldersUseCase, +} from "@application/use-cases/retry-failed-holders.use-case" +import { RetryFailedHoldersDomainService } from "@domain/services/retry-failed-holders.domain-service" + +describe(RetryFailedHoldersUseCase.name, () => { + let retryFailedHoldersUseCase: RetryFailedHoldersUseCase + const retryFailedHoldersDomainServiceMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + RetryFailedHoldersUseCase, + { + provide: RetryFailedHoldersDomainService, + useValue: retryFailedHoldersDomainServiceMock, + }, + ], + }).compile() + + retryFailedHoldersUseCase = module.get(RetryFailedHoldersUseCase) + }) + + describe("execute", () => { + it("should call domain service with correct parameters", async () => { + const command = { + distributionId: faker.string.uuid(), + } as RetryFailedHoldersCommand + + await retryFailedHoldersUseCase.execute(command) + + expect(retryFailedHoldersDomainServiceMock.execute).toHaveBeenCalledWith(command.distributionId) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/unpause-asset.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/unpause-asset.use-case.spec.ts new file mode 100644 index 000000000..c52377c1e --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/unpause-asset.use-case.spec.ts @@ -0,0 +1,266 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { UnpauseAssetUseCase } from "@application/use-cases/unpause-asset.use-case" +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { UnpauseAssetDomainService } from "@domain/services/unpause-asset.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" + +describe(UnpauseAssetUseCase.name, () => { + let unpauseAssetUseCase: UnpauseAssetUseCase + const unpauseAssetDomainServiceMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + UnpauseAssetUseCase, + { + provide: UnpauseAssetDomainService, + useValue: unpauseAssetDomainServiceMock, + }, + ], + }).compile() + + unpauseAssetUseCase = module.get(UnpauseAssetUseCase) + + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should call domain service with correct parameters and return the result", async () => { + const id = faker.string.uuid() + const name = faker.commerce.productName() + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const expectedAsset = new Asset( + id, + name, + AssetType.EQUITY, + hederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + undefined, + undefined, + false, + true, + new Date(), + new Date(), + ) + + unpauseAssetDomainServiceMock.unpause.mockResolvedValue(expectedAsset) + + const result = await unpauseAssetUseCase.execute(id) + + expect(unpauseAssetDomainServiceMock.unpause).toHaveBeenCalledWith(id) + expect(result).toBe(expectedAsset) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/application/use-cases/update-asset.use-case.spec.ts b/apps/mass-payout/backend/test/unit/application/use-cases/update-asset.use-case.spec.ts new file mode 100644 index 000000000..1b50df7d2 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/application/use-cases/update-asset.use-case.spec.ts @@ -0,0 +1,264 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { UpdateAssetUseCase } from "@application/use-cases/update-asset.use-case" +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { UpdateAssetDomainService } from "@domain/services/update-asset.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" + +describe(UpdateAssetUseCase.name, () => { + let updateAssetUseCase: UpdateAssetUseCase + const updateAssetDomainServiceMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + UpdateAssetUseCase, + { + provide: UpdateAssetDomainService, + useValue: updateAssetDomainServiceMock, + }, + ], + }).compile() + + updateAssetUseCase = module.get(UpdateAssetUseCase) + }) + + describe("execute", () => { + it("should call domain service with correct parameters and return the result", async () => { + const id = faker.string.uuid() + const name = faker.commerce.productName() + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const expectedAsset = new Asset( + id, + name, + AssetType.EQUITY, + hederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + undefined, + undefined, + false, + true, + new Date(), + new Date(), + ) + + updateAssetDomainServiceMock.updateAsset.mockResolvedValue(expectedAsset) + + const result = await updateAssetUseCase.execute(id, name) + + expect(updateAssetDomainServiceMock.updateAsset).toHaveBeenCalledWith(id, name) + expect(result).toBe(expectedAsset) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/errors/shared/custom.error.spec.ts b/apps/mass-payout/backend/test/unit/domain/errors/shared/custom.error.spec.ts new file mode 100644 index 000000000..ef7128212 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/errors/shared/custom.error.spec.ts @@ -0,0 +1,269 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { CustomError } from "@domain/errors/shared/custom.error" +import { faker } from "@faker-js/faker" + +const truncated = (msg: string) => msg.substring(0, CustomError.MAX_MESSAGE_LENGTH) + "... (omitted)" + +describe(CustomError.name, () => { + it("uses the default message when none is provided", () => { + const err = new CustomError() + + expect(err).toMatchObject({ message: "Internal error", cause: undefined }) + expect(err.name).toBe(CustomError.name) + }) + + it(`truncates messages longer than ${CustomError.MAX_MESSAGE_LENGTH} characters`, () => { + const longMessage = "x".repeat(CustomError.MAX_MESSAGE_LENGTH + 100) + + const err = new CustomError(longMessage) + + expect(err.message).toBe(truncated(longMessage)) + }) + + it("appends the original stack trace after the wrapper stack", () => { + const original = new Error("root stack") + + const err = new CustomError("wrapper stack", original) + + expect(err.stack).toContain("Error: wrapper stack") + expect(err.stack).toContain("Error: root stack") + }) + + it("returns the original root error, no matter the wrap depth", () => { + const rootError = new Error("deepest") + + const wrappedTwice = new CustomError("level-1", new CustomError("level-2", rootError)) + + expect(CustomError.getRootError(wrappedTwice)).toBe(rootError) + }) + + describe("toJson()", () => { + it("includes the cause when the root error is a CustomError", () => { + const message = faker.lorem.sentence() + const cause = faker.lorem.sentence() + + const root = new CustomError("root error message", undefined, cause) + const wrapped = new CustomError(message, root) + + expect(wrapped.toJson()).toEqual({ + message: message, + cause: cause, + }) + }) + + it("sets cause to undefined when the root error is a plain Error", () => { + const root = new Error("root") + const wrappedMessage = faker.lorem.sentence() + + const wrapped = new CustomError(wrappedMessage, root) + + expect(wrapped.toJson()).toEqual({ + message: wrappedMessage, + cause: undefined, + }) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/model/asset.entity.spec.ts b/apps/mass-payout/backend/test/unit/domain/model/asset.entity.spec.ts new file mode 100644 index 000000000..5dfba116a --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/model/asset.entity.spec.ts @@ -0,0 +1,868 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { + AssetEvmTokenAddressInvalidError, + AssetHederaTokenAddressInvalidError, + AssetLifeCycleCashFlowEvmAddressInvalidError, + AssetLifeCycleCashFlowHederaAddressInvalidError, + AssetNameMissingError, +} from "@domain/errors/asset.error" +import { BaseEntityInvalidDatesError } from "@domain/errors/shared/base-entity-invalid-dates.error" +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { LifeCycleCashFlowAddress } from "@domain/model/life-cycle-cash-flow-address.value-object" +import { faker } from "@faker-js/faker" +import { AssetUtils } from "@test/shared/asset.utils" +import { fakeHederaAddress, fakeLifeCycleCashFlowAddress } from "@test/shared/utils" + +describe(Asset.name, () => { + describe("create", () => { + it("should create an Asset", () => { + const name = faker.string.alphanumeric() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const asset = AssetUtils.newInstance({ name, type, hederaTokenAddress, evmTokenAddress }) + + expect(asset).toBeInstanceOf(Asset) + expect(asset.id).toBeDefined() + expect(asset.name).toBe(name) + expect(asset.type).toBe(type) + expect(asset.hederaTokenAddress).toBe(hederaTokenAddress) + expect(asset.evmTokenAddress).toBe(evmTokenAddress) + }) + + it("should create an Asset with BOND type", () => { + const name = faker.string.alphanumeric() + const type = AssetType.BOND + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const asset = AssetUtils.newInstance({ name, type, hederaTokenAddress, evmTokenAddress }) + + expect(asset).toBeInstanceOf(Asset) + expect(asset.id).toBeDefined() + expect(asset.name).toBe(name) + expect(asset.type).toBe(type) + expect(asset.hederaTokenAddress).toBe(hederaTokenAddress) + expect(asset.evmTokenAddress).toBe(evmTokenAddress) + }) + + it("should create an Asset with isPaused set to true if specified", () => { + const name = faker.string.alphanumeric() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const isPaused = true + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, type, hederaTokenAddress, evmTokenAddress, symbol, undefined, isPaused) + + expect(asset).toBeInstanceOf(Asset) + expect(asset.id).toBeDefined() + expect(asset.name).toBe(name) + expect(asset.type).toBe(type) + expect(asset.hederaTokenAddress).toBe(hederaTokenAddress) + expect(asset.evmTokenAddress).toBe(evmTokenAddress) + expect(asset.isPaused).toBe(true) + }) + + it("fails when name is empty, null or undefined", () => { + const invalidNames = [" ", "", null, undefined] as unknown[] + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + invalidNames.forEach((invalidName) => { + expect(() => { + const symbol = faker.string.alpha({ length: 3 }) + Asset.create(invalidName as string, type, hederaTokenAddress, evmTokenAddress, symbol) + }).toThrow(AssetNameMissingError) + }) + }) + + it("fails when hederaTokenAddress is not in format 0.0.X", () => { + const name = faker.finance.currencyName() + const type = AssetType.EQUITY + const invalidHederaTokenAddresses = ["1.2", "a.b.c", "0.0", faker.string.uuid()] + const evmTokenAddress = faker.finance.ethereumAddress() + + invalidHederaTokenAddresses.forEach((invalidHederaTokenAddress) => { + let error: Error + try { + const symbol = faker.string.alpha({ length: 3 }) + Asset.create(name, type, invalidHederaTokenAddress, evmTokenAddress, symbol) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(AssetHederaTokenAddressInvalidError) + }) + }) + + it("fails when evmTokenAddress is not a valid Ethereum address", () => { + const name = faker.finance.currencyName() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const invalidEvmTokenAddresses = ["1.2", "a.b.c", "0.0", "0xInvalidEthereumAddress"] + + invalidEvmTokenAddresses.forEach((invalidEvmTokenAddress) => { + let error: Error + try { + const symbol = faker.string.alpha({ length: 3 }) + Asset.create(name, type, hederaTokenAddress, invalidEvmTokenAddress, symbol) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(AssetEvmTokenAddressInvalidError) + }) + }) + }) + + describe("createExisting", () => { + it("should recreate an Asset with all provided valid data", () => { + const id = faker.string.uuid() + const name = faker.finance.currencyName() + const type = AssetType.BOND + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaLifeCycleCashFlowAddress = fakeHederaAddress() + const evmLifeCycleCashFlowAddress = faker.finance.ethereumAddress() + const isPaused = false + const syncEnabled = true + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = type === AssetType.BOND ? faker.date.future() : undefined + const asset = Asset.createExisting( + id, + name, + type, + hederaTokenAddress, + evmTokenAddress, + symbol, + maturityDate, + hederaLifeCycleCashFlowAddress, + evmLifeCycleCashFlowAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + + expect(asset).toBeInstanceOf(Asset) + expect(asset.id).toBe(id) + expect(asset.name).toBe(name) + expect(asset.type).toBe(type) + expect(asset.hederaTokenAddress).toBe(hederaTokenAddress) + expect(asset.evmTokenAddress).toBe(evmTokenAddress) + expect(asset.lifeCycleCashFlowHederaAddress).toBe(hederaLifeCycleCashFlowAddress) + expect(asset.lifeCycleCashFlowEvmAddress).toBe(evmLifeCycleCashFlowAddress) + expect(asset.isPaused).toBe(isPaused) + expect(asset.syncEnabled).toBe(syncEnabled) + expect(asset.createdAt).toBe(createdAt) + expect(asset.updatedAt).toBe(updatedAt) + }) + + it("fails when name is empty, null or undefined for existing asset", () => { + const id = faker.string.uuid() + const invalidNames = [" ", "", null, undefined] as unknown[] + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaLifeCycleCashFlowAddress = fakeHederaAddress() + const evmLifeCycleCashFlowAddress = faker.finance.ethereumAddress() + const isPaused = false + const syncEnabled = true + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + invalidNames.forEach((invalidName) => { + let error: Error + try { + const symbol = faker.string.alpha({ length: 3 }) + Asset.createExisting( + id, + invalidName as string, + type, + hederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + hederaLifeCycleCashFlowAddress, + evmLifeCycleCashFlowAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(AssetNameMissingError) + }) + }) + + it("fails when hederaTokenAddress is not in format 0.0.X for existing asset", () => { + const id = faker.string.uuid() + const name = faker.finance.currencyName() + const type = AssetType.EQUITY + const invalidHederaTokenAddresses = ["1.2", "a.b.c", "0.0", faker.string.uuid()] + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaLifeCycleCashFlowAddress = fakeHederaAddress() + const evmLifeCycleCashFlowAddress = faker.finance.ethereumAddress() + const isPaused = false + const syncEnabled = true + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + invalidHederaTokenAddresses.forEach((invalidHederaTokenAddress) => { + let error: Error + try { + const symbol = faker.string.alpha({ length: 3 }) + Asset.createExisting( + id, + name, + type, + invalidHederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + hederaLifeCycleCashFlowAddress, + evmLifeCycleCashFlowAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(AssetHederaTokenAddressInvalidError) + }) + }) + + it("fails when evmTokenAddress is not a valid Ethereum address for existing asset", () => { + const id = faker.string.uuid() + const name = faker.finance.currencyName() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const hederaLifeCycleCashFlowAddress = fakeHederaAddress() + const isPaused = false + const syncEnabled = true + const evmLifeCycleCashFlowAddress = faker.finance.ethereumAddress() + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const invalidEvmTokenAddresses = ["1.2", "a.b.c", "0.0", "0xInvalidEthereumAddress"] + + invalidEvmTokenAddresses.forEach((invalidEvmTokenAddress) => { + let error: Error + try { + const symbol = faker.string.alpha({ length: 3 }) + Asset.createExisting( + id, + name, + type, + hederaTokenAddress, + invalidEvmTokenAddress, + symbol, + undefined, + hederaLifeCycleCashFlowAddress, + evmLifeCycleCashFlowAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(AssetEvmTokenAddressInvalidError) + }) + }) + + it("should fail if createdAt is after updatedAt when recreating from existing data", () => { + const id = faker.string.uuid() + const name = faker.finance.currencyName() + const type = AssetType.BOND + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaLifeCycleCashFlowAddress = fakeHederaAddress() + const isPaused = false + const syncEnabled = true + const evmLifeCycleCashFlowAddress = faker.finance.ethereumAddress() + const createdAt = faker.date.future() + const updatedAt = faker.date.past() + let error: Error + + try { + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = type === AssetType.BOND ? faker.date.future() : undefined + Asset.createExisting( + id, + name, + type, + hederaTokenAddress, + evmTokenAddress, + symbol, + maturityDate, + hederaLifeCycleCashFlowAddress, + evmLifeCycleCashFlowAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + } catch (e) { + error = e + } + + expect(error).toBeInstanceOf(BaseEntityInvalidDatesError) + }) + + it("should fail if lifeCycleCashFlowHederaAddress is not in format 0.0.X", () => { + const wrongLifeCycleCashFlowHederaAddress = "0.0.WrongAddress" + const name = faker.string.alphanumeric() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const isPaused = false + const syncEnabled = true + const lifeCycleCashFlowEvmAddress = faker.finance.ethereumAddress() + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + expect(() => { + const symbol = faker.string.alpha({ length: 3 }) + Asset.createExisting( + faker.string.uuid(), + name, + type, + hederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + wrongLifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + }).toThrow(AssetLifeCycleCashFlowHederaAddressInvalidError) + }) + + it("should fail if lifeCycleCashFlowEvmAddress is not a valid Ethereum address", () => { + const wrongLifeCycleCashFlowEvmAddress = "0xWrongAddress" + const name = faker.string.alphanumeric() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const isPaused = false + const syncEnabled = true + const lifeCycleCashFlowHederaAddress = fakeHederaAddress() + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + expect(() => { + const symbol = faker.string.alpha({ length: 3 }) + Asset.createExisting( + faker.string.uuid(), + name, + type, + hederaTokenAddress, + evmTokenAddress, + symbol, + undefined, + lifeCycleCashFlowHederaAddress, + wrongLifeCycleCashFlowEvmAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + }).toThrow(AssetLifeCycleCashFlowEvmAddressInvalidError) + }) + }) + + describe("withLifeCycleCashFlow", () => { + it("should add lifeCycleCashFlow addresses to an existing asset", () => { + const name = faker.string.alphanumeric() + const type = AssetType.BOND + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const asset = AssetUtils.newInstance({ name, type, hederaTokenAddress, evmTokenAddress }) + + const lifeCycleCashFlowAddress = fakeLifeCycleCashFlowAddress() + const hederaLifeCycleCashFlowAddress = lifeCycleCashFlowAddress.hederaAddress + const evmLifeCycleCashFlowAddress = lifeCycleCashFlowAddress.evmAddress + + expect(asset.lifeCycleCashFlowHederaAddress).toBeUndefined() + expect(asset.lifeCycleCashFlowEvmAddress).toBeUndefined() + + const assetWithLifeCycleCashFlow = asset.withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + expect(assetWithLifeCycleCashFlow).toBeInstanceOf(Asset) + expect(assetWithLifeCycleCashFlow.id).toBe(asset.id) + expect(assetWithLifeCycleCashFlow.name).toBe(name) + expect(assetWithLifeCycleCashFlow.type).toBe(type) + expect(assetWithLifeCycleCashFlow.hederaTokenAddress).toBe(hederaTokenAddress) + expect(assetWithLifeCycleCashFlow.evmTokenAddress).toBe(evmTokenAddress) + expect(assetWithLifeCycleCashFlow.lifeCycleCashFlowHederaAddress).toBe(hederaLifeCycleCashFlowAddress) + expect(assetWithLifeCycleCashFlow.lifeCycleCashFlowEvmAddress).toBe(evmLifeCycleCashFlowAddress) + expect(assetWithLifeCycleCashFlow.createdAt).toBe(asset.createdAt) + }) + + it("should validate lifeCycleCashFlow addresses format", () => { + const invalidHederaAddress = "invalid-address" + const invalidEvmAddress = "invalid-ethereum-address" + const validEvmAddress = faker.finance.ethereumAddress() + const validHederaAddress = fakeHederaAddress() + + expect(() => { + LifeCycleCashFlowAddress.create(invalidHederaAddress, validEvmAddress) + }).toThrow(AssetLifeCycleCashFlowHederaAddressInvalidError) + + expect(() => { + LifeCycleCashFlowAddress.create(validHederaAddress, invalidEvmAddress) + }).toThrow(AssetLifeCycleCashFlowEvmAddressInvalidError) + }) + }) + + describe("withName", () => { + it("should create a new instance with updated name", () => { + const name = faker.company.name() + const newName = faker.company.name() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, type, hederaTokenAddress, evmTokenAddress, symbol) + expect(asset.name).toBe(name) + + const updatedAsset = asset.withName(newName) + + expect(updatedAsset).toBeInstanceOf(Asset) + expect(updatedAsset.id).toBe(asset.id) + expect(updatedAsset.name).toBe(newName) + expect(updatedAsset.type).toBe(type) + expect(updatedAsset.hederaTokenAddress).toBe(hederaTokenAddress) + expect(updatedAsset.evmTokenAddress).toBe(evmTokenAddress) + expect(updatedAsset.lifeCycleCashFlowHederaAddress).toBeUndefined() + expect(updatedAsset.lifeCycleCashFlowEvmAddress).toBeUndefined() + expect(updatedAsset.createdAt).toBe(asset.createdAt) + expect(updatedAsset.updatedAt).not.toBe(asset.updatedAt) + }) + + it("should validate the new name", () => { + const name = faker.company.name() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, type, hederaTokenAddress, evmTokenAddress, symbol) + + expect(() => { + asset.withName("") + }).toThrow(AssetNameMissingError) + + expect(() => { + asset.withName(" ") + }).toThrow(AssetNameMissingError) + }) + }) + + describe("withType", () => { + it("should create a new instance with updated type", () => { + const name = faker.company.name() + const originalType = AssetType.EQUITY + const newType = AssetType.BOND + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, originalType, hederaTokenAddress, evmTokenAddress, symbol) + expect(asset.type).toBe(originalType) + + const updatedAsset = asset.withType(newType) + + expect(updatedAsset).toBeInstanceOf(Asset) + expect(updatedAsset.id).toBe(asset.id) + expect(updatedAsset.name).toBe(name) + expect(updatedAsset.type).toBe(newType) + expect(updatedAsset.hederaTokenAddress).toBe(hederaTokenAddress) + expect(updatedAsset.evmTokenAddress).toBe(evmTokenAddress) + expect(updatedAsset.lifeCycleCashFlowHederaAddress).toBeUndefined() + expect(updatedAsset.lifeCycleCashFlowEvmAddress).toBeUndefined() + expect(updatedAsset.createdAt).toBe(asset.createdAt) + expect(updatedAsset.updatedAt).not.toBe(asset.updatedAt) + }) + + it("should preserve lifecycle cash flow addresses when updating type", () => { + const name = faker.company.name() + const originalType = AssetType.EQUITY + const newType = AssetType.BOND + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, originalType, hederaTokenAddress, evmTokenAddress, symbol) + const lifeCycleCashFlowAddress = fakeLifeCycleCashFlowAddress() + const assetWithLifeCycle = asset.withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + const updatedAsset = assetWithLifeCycle.withType(newType) + + expect(updatedAsset.type).toBe(newType) + expect(updatedAsset.lifeCycleCashFlowHederaAddress).toBe(lifeCycleCashFlowAddress.hederaAddress) + expect(updatedAsset.lifeCycleCashFlowEvmAddress).toBe(lifeCycleCashFlowAddress.evmAddress) + }) + }) + + describe("pause and unpause", () => { + it("should create a new instance with isPaused set to true when paused", () => { + const name = faker.company.name() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, type, hederaTokenAddress, evmTokenAddress, symbol) + expect(asset.isPaused).toBe(false) + + const pausedAsset = asset.pause() + + expect(pausedAsset).toBeInstanceOf(Asset) + expect(pausedAsset.id).toBe(asset.id) + expect(pausedAsset.name).toBe(name) + expect(pausedAsset.type).toBe(type) + expect(pausedAsset.hederaTokenAddress).toBe(hederaTokenAddress) + expect(pausedAsset.evmTokenAddress).toBe(evmTokenAddress) + expect(pausedAsset.lifeCycleCashFlowHederaAddress).toBeUndefined() + expect(pausedAsset.lifeCycleCashFlowEvmAddress).toBeUndefined() + expect(pausedAsset.isPaused).toBe(true) + expect(pausedAsset.createdAt).toBe(asset.createdAt) + expect(pausedAsset.updatedAt).not.toBe(asset.updatedAt) + }) + + it("should create a new instance with isPaused set to false when unpaused", () => { + const name = faker.company.name() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, type, hederaTokenAddress, evmTokenAddress, symbol) + const pausedAsset = asset.pause() + expect(pausedAsset.isPaused).toBe(true) + + const unpausedAsset = pausedAsset.unpause() + + expect(unpausedAsset).toBeInstanceOf(Asset) + expect(unpausedAsset.id).toBe(asset.id) + expect(unpausedAsset.name).toBe(name) + expect(unpausedAsset.type).toBe(type) + expect(unpausedAsset.hederaTokenAddress).toBe(hederaTokenAddress) + expect(unpausedAsset.evmTokenAddress).toBe(evmTokenAddress) + expect(unpausedAsset.lifeCycleCashFlowHederaAddress).toBeUndefined() + expect(unpausedAsset.lifeCycleCashFlowEvmAddress).toBeUndefined() + expect(unpausedAsset.isPaused).toBe(false) + expect(unpausedAsset.createdAt).toBe(asset.createdAt) + expect(unpausedAsset.updatedAt).not.toBe(pausedAsset.updatedAt) + }) + + it("should preserve lifecycle cash flow addresses when pausing and unpausing", () => { + const name = faker.company.name() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, type, hederaTokenAddress, evmTokenAddress, symbol) + const lifeCycleCashFlowAddress = fakeLifeCycleCashFlowAddress() + const assetWithLifeCycle = asset.withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + const pausedAsset = assetWithLifeCycle.pause() + expect(pausedAsset.isPaused).toBe(true) + expect(pausedAsset.lifeCycleCashFlowHederaAddress).toBe(lifeCycleCashFlowAddress.hederaAddress) + expect(pausedAsset.lifeCycleCashFlowEvmAddress).toBe(lifeCycleCashFlowAddress.evmAddress) + + const unpausedAsset = pausedAsset.unpause() + expect(unpausedAsset.isPaused).toBe(false) + expect(unpausedAsset.lifeCycleCashFlowHederaAddress).toBe(lifeCycleCashFlowAddress.hederaAddress) + expect(unpausedAsset.lifeCycleCashFlowEvmAddress).toBe(lifeCycleCashFlowAddress.evmAddress) + }) + + it("should create asset with isPaused false by default", () => { + const name = faker.string.alphanumeric() + const type = AssetType.EQUITY + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, type, hederaTokenAddress, evmTokenAddress, symbol) + + expect(asset.isPaused).toBe(false) + }) + + it("should allow multiple pause/unpause operations", () => { + const name = faker.company.name() + const type = AssetType.BOND + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, type, hederaTokenAddress, evmTokenAddress, symbol) + + const pausedOnce = asset.pause() + expect(pausedOnce.isPaused).toBe(true) + + const pausedTwice = pausedOnce.pause() + expect(pausedTwice.isPaused).toBe(true) + + const unpausedOnce = pausedTwice.unpause() + expect(unpausedOnce.isPaused).toBe(false) + + const unpausedTwice = unpausedOnce.unpause() + expect(unpausedTwice.isPaused).toBe(false) + }) + + it("should recreate existing asset with isPaused state", () => { + const id = faker.string.uuid() + const name = faker.finance.currencyName() + const type = AssetType.BOND + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaLifeCycleCashFlowAddress = fakeHederaAddress() + const evmLifeCycleCashFlowAddress = faker.finance.ethereumAddress() + const isPaused = true + const syncEnabled = false + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = type === AssetType.BOND ? faker.date.future() : undefined + const asset = Asset.createExisting( + id, + name, + type, + hederaTokenAddress, + evmTokenAddress, + symbol, + maturityDate, + hederaLifeCycleCashFlowAddress, + evmLifeCycleCashFlowAddress, + isPaused, + syncEnabled, + createdAt, + updatedAt, + ) + + expect(asset.isPaused).toBe(true) + expect(asset.id).toBe(id) + expect(asset.name).toBe(name) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/model/batch-payout.entity.spec.ts b/apps/mass-payout/backend/test/unit/domain/model/batch-payout.entity.spec.ts new file mode 100644 index 000000000..8b60d603b --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/model/batch-payout.entity.spec.ts @@ -0,0 +1,404 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayout, BatchPayoutStatus } from "@domain/model/batch-payout" +import { faker } from "@faker-js/faker" +import { fakeHederaTxId } from "@test/shared/utils" +import { + BatchPayoutDistributionIdMissingError, + BatchPayoutHederaTransactionIdInvalidError, + BatchPayoutHederaTransactionHashInvalidError, + BatchPayoutHoldersNumberInvalidError, +} from "@domain/errors/batch-payout.error" +import { BaseEntityInvalidDatesError } from "@domain/errors/shared/base-entity-invalid-dates.error" +import { Distribution } from "@domain/model/distribution" +import { DistributionUtils } from "@test/shared/distribution.utils" + +describe(BatchPayout.name, () => { + describe("create", () => { + it("should create a BatchPayout", () => { + const distribution = DistributionUtils.newInstance() + const hederaTransactionId = fakeHederaTxId() + const hederaTransactionHash = `0x${faker.string.hexadecimal({ length: 96, prefix: "" })}` + const name = faker.string.alpha({ length: 10 }) + const holdersNumber = 10 + const status = BatchPayoutStatus.IN_PROGRESS + const createdAt = faker.date.past() + const updatedAt = faker.date.future() + + const batchPayout = BatchPayout.create( + distribution, + name, + hederaTransactionId, + hederaTransactionHash, + holdersNumber, + status, + createdAt, + updatedAt, + ) + + expect(batchPayout).toBeInstanceOf(BatchPayout) + expect(batchPayout.distribution).toBe(distribution) + expect(batchPayout.hederaTransactionId).toBe(hederaTransactionId) + expect(batchPayout.hederaTransactionHash).toBe(hederaTransactionHash) + expect(batchPayout.name).toBe(name) + expect(batchPayout.holdersNumber).toBe(holdersNumber) + expect(batchPayout.status).toBe(status) + expect(batchPayout.createdAt).toBe(createdAt) + expect(batchPayout.updatedAt).toBe(updatedAt) + }) + + it("auto-fills id & dates when omitted", () => { + const batch = BatchPayout.create( + DistributionUtils.newInstance(), + faker.string.alpha({ length: 10 }), + fakeHederaTxId(), + `0x${faker.string.hexadecimal({ length: 96, prefix: "" })}`, + 5, + BatchPayoutStatus.IN_PROGRESS, + ) + + expect(batch.createdAt.getTime()).toBe(batch.updatedAt.getTime()) + }) + + it("creates an existing BatchPayout using createExisting()", () => { + const id = faker.string.uuid() + const distribution = DistributionUtils.newInstance() + const hederaTransactionId = fakeHederaTxId() + const hederaTransactionHash = `0x${faker.string.hexadecimal({ length: 96, prefix: "" })}` + const name = faker.string.alpha({ length: 10 }) + const holdersNumber = 20 + const status = BatchPayoutStatus.COMPLETED + const createdAt = faker.date.past() + const updatedAt = faker.date.future() + + const batch = BatchPayout.createExisting( + id, + distribution, + name, + hederaTransactionId, + hederaTransactionHash, + holdersNumber, + status, + createdAt, + updatedAt, + ) + + expect(batch.id).toBe(id) + expect(batch.status).toBe(status) + expect(batch.name).toBe(name) + expect(batch.distribution).toBe(distribution) + expect(batch.hederaTransactionId).toBe(hederaTransactionId) + expect(batch.hederaTransactionHash).toBe(hederaTransactionHash) + expect(batch.holdersNumber).toBe(holdersNumber) + expect(batch.createdAt).toBe(createdAt) + expect(batch.updatedAt).toBe(updatedAt) + }) + + it("fails when createdAt is after updatedAt", () => { + const createdAt = faker.date.future() + const updatedAt = faker.date.past() + let error: Error + + try { + BatchPayout.create( + DistributionUtils.newInstance(), + faker.string.alpha({ length: 10 }), + fakeHederaTxId(), + faker.finance.ethereumAddress(), + 1, + BatchPayoutStatus.FAILED, + createdAt, + updatedAt, + ) + } catch (e) { + error = e + } + + expect(error).toBeInstanceOf(BaseEntityInvalidDatesError) + }) + + it("fails when distribution is empty, null or undefined", () => { + const invalidDistributions = [null, undefined] as unknown[] + + invalidDistributions.forEach((invalidDistribution) => { + let error: Error + + try { + BatchPayout.create( + invalidDistribution as Distribution, + faker.string.alpha({ length: 10 }), + fakeHederaTxId(), + `0x${faker.string.hexadecimal({ length: 96, prefix: "" })}`, + 1, + BatchPayoutStatus.FAILED, + ) + } catch (e) { + error = e as Error + } + + expect(error).toBeInstanceOf(BatchPayoutDistributionIdMissingError) + }) + }) + + it("fails when hederaTransactionHash is not a valid Hedera transaction id", () => { + let error: Error + + try { + BatchPayout.create( + DistributionUtils.newInstance(), + faker.string.alpha({ length: 10 }), + fakeHederaTxId(), + faker.finance.ethereumAddress(), + 2, + BatchPayoutStatus.IN_PROGRESS, + ) + } catch (e) { + error = e + } + + expect(error).toBeInstanceOf(BatchPayoutHederaTransactionHashInvalidError) + }) + + it("fails when hederaTransactionId is not a valid Hedera transaction ID", () => { + let error: Error + try { + BatchPayout.create( + DistributionUtils.newInstance(), + faker.string.alpha({ length: 10 }), + faker.string.alpha({ length: 10 }), + `0x${faker.string.hexadecimal({ length: 96, prefix: "" })}`, + 2, + BatchPayoutStatus.IN_PROGRESS, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(BatchPayoutHederaTransactionIdInvalidError) + }) + + it("fails when holdersNumber is zero or negative", () => { + const invalidNumbers = [0, -10] + + invalidNumbers.forEach(() => { + let error: Error + + try { + BatchPayout.create( + DistributionUtils.newInstance(), + faker.string.alpha({ length: 10 }), + fakeHederaTxId(), + `0x${faker.string.hexadecimal({ length: 96, prefix: "" })}`, + 0, + BatchPayoutStatus.IN_PROGRESS, + ) + } catch (e) { + error = e as Error + } + + expect(error).toBeInstanceOf(BatchPayoutHoldersNumberInvalidError) + }) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/model/distribution.entity.spec.ts b/apps/mass-payout/backend/test/unit/domain/model/distribution.entity.spec.ts new file mode 100644 index 000000000..61a92111f --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/model/distribution.entity.spec.ts @@ -0,0 +1,1458 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { + DistributionAssetIdMissingError, + DistributionExecutionDateInPastError, + DistributionExecutionDateMissingError, + DistributionRecurrencyMissingError, +} from "@domain/errors/distribution.error" +import { BaseEntityInvalidDatesError } from "@domain/errors/shared/base-entity-invalid-dates.error" +import { Asset } from "@domain/model/asset" +import { + AmountType, + Distribution, + DistributionStatus, + DistributionType, + PayoutSubtype, + Recurrency, +} from "@domain/model/distribution" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { faker } from "@faker-js/faker" +import { AssetUtils } from "@test/shared/asset.utils" + +describe(Distribution.name, () => { + describe("createCorporateAction", () => { + it("should create a Corporate Action Distribution", () => { + const asset = AssetUtils.newInstance() + const executionDate = faker.date.future() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + const distribution = Distribution.createCorporateAction( + asset, + corporateActionId, + executionDate, + status, + createdAt, + updatedAt, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.CORPORATE_ACTION) + expect((distribution.details as any).corporateActionId).toBe(corporateActionId) + expect((distribution.details as any).executionDate).toBe(executionDate) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it( + "should create a Corporate Action Distribution with default " + + "values when optional parameters are not provided", + () => { + const asset = AssetUtils.newInstance() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const executionDate = faker.date.future() + + const distribution = Distribution.createCorporateAction(asset, corporateActionId, executionDate) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.CORPORATE_ACTION) + expect((distribution.details as any).corporateActionId).toBe(corporateActionId) + expect((distribution.details as any).executionDate).toBe(executionDate) + expect(distribution.status).toBe(DistributionStatus.SCHEDULED) + expect(distribution.createdAt.getTime()).toBe(distribution.updatedAt.getTime()) + }, + ) + + it("should fail if createdAt is after updatedAt", () => { + const asset = AssetUtils.newInstance() + const executionDate = faker.date.future() + const status = faker.helpers.objectValue(DistributionStatus) + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const createdAt = faker.date.future() + const updatedAt = faker.date.past() + let error: Error + + try { + Distribution.createCorporateAction(asset, corporateActionId, executionDate, status, createdAt, updatedAt) + } catch (e) { + error = e + } + + expect(error).toBeInstanceOf(BaseEntityInvalidDatesError) + }) + + it("fails when asset is null or undefined", () => { + const invalidAssets = [null, undefined] as unknown[] + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const executionDate = faker.date.future() + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createCorporateAction(invalidAsset as Asset, corporateActionId, executionDate) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + + it("fails when executionDate is not provided or is in the past", () => { + const asset = AssetUtils.newInstance() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const pastDate = faker.date.past() + const invalidDates = [null, undefined, pastDate] + + invalidDates.forEach((invalidDate) => { + let error: Error + try { + Distribution.createCorporateAction(asset, corporateActionId, invalidDate as Date) + } catch (e) { + error = e + } + if (invalidDate === null || invalidDate === undefined) { + expect(error).toBeInstanceOf(DistributionExecutionDateMissingError) + } else { + expect(error).toBeInstanceOf(DistributionExecutionDateInPastError) + } + }) + }) + }) + + describe("createImmediate", () => { + it("should create a Payout Distribution", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + const distribution = Distribution.createImmediate( + asset, + amount, + amountType, + snapshotId, + status, + concept, + createdAt, + updatedAt, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.IMMEDIATE) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).concept).toBe(concept) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it("should create a Payout Distribution with default values when optional parameters are not provided", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + const distribution = Distribution.createImmediate(asset, amount, amountType, snapshotId) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.IMMEDIATE) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect(distribution.status).toBe(DistributionStatus.SCHEDULED) + expect(distribution.createdAt.getTime()).toBe(distribution.updatedAt.getTime()) + }) + + it("fails when asset is null or undefined", () => { + const invalidAssets = [null, undefined] as unknown[] + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createImmediate(invalidAsset as Asset, amount, amountType, snapshotId) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + }) + + describe("createExistingCorporateAction", () => { + it("should recreate a Corporate Action Distribution with all provided valid data", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const executionDate = faker.date.future() + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + const distribution = Distribution.createExistingCorporateAction( + id, + asset, + corporateActionId, + executionDate, + status, + createdAt, + updatedAt, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBe(id) + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.CORPORATE_ACTION) + expect((distribution.details as any).corporateActionId).toBe(corporateActionId) + expect((distribution.details as any).executionDate).toBe(executionDate) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it("should fail if createdAt is after updatedAt when recreating from existing data", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const executionDate = faker.date.future() + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.future() + const updatedAt = faker.date.past() + let error: Error + + try { + Distribution.createExistingCorporateAction( + id, + asset, + corporateActionId, + executionDate, + status, + createdAt, + updatedAt, + ) + } catch (e) { + error = e + } + + expect(error).toBeInstanceOf(BaseEntityInvalidDatesError) + }) + + it("fails when asset is null or undefined for existing distribution", () => { + const id = faker.string.uuid() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const invalidAssets = [null, undefined] as unknown[] + const executionDate = faker.date.past() + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createExistingCorporateAction( + id, + invalidAsset as Asset, + corporateActionId, + executionDate, + status, + createdAt, + updatedAt, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + + it("fails when executionDate is not provided for existing distribution", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const invalidDates = [null, undefined] + + invalidDates.forEach((invalidDate) => { + let error: Error + try { + Distribution.createExistingCorporateAction( + id, + asset, + corporateActionId, + invalidDate as Date, + status, + createdAt, + updatedAt, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionExecutionDateMissingError) + }) + }) + }) + + describe("createExistingImmediate", () => { + it("should recreate a Payout Distribution with all provided valid data", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + const distribution = Distribution.createExistingImmediate( + id, + asset, + snapshotId, + status, + createdAt, + updatedAt, + amount, + amountType, + concept, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBe(id) + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).concept).toBe(concept) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it("fails when asset is null or undefined for existing payout distribution", () => { + const id = faker.string.uuid() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const invalidAssets = [null, undefined] as unknown[] + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createExistingImmediate( + id, + invalidAsset as Asset, + snapshotId, + status, + createdAt, + updatedAt, + amount, + amountType, + concept, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + }) + + describe("updateExecutionDate", () => { + it("should update execution date for corporate action distribution", () => { + const asset = AssetUtils.newInstance() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const originalExecutionDate = faker.date.future() + const newExecutionDate = faker.date.future({ years: 2 }) + + const distribution = Distribution.createCorporateAction(asset, corporateActionId, originalExecutionDate) + const originalUpdatedAt = distribution.updatedAt.getTime() + + const updatedDistribution = distribution.updateExecutionDate(newExecutionDate) + + expect(updatedDistribution).toBeInstanceOf(Distribution) + expect(updatedDistribution.id).toBe(distribution.id) + expect((updatedDistribution.details as any).executionDate).toBe(newExecutionDate) + expect(updatedDistribution.updatedAt.getTime()).toBeGreaterThanOrEqual(originalUpdatedAt) + }) + + it("should fail when trying to update execution date for payout distribution", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const newExecutionDate = faker.date.future() + + const distribution = Distribution.createImmediate(asset, amount, amountType, snapshotId) + let error: Error + + try { + distribution.updateExecutionDate(newExecutionDate) + } catch (e) { + error = e as Error + } + + expect(error).toBeInstanceOf(Error) + expect(error.message).toBe("Cannot update execution date for non-corporate action distribution") + }) + }) + + describe("updateSnapshotId", () => { + it("should update snapshotId for payout distribution", () => { + const asset = AssetUtils.newInstance() + const originalSnapshotIdValue = faker.string.alpha({ length: 10 }) + const originalSnapshotId = SnapshotId.create(originalSnapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const newSnapshotNumber = faker.number.int({ min: 1000, max: 9999 }) + const distribution = Distribution.createImmediate(asset, amount, amountType, originalSnapshotId) + const originalUpdatedAt = distribution.updatedAt.getTime() + + distribution.updateSnapshotId(newSnapshotNumber) + + expect((distribution.details as any).snapshotId.value).toBe(newSnapshotNumber.toString()) + expect(distribution.updatedAt.getTime()).toBeGreaterThanOrEqual(originalUpdatedAt) + expect(distribution.id).toBe(distribution.id) + expect(distribution.asset).toBe(distribution.asset) + expect(distribution.status).toBe(distribution.status) + expect(distribution.createdAt).toBe(distribution.createdAt) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + }) + + it("should throw error when trying to update snapshotId for corporate action distribution", () => { + const asset = AssetUtils.newInstance() + const corporateActionIdValue = faker.string.alpha({ length: 10 }) + const corporateActionId = CorporateActionId.create(corporateActionIdValue) + const executionDate = faker.date.future() + const newSnapshotNumber = faker.number.int({ min: 1000, max: 9999 }) + + const distribution = Distribution.createCorporateAction(asset, corporateActionId, executionDate) + + expect(() => { + distribution.updateSnapshotId(newSnapshotNumber) + }).toThrow("Cannot update snapshot ID for non-payout distribution") + }) + }) + + describe("createOneOff", () => { + it("should create a One-Off Payout Distribution", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + const distribution = Distribution.createOneOff( + asset, + executeAt, + amount, + amountType, + snapshotId, + status, + concept, + createdAt, + updatedAt, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.ONE_OFF) + expect((distribution.details as any).executeAt).toBe(executeAt) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).concept).toBe(concept) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it( + "should create a One-Off Payout Distribution with default values when " + "optional parameters are not provided", + () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + const distribution = Distribution.createOneOff(asset, executeAt, amount, amountType, snapshotId) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.ONE_OFF) + expect((distribution.details as any).executeAt).toBe(executeAt) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect(distribution.status).toBe(DistributionStatus.SCHEDULED) + expect(distribution.createdAt.getTime()).toBe(distribution.updatedAt.getTime()) + }, + ) + + it("fails when asset is null or undefined", () => { + const invalidAssets = [null, undefined] as unknown[] + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createOneOff(invalidAsset as Asset, executeAt, amount, amountType, snapshotId) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + + it("fails when executeAt is not provided or is in the past", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const pastDate = faker.date.past() + const invalidDates = [null, undefined, pastDate] + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidDates.forEach((invalidDate) => { + let error: Error + try { + Distribution.createOneOff(asset, invalidDate as Date, amount, amountType, snapshotId) + } catch (e) { + error = e + } + if (invalidDate === null || invalidDate === undefined) { + expect(error).toBeInstanceOf(DistributionExecutionDateMissingError) + } else { + expect(error).toBeInstanceOf(DistributionExecutionDateInPastError) + } + }) + }) + }) + + describe("createExistingOneOff", () => { + it("should recreate a One-Off Payout Distribution with all provided valid data", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + const distribution = Distribution.createExistingOneOff( + id, + asset, + snapshotId, + executeAt, + status, + amount, + amountType, + createdAt, + updatedAt, + concept, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBe(id) + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.ONE_OFF) + expect((distribution.details as any).executeAt).toBe(executeAt) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).concept).toBe(concept) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it("fails when asset is null or undefined for existing one-off distribution", () => { + const id = faker.string.uuid() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const invalidAssets = [null, undefined] as unknown[] + const executeAt = faker.date.future() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createExistingOneOff( + id, + invalidAsset as Asset, + snapshotId, + executeAt, + status, + amount, + amountType, + createdAt, + updatedAt, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + + it("fails when executeAt is not provided for existing one-off distribution", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const invalidDates = [null, undefined] + const concept = faker.string.alpha({ length: 10 }) + + invalidDates.forEach((invalidDate) => { + let error: Error + try { + Distribution.createExistingOneOff( + id, + asset, + snapshotId, + invalidDate as Date, + status, + amount, + amountType, + createdAt, + updatedAt, + concept, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionExecutionDateMissingError) + }) + }) + }) + + describe("createRecurring", () => { + it("should create a Recurring Payout Distribution", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const recurrency = faker.helpers.objectValue(Recurrency) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + const distribution = Distribution.createRecurring( + asset, + executeAt, + recurrency, + amount, + amountType, + snapshotId, + status, + concept, + createdAt, + updatedAt, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.RECURRING) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).executeAt).toBe(executeAt) + expect((distribution.details as any).recurrency).toBe(recurrency) + expect((distribution.details as any).concept).toBe(concept) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it( + "should create a Recurring Payout Distribution with default values when " + + "optional parameters are not provided", + () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const recurrency = faker.helpers.objectValue(Recurrency) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + const distribution = Distribution.createRecurring(asset, executeAt, recurrency, amount, amountType, snapshotId) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.RECURRING) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).executeAt).toBe(executeAt) + expect((distribution.details as any).recurrency).toBe(recurrency) + expect(distribution.status).toBe(DistributionStatus.SCHEDULED) + expect(distribution.createdAt.getTime()).toBe(distribution.updatedAt.getTime()) + }, + ) + + it("should create next Recurring Payout Distribution", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = new Date(2050, 1, 1, 0, 0, 0) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const concept = faker.string.alpha({ length: 10 }) + + const distributionData = [ + { + distribution: Distribution.createRecurring( + asset, + executeAt, + Recurrency.HOURLY, + amount, + amountType, + snapshotId, + undefined, + concept, + ), + nextDate: new Date(2050, 1, 1, 1, 0, 0), + }, + { + distribution: Distribution.createRecurring( + asset, + executeAt, + Recurrency.DAILY, + amount, + amountType, + snapshotId, + undefined, + concept, + ), + nextDate: new Date(2050, 1, 2, 0, 0, 0), + }, + { + distribution: Distribution.createRecurring( + asset, + executeAt, + Recurrency.WEEKLY, + amount, + amountType, + snapshotId, + undefined, + concept, + ), + nextDate: new Date(2050, 1, 8, 0, 0, 0), + }, + { + distribution: Distribution.createRecurring( + asset, + executeAt, + Recurrency.MONTHLY, + amount, + amountType, + snapshotId, + undefined, + concept, + ), + nextDate: new Date(2050, 2, 1, 0, 0, 0), + }, + ] + + distributionData.forEach((data) => { + const nextRecurringDistribution: Distribution = data.distribution.createNextRecurring() + expect(nextRecurringDistribution).toBeInstanceOf(Distribution) + expect(nextRecurringDistribution.id).toBeDefined() + expect(nextRecurringDistribution.asset).toBe(asset) + expect(nextRecurringDistribution.details.type).toBe(DistributionType.PAYOUT) + expect((nextRecurringDistribution.details as any).snapshotId).toBeUndefined() + expect((nextRecurringDistribution.details as any).subtype).toBe(PayoutSubtype.RECURRING) + expect((nextRecurringDistribution.details as any).amount).toBe(amount) + expect((nextRecurringDistribution.details as any).amountType).toBe(amountType) + expect((nextRecurringDistribution.details as any).executeAt).toStrictEqual(data.nextDate) + expect((nextRecurringDistribution.details as any).recurrency).toBe( + (data.distribution.details as any).recurrency, + ) + expect((nextRecurringDistribution.details as any).concept).toBe(concept) + expect(nextRecurringDistribution.status).toBe(DistributionStatus.SCHEDULED) + expect(nextRecurringDistribution.createdAt.getTime()).toBe(nextRecurringDistribution.updatedAt.getTime()) + }) + }) + + it("fails when asset is null or undefined", () => { + const invalidAssets = [null, undefined] as unknown[] + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const recurrency = faker.helpers.objectValue(Recurrency) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createRecurring(invalidAsset as Asset, executeAt, recurrency, amount, amountType, snapshotId) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + + it("fails when executeAt is not provided or is in the past", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const pastDate = faker.date.past() + const recurrency = faker.helpers.objectValue(Recurrency) + const invalidDates = [null, undefined, pastDate] + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidDates.forEach((invalidDate) => { + let error: Error + try { + Distribution.createRecurring(asset, invalidDate as Date, recurrency, amount, amountType, snapshotId) + } catch (e) { + error = e + } + if (invalidDate === null || invalidDate === undefined) { + expect(error).toBeInstanceOf(DistributionExecutionDateMissingError) + } else { + expect(error).toBeInstanceOf(DistributionExecutionDateInPastError) + } + }) + }) + + it("fails when recurrency is not provided", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const invalidRecurrencies = [null, undefined] + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidRecurrencies.forEach((invalidRecurrency) => { + let error: Error + try { + Distribution.createRecurring( + asset, + executeAt, + invalidRecurrency as Recurrency, + amount, + amountType, + snapshotId, + ) + } catch (e) { + error = e + } + expect(error).toBeInstanceOf(DistributionRecurrencyMissingError) + }) + }) + }) + + describe("createExistingRecurring", () => { + it("should create a Recurring Payout Distribution", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const recurrency = faker.helpers.objectValue(Recurrency) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + const distribution = Distribution.createExistingRecurring( + id, + asset, + executeAt, + recurrency, + amount, + amountType, + snapshotId, + status, + createdAt, + updatedAt, + concept, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.RECURRING) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).executeAt).toBe(executeAt) + expect((distribution.details as any).recurrency).toBe(recurrency) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it( + "should create a Recurring Payout Distribution with default values when " + + "optional parameters are not provided", + () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const recurrency = faker.helpers.objectValue(Recurrency) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + const distribution = Distribution.createExistingRecurring( + id, + asset, + executeAt, + recurrency, + amount, + amountType, + snapshotId, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.RECURRING) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).executeAt).toBe(executeAt) + expect((distribution.details as any).recurrency).toBe(recurrency) + expect(distribution.status).toBe(DistributionStatus.SCHEDULED) + expect(distribution.createdAt.getTime()).toBe(distribution.updatedAt.getTime()) + }, + ) + + it("fails when asset is null or undefined", () => { + const id = faker.string.uuid() + const invalidAssets = [null, undefined] as unknown[] + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const recurrency = faker.helpers.objectValue(Recurrency) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createExistingRecurring( + id, + invalidAsset as Asset, + executeAt, + recurrency, + amount, + amountType, + snapshotId, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + + it("fails when executeAt is not provided", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const recurrency = faker.helpers.objectValue(Recurrency) + const invalidDates = [null, undefined] + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidDates.forEach((invalidDate) => { + let error: Error + try { + Distribution.createExistingRecurring( + id, + asset, + invalidDate as Date, + recurrency, + amount, + amountType, + snapshotId, + ) + } catch (e) { + error = e + } + expect(error).toBeInstanceOf(DistributionExecutionDateMissingError) + }) + }) + + it("fails when recurrency is not provided", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const invalidRecurrencies = [null, undefined] + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidRecurrencies.forEach((invalidRecurrency) => { + let error: Error + try { + Distribution.createExistingRecurring( + id, + asset, + executeAt, + invalidRecurrency as Recurrency, + amount, + amountType, + snapshotId, + ) + } catch (e) { + error = e + } + expect(error).toBeInstanceOf(DistributionRecurrencyMissingError) + }) + }) + }) + + describe("createAutomated", () => { + it("should create an Automated Payout Distribution", () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + const distribution = Distribution.createAutomated( + asset, + amount, + amountType, + concept, + snapshotId, + status, + createdAt, + updatedAt, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.AUTOMATED) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).concept).toBe(concept) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it( + "should create an Automated Payout Distribution with default values " + + "when optional parameters are not provided", + () => { + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + const distribution = Distribution.createAutomated(asset, amount, amountType, undefined, snapshotId) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBeDefined() + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.AUTOMATED) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect(distribution.status).toBe(DistributionStatus.SCHEDULED) + expect(distribution.createdAt.getTime()).toBe(distribution.updatedAt.getTime()) + }, + ) + + it("fails when asset is null or undefined", () => { + const invalidAssets = [null, undefined] as unknown[] + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const executeAt = faker.date.future() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createAutomated(invalidAsset as Asset, amount, amountType, undefined, snapshotId) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + }) + + describe("createExistingAutomated", () => { + it("should recreate a Automated Payout Distribution with all provided valid data", () => { + const id = faker.string.uuid() + const asset = AssetUtils.newInstance() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + const concept = faker.string.alpha({ length: 10 }) + + const distribution = Distribution.createExistingAutomated( + id, + asset, + amount, + amountType, + concept, + snapshotId, + status, + createdAt, + updatedAt, + ) + + expect(distribution).toBeInstanceOf(Distribution) + expect(distribution.id).toBe(id) + expect(distribution.asset).toBe(asset) + expect(distribution.details.type).toBe(DistributionType.PAYOUT) + expect((distribution.details as any).snapshotId).toBe(snapshotId) + expect((distribution.details as any).subtype).toBe(PayoutSubtype.AUTOMATED) + expect((distribution.details as any).amount).toBe(amount) + expect((distribution.details as any).amountType).toBe(amountType) + expect((distribution.details as any).concept).toBe(concept) + expect(distribution.status).toBe(status) + expect(distribution.createdAt).toBe(createdAt) + expect(distribution.updatedAt).toBe(updatedAt) + }) + + it("fails when asset is null or undefined for existing automated distribution", () => { + const id = faker.string.uuid() + const snapshotIdValue = faker.string.alpha({ length: 10 }) + const snapshotId = SnapshotId.create(snapshotIdValue) + const invalidAssets = [null, undefined] as unknown[] + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const amountType = faker.helpers.objectValue(AmountType) + const status = faker.helpers.objectValue(DistributionStatus) + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + invalidAssets.forEach((invalidAsset) => { + let error: Error + try { + Distribution.createExistingAutomated( + id, + invalidAsset as Asset, + amount, + amountType, + undefined, + snapshotId, + status, + createdAt, + updatedAt, + ) + } catch (e) { + error = e as Error + } + expect(error).toBeInstanceOf(DistributionAssetIdMissingError) + }) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/model/holder.entity.spec.ts b/apps/mass-payout/backend/test/unit/domain/model/holder.entity.spec.ts new file mode 100644 index 000000000..d05bdd1aa --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/model/holder.entity.spec.ts @@ -0,0 +1,408 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Holder, HolderStatus } from "@domain/model/holder" +import { faker } from "@faker-js/faker" +import { + HolderBatchPayoutIdMissingError, + HolderEvmAddressInvalidError, + HolderHederaAddressInvalidError, + HolderRetryCounterNegativeError, +} from "@domain/errors/holder.error" +import { BaseEntityInvalidDatesError } from "@domain/errors/shared/base-entity-invalid-dates.error" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { BatchPayout } from "@domain/model/batch-payout" + +const fakeHederaId = () => `${faker.number.int()}.${faker.number.int()}.${faker.number.int({ min: 1 })}` + +describe(Holder.name, () => { + describe("create", () => { + it("should create a Holder", () => { + const batchPayout = BatchPayoutUtils.newInstance() + const holderHederaAddress = fakeHederaId() + const holderEvmAddress = faker.finance.ethereumAddress() + const retryCounter = faker.number.int({ min: 0 }) + const status = HolderStatus.PENDING + const nextRetryAt = faker.date.future() + const lastError = faker.lorem.sentence() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + const holder = Holder.create( + batchPayout, + holderHederaAddress, + holderEvmAddress, + retryCounter, + status, + nextRetryAt, + lastError, + amount, + createdAt, + updatedAt, + ) + + expect(holder).toBeInstanceOf(Holder) + expect(holder.id).toBeDefined() + expect(holder.batchPayout).toBe(batchPayout) + expect(holder.holderHederaAddress).toBe(holderHederaAddress) + expect(holder.holderEvmAddress).toBe(holderEvmAddress) + expect(holder.retryCounter).toBe(retryCounter) + expect(holder.status).toBe(status) + expect(holder.nextRetryAt).toBe(nextRetryAt) + expect(holder.lastError).toBe(lastError) + expect(holder.createdAt).toBe(createdAt) + expect(holder.updatedAt).toBe(updatedAt) + }) + + it("should create a Holder as well if createdAt, updatedAt and lastError are not provided", () => { + const batchPayout = BatchPayoutUtils.newInstance() + const holderHederaAddress = fakeHederaId() + const holderEvmAddress = faker.finance.ethereumAddress() + const retryCounter = faker.number.int({ min: 0 }) + const status = HolderStatus.PENDING + const nextRetryAt = faker.date.future() + + const holder = Holder.create( + batchPayout, + holderHederaAddress, + holderEvmAddress, + retryCounter, + status, + nextRetryAt, + ) + + expect(holder).toBeInstanceOf(Holder) + expect(holder.id).toBeDefined() + expect(holder.createdAt.getTime()).toBe(holder.updatedAt.getTime()) + expect(holder.lastError).toBeUndefined() + }) + + it("should fail if createdAt is after updatedAt", () => { + const batchPayout = BatchPayoutUtils.newInstance() + const holderHederaAddress = fakeHederaId() + const holderEvmAddress = faker.finance.ethereumAddress() + const retryCounter = faker.number.int({ min: 0 }) + const status = HolderStatus.PENDING + const nextRetryAt = faker.date.future() + const createdAt = faker.date.future() + const updatedAt = faker.date.past() + let error: Error + + try { + Holder.create( + batchPayout, + holderHederaAddress, + holderEvmAddress, + retryCounter, + status, + nextRetryAt, + undefined, + undefined, + createdAt, + updatedAt, + ) + } catch (e) { + error = e + } + + expect(error).toBeInstanceOf(BaseEntityInvalidDatesError) + }) + + it("fails when batchPayout is empty, null or undefined", () => { + const invalidBatchPayout = [null, undefined] as unknown[] + invalidBatchPayout.forEach((invalidBatchPayout) => { + expect(() => { + Holder.create( + invalidBatchPayout as BatchPayout, + fakeHederaId(), + faker.finance.ethereumAddress(), + 0, + HolderStatus.PENDING, + new Date(), + ) + }).toThrow(HolderBatchPayoutIdMissingError) + }) + }) + + // TODO restore regexp validation after solving problem with hedera address from evm address + it.skip("fails when holderHederaAddress is not in format 0.0.X", () => { + const invalidAddresses = ["1.2", "a.b.c", "0.0", faker.string.uuid()] + invalidAddresses.forEach((invalidAddress) => { + expect(() => { + Holder.create( + BatchPayoutUtils.newInstance(), + invalidAddress, + faker.finance.ethereumAddress(), + 0, + HolderStatus.PENDING, + new Date(), + ) + }).toThrow(HolderHederaAddressInvalidError) + }) + }) + + it("fails when holderEvmAddress is not a valid Ethereum address", () => { + const invalidAddresses = ["1.2", "a.b.c", "0.0", "0xInvalidEthereumAddress"] + invalidAddresses.forEach((invalidAddress) => { + expect(() => { + Holder.create( + BatchPayoutUtils.newInstance(), + fakeHederaId(), + invalidAddress, + 0, + HolderStatus.PENDING, + new Date(), + ) + }).toThrow(HolderEvmAddressInvalidError) + }) + }) + + it("fails when retryCounter is negative", () => { + expect(() => { + Holder.create( + BatchPayoutUtils.newInstance(), + fakeHederaId(), + faker.finance.ethereumAddress(), + -1, + HolderStatus.PENDING, + new Date(), + ) + }).toThrow(HolderRetryCounterNegativeError) + }) + }) + + describe("createExisting", () => { + it("should recreate a Holder with all provided valid data", () => { + const id = faker.string.uuid() + const batchPayout = BatchPayoutUtils.newInstance() + const holderHederaAddress = fakeHederaId() + const holderEvmAddress = faker.finance.ethereumAddress() + const retryCounter = faker.number.int({ min: 0 }) + const status = HolderStatus.PENDING + const nextRetryAt = faker.date.future() + const lastError = faker.lorem.sentence() + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const createdAt = faker.date.past() + const updatedAt = faker.date.future({ refDate: createdAt }) + + const holder = Holder.createExisting( + id, + batchPayout, + holderHederaAddress, + holderEvmAddress, + retryCounter, + status, + nextRetryAt, + lastError, + amount, + createdAt, + updatedAt, + ) + + expect(holder).toBeInstanceOf(Holder) + expect(holder.id).toBe(id) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/model/life-cycle-cash-flow-address.value-object.spec.ts b/apps/mass-payout/backend/test/unit/domain/model/life-cycle-cash-flow-address.value-object.spec.ts new file mode 100644 index 000000000..d72e8f1fe --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/model/life-cycle-cash-flow-address.value-object.spec.ts @@ -0,0 +1,248 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { LifeCycleCashFlowAddress } from "@domain/model/life-cycle-cash-flow-address.value-object" +import { faker } from "@faker-js/faker" +import { fakeHederaAddress } from "@test/shared/utils" +import { + AssetLifeCycleCashFlowEvmAddressInvalidError, + AssetLifeCycleCashFlowHederaAddressInvalidError, +} from "@domain/errors/asset.error" + +describe(LifeCycleCashFlowAddress.name, () => { + describe("create", () => { + it("should create a LifeCycleCashFlowAddress", () => { + const hederaAddress = fakeHederaAddress() + const evmAddress = faker.finance.ethereumAddress() + + const lifeCycleCashFlowAddress = LifeCycleCashFlowAddress.create(hederaAddress, evmAddress) + + expect(lifeCycleCashFlowAddress).toBeInstanceOf(LifeCycleCashFlowAddress) + expect(lifeCycleCashFlowAddress.hederaAddress).toBe(hederaAddress) + expect(lifeCycleCashFlowAddress.evmAddress).toBe(evmAddress) + }) + + it("fails when hederaAddress is not in format 0.0.X", () => { + const invalidHederaAddresses = ["1.2", "a.b.c", "0.0", faker.string.uuid()] + const evmAddress = faker.finance.ethereumAddress() + + invalidHederaAddresses.forEach((invalidHederaAddress) => { + expect(() => { + LifeCycleCashFlowAddress.create(invalidHederaAddress, evmAddress) + }).toThrow(AssetLifeCycleCashFlowHederaAddressInvalidError) + }) + }) + + it("fails when evmAddress is not a valid Ethereum address", () => { + const hederaAddress = fakeHederaAddress() + const invalidEvmAddresses = ["1.2", "a.b.c", "0.0", "0xInvalidEthereumAddress"] + + invalidEvmAddresses.forEach((invalidEvmAddress) => { + expect(() => { + LifeCycleCashFlowAddress.create(hederaAddress, invalidEvmAddress) + }).toThrow(AssetLifeCycleCashFlowEvmAddressInvalidError) + }) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/base-payout.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/base-payout.domain-service.spec.ts new file mode 100644 index 000000000..b853c5ff7 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/base-payout.domain-service.spec.ts @@ -0,0 +1,451 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Test, TestingModule } from "@nestjs/testing" +import { createMock, DeepMocked } from "@golevelup/ts-jest" +import { ExecutePayoutDistributionDomainService } from "@domain/services/execute-payout-distribution.domain-service" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { CreateHoldersDomainService } from "@domain/services/create-holders.domain-service" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" +import { ConfigService } from "@nestjs/config" +import { BatchPayout, BatchPayoutStatus } from "@domain/model/batch-payout" +import { ExecuteDistributionResponse } from "@domain/ports/execute-distribution-response.interface" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { OnChainDistributionRepositoryPort } from "@domain/ports/on-chain-distribution-repository.port" +import { ValidateAssetPauseStateDomainService } from "@domain/services/validate-asset-pause-state.domain-service" +import { HederaService } from "@domain/ports/hedera.port" + +class TestableExecutePayoutDistributionDomainService extends ExecutePayoutDistributionDomainService { + public async testUpdateBatchPayoutTransactionHashes(batchPayout: BatchPayout, transactionId: string) { + return (this as any).updateBatchPayoutTransactionHashes(batchPayout, transactionId) + } + + public async testHandlePayoutResult(batchPayout: BatchPayout, result: ExecuteDistributionResponse) { + return await (this as any).handlePayoutResult(batchPayout, result) + } +} + +describe("BasePayoutDomainService", () => { + let service: TestableExecutePayoutDistributionDomainService + let batchPayoutRepositoryMock: DeepMocked + let createHoldersDomainServiceMock: DeepMocked + let updateBatchPayoutStatusDomainServiceMock: DeepMocked + let updateDistributionStatusDomainServiceMock: DeepMocked + let configServiceMock: DeepMocked + let assetTokenizationStudioServiceMock: DeepMocked + let distributionRepositoryMock: DeepMocked + let onChainDistributionRepositoryMock: DeepMocked + let onChainLifeCycleCashFlowServiceMock: DeepMocked + let validateAssetPauseStateDomainServiceMock: DeepMocked + let hederaServiceMock: DeepMocked + + beforeEach(async () => { + batchPayoutRepositoryMock = createMock() + createHoldersDomainServiceMock = createMock() + updateBatchPayoutStatusDomainServiceMock = createMock() + updateDistributionStatusDomainServiceMock = createMock() + configServiceMock = createMock() + assetTokenizationStudioServiceMock = createMock() + distributionRepositoryMock = createMock() + onChainDistributionRepositoryMock = createMock() + onChainLifeCycleCashFlowServiceMock = createMock() + validateAssetPauseStateDomainServiceMock = createMock() + hederaServiceMock = createMock() + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + TestableExecutePayoutDistributionDomainService, + { + provide: "BatchPayoutRepository", + useValue: batchPayoutRepositoryMock, + }, + { + provide: "AssetTokenizationStudioService", + useValue: assetTokenizationStudioServiceMock, + }, + { + provide: CreateHoldersDomainService, + useValue: createHoldersDomainServiceMock, + }, + { + provide: "UpdateBatchPayoutStatusDomainService", + useValue: updateBatchPayoutStatusDomainServiceMock, + }, + { + provide: "UpdateDistributionStatusDomainService", + useValue: updateDistributionStatusDomainServiceMock, + }, + { + provide: "OnChainDistributionRepositoryPort", + useValue: onChainDistributionRepositoryMock, + }, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useValue: onChainLifeCycleCashFlowServiceMock, + }, + { + provide: ValidateAssetPauseStateDomainService, + useValue: validateAssetPauseStateDomainServiceMock, + }, + { + provide: ConfigService, + useValue: configServiceMock, + }, + { + provide: "HederaService", + useValue: hederaServiceMock, + }, + ], + }).compile() + + service = module.get(TestableExecutePayoutDistributionDomainService) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("updateBatchPayoutTransactionAddresses", () => { + it("should update batch payout with transaction addresses", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ + hederaTransactionId: "0.0.0@0000000000.000000000", + hederaTransactionHash: + "0x000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000", + status: BatchPayoutStatus.IN_PROGRESS, + }) + const transactionId = "0.0.123@1234567890.123456789" + + batchPayoutRepositoryMock.updateBatchPayout.mockResolvedValue(undefined) + hederaServiceMock.getParentHederaTransactionHash.mockResolvedValue({ + hederaTransactionHash: + "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + "1234567890abcdef1234567890abcdef", + isFromMirrorNode: true, + }) + + await service.testUpdateBatchPayoutTransactionHashes(originalBatchPayout, transactionId) + + expect(batchPayoutRepositoryMock.updateBatchPayout).toHaveBeenCalledWith( + expect.objectContaining({ + hederaTransactionId: transactionId, + hederaTransactionHash: expect.stringMatching(/^0x[a-fA-F0-9]{96}$/), + }), + ) + }) + + it("should handle repository errors gracefully", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ + status: BatchPayoutStatus.IN_PROGRESS, + }) + const transactionId = "0.0.123@1234567890.123456789" + const consoleErrorSpy = jest.spyOn(console, "error").mockImplementation() + + batchPayoutRepositoryMock.updateBatchPayout.mockRejectedValue(new Error("Database error")) + hederaServiceMock.getParentHederaTransactionHash.mockResolvedValue({ + hederaTransactionHash: + "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + "1234567890abcdef1234567890abcdef", + isFromMirrorNode: true, + }) + + await expect( + service.testUpdateBatchPayoutTransactionHashes(originalBatchPayout, transactionId), + ).resolves.not.toThrow() + + expect(consoleErrorSpy).toHaveBeenCalledWith( + expect.stringContaining(`Failed to update transaction hashes for BatchPayout ${originalBatchPayout.id}`), + expect.any(Error), + ) + + consoleErrorSpy.mockRestore() + }) + }) + + describe("handlePayoutResult", () => { + it("should update transaction addresses when transactionId is provided", async () => { + const batchPayout = BatchPayoutUtils.newInstance({ + hederaTransactionId: "0.0.0@0000000000.000000000", + hederaTransactionHash: + "0x000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000", + status: BatchPayoutStatus.IN_PROGRESS, + }) + const executeDistributionResponse: ExecuteDistributionResponse = { + failed: [], + succeeded: ["0x123", "0x456"], + paidAmount: ["100", "200"], + transactionId: "0.0.123@1234567890.123456789", + } + + createHoldersDomainServiceMock.execute.mockResolvedValue(undefined) + batchPayoutRepositoryMock.updateBatchPayout.mockResolvedValue(undefined) + hederaServiceMock.getParentHederaTransactionHash.mockResolvedValue({ + hederaTransactionHash: + "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef" + "1234567890abcdef1234567890abcdef", + isFromMirrorNode: true, + }) + const spy = jest.spyOn(service["createHoldersDomainService"], "execute") + + await service.testHandlePayoutResult(batchPayout, executeDistributionResponse) + + expect(spy).toHaveBeenCalledWith( + batchPayout, + executeDistributionResponse.failed, + executeDistributionResponse.succeeded, + executeDistributionResponse.paidAmount, + ) + expect(batchPayoutRepositoryMock.updateBatchPayout).toHaveBeenCalledWith( + expect.objectContaining({ + hederaTransactionId: executeDistributionResponse.transactionId, + hederaTransactionHash: expect.stringMatching(/^0x[a-fA-F0-9]{96}$/), + }), + ) + }) + + it("should not update transaction addresses when transactionId is not provided", async () => { + const batchPayout = BatchPayoutUtils.newInstance({ + status: BatchPayoutStatus.IN_PROGRESS, + }) + const executeDistributionResponse: ExecuteDistributionResponse = { + failed: [], + succeeded: ["0x123", "0x456"], + paidAmount: ["100", "200"], + transactionId: "", + } + + createHoldersDomainServiceMock.execute.mockResolvedValue(undefined) + + const result = await service.testHandlePayoutResult(batchPayout, executeDistributionResponse) + + expect(batchPayoutRepositoryMock.updateBatchPayout).not.toHaveBeenCalled() + + expect(result).toBe(batchPayout) + }) + + it("should not update transaction addresses when transactionId is null", async () => { + const batchPayout = BatchPayoutUtils.newInstance({ + status: BatchPayoutStatus.IN_PROGRESS, + }) + const executeDistributionResponse: ExecuteDistributionResponse = { + failed: [], + succeeded: ["0x123", "0x456"], + paidAmount: ["100", "200"], + transactionId: null as any, + } + + createHoldersDomainServiceMock.execute.mockResolvedValue(undefined) + + const result = await service.testHandlePayoutResult(batchPayout, executeDistributionResponse) + + expect(batchPayoutRepositoryMock.updateBatchPayout).not.toHaveBeenCalled() + + expect(result).toBe(batchPayout) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/create-holders.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/create-holders.domain-service.spec.ts new file mode 100644 index 000000000..6cb5a32f0 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/create-holders.domain-service.spec.ts @@ -0,0 +1,324 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Test, TestingModule } from "@nestjs/testing" +import { faker } from "@faker-js/faker" +import { createMock, DeepMocked } from "@golevelup/ts-jest" +import { CreateHoldersDomainService } from "@domain/services/create-holders.domain-service" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { HolderStatus } from "@domain/model/holder" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { fakeHederaAddress } from "@test/shared/utils" +import { HederaService } from "@domain/ports/hedera.port" + +describe(CreateHoldersDomainService.name, () => { + let createHoldersDomainService: CreateHoldersDomainService + let holderRepositoryMock: DeepMocked + let hederaServiceMock: DeepMocked + + beforeAll(async () => { + holderRepositoryMock = createMock() + hederaServiceMock = createMock() + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + CreateHoldersDomainService, + { + provide: "HolderRepository", + useValue: holderRepositoryMock, + }, + { + provide: "HederaService", + useValue: hederaServiceMock, + }, + ], + }).compile() + + createHoldersDomainService = module.get(CreateHoldersDomainService) + }) + + beforeEach(async () => { + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should create holders", async () => { + const batchPayout = BatchPayoutUtils.newInstance() + const failedHolderNumber = faker.number.int({ min: 2, max: 4 }) + const succeededHolderNumber = faker.number.int({ min: 2, max: 4 }) + const failedAddresses = Array.from({ length: failedHolderNumber }, () => faker.finance.ethereumAddress()) + const succeededAddresses = Array.from({ length: succeededHolderNumber }, () => faker.finance.ethereumAddress()) + const hederaFailedAddresses = Array.from({ length: failedHolderNumber }, () => fakeHederaAddress()) + const hederaSucceededAddresses = Array.from({ length: succeededHolderNumber }, () => fakeHederaAddress()) + const paidAmounts = Array.from({ length: succeededHolderNumber }, () => + faker.number.int({ min: 1, max: 1000 }).toString(), + ) + failedAddresses.forEach((_, index) => { + hederaServiceMock.getHederaAddressFromEvm.mockResolvedValueOnce(hederaFailedAddresses[index]) + }) + succeededAddresses.forEach((_, index) => { + hederaServiceMock.getHederaAddressFromEvm.mockResolvedValueOnce(hederaSucceededAddresses[index]) + }) + holderRepositoryMock.saveHolders.mockImplementation((holders) => Promise.resolve(holders)) + + const result = await createHoldersDomainService.execute( + batchPayout, + failedAddresses, + succeededAddresses, + paidAmounts, + ) + const failedHolders = result.filter((failedHolder) => failedHolder.status === HolderStatus.FAILED) + const succeededHolders = result.filter((failedHolder) => failedHolder.status === HolderStatus.SUCCESS) + + expect(hederaServiceMock.getHederaAddressFromEvm).toHaveBeenCalledTimes( + failedHolderNumber + succeededHolderNumber, + ) + failedAddresses.forEach((address, index) => { + expect(hederaServiceMock.getHederaAddressFromEvm).toHaveBeenNthCalledWith(index + 1, address) + }) + succeededAddresses.forEach((address, index) => { + expect(hederaServiceMock.getHederaAddressFromEvm).toHaveBeenNthCalledWith( + failedHolderNumber + index + 1, + address, + ) + }) + expect(holderRepositoryMock.saveHolders).toHaveBeenCalledTimes(1) + expect(result).toHaveLength(failedHolderNumber + succeededHolderNumber) + expect(failedHolders).toHaveLength(failedHolderNumber) + expect(succeededHolders).toHaveLength(succeededHolderNumber) + + failedHolders.forEach((holder, index) => { + expect(holder.batchPayout).toBe(batchPayout) + expect(holder.holderHederaAddress).toBe(hederaFailedAddresses[index]) + expect(holder.holderEvmAddress).toBe(failedAddresses[index]) + expect(holder.retryCounter).toBe(0) + expect(holder.nextRetryAt).toBeInstanceOf(Date) + expect(holder.nextRetryAt.getTime()).toBeGreaterThan(Date.now()) + expect(holder.lastError).toBe("Payment execution failed") + }) + succeededHolders.forEach((holder, index) => { + expect(holder.batchPayout).toBe(batchPayout) + expect(holder.holderHederaAddress).toBe(hederaSucceededAddresses[index]) + expect(holder.holderEvmAddress).toBe(succeededAddresses[index]) + expect(holder.retryCounter).toBe(0) + expect(holder.nextRetryAt).toBeUndefined() + expect(holder.lastError).toBeUndefined() + expect(holder.amount).toBe(paidAmounts[index]) + }) + }) + + it("should create failed holders with empty array", async () => { + const distribution = DistributionUtils.newInstance() + const batchPayout = BatchPayoutUtils.newInstance({ distribution }) + holderRepositoryMock.saveHolders.mockResolvedValue([]) + + const result = await createHoldersDomainService.execute(batchPayout, [], [], []) + + expect(hederaServiceMock.getHederaAddressFromEvm).not.toHaveBeenCalled() + expect(holderRepositoryMock.saveHolders).toHaveBeenCalledWith([]) + expect(result).toHaveLength(0) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/execute-corporate-action-distribution.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/execute-corporate-action-distribution.domain-service.spec.ts new file mode 100644 index 000000000..4d96d0ef3 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/execute-corporate-action-distribution.domain-service.spec.ts @@ -0,0 +1,648 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AmountType, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { HederaService } from "@domain/ports/hedera.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { OnChainDistributionRepositoryPort } from "@domain/ports/on-chain-distribution-repository.port" +import { CreateHoldersDomainService } from "@domain/services/create-holders.domain-service" +import { ExecuteCorporateActionDistributionDomainService } from "@domain/services/execute-corporate-action-distribution.domain-service" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" +import { ValidateAssetPauseStateDomainService } from "@domain/services/validate-asset-pause-state.domain-service" +import { faker } from "@faker-js/faker/." +import { createMock } from "@golevelup/ts-jest" +import { ConfigService } from "@nestjs/config" +import { Test, TestingModule } from "@nestjs/testing" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { AssetUtils } from "@test/shared/asset.utils" +import { AssetPausedError } from "@domain/errors/asset.error" +import { DistributionNotCorporateActionError } from "@domain/errors/distribution.error" + +describe(ExecuteCorporateActionDistributionDomainService.name, () => { + let executeCorporateActionDistributionDomainService: ExecuteCorporateActionDistributionDomainService + const assetRepositoryMock = createMock() + const batchPayoutRepositoryMock = createMock() + const assetTokenizationStudioServiceMock = createMock() + const createHoldersDomainServiceMock = createMock() + const updateBatchPayoutStatusDomainServiceMock = createMock() + const validateAssetPauseStateDomainServiceMock = createMock() + const configServiceMock = createMock() + const hederaServiceMock = createMock() + const onchainDistributionRepositoryMock = createMock() + const onChainLifeCycleCashFlowServiceMock = createMock() + const DEFAULT_BATCH_SIZE = 100 + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ExecuteCorporateActionDistributionDomainService, + { + provide: "AssetRepository", + useValue: assetRepositoryMock, + }, + { + provide: "BatchPayoutRepository", + useValue: batchPayoutRepositoryMock, + }, + { + provide: "AssetTokenizationStudioService", + useValue: assetTokenizationStudioServiceMock, + }, + { + provide: CreateHoldersDomainService, + useValue: createHoldersDomainServiceMock, + }, + { + provide: "UpdateBatchPayoutStatusDomainService", + useValue: updateBatchPayoutStatusDomainServiceMock, + }, + { + provide: ValidateAssetPauseStateDomainService, + useValue: validateAssetPauseStateDomainServiceMock, + }, + { + provide: "OnChainDistributionRepositoryPort", + useValue: onchainDistributionRepositoryMock, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useValue: onChainLifeCycleCashFlowServiceMock, + }, + { + provide: ConfigService, + useValue: configServiceMock, + }, + { + provide: "HederaService", + useValue: hederaServiceMock, + }, + ], + }).compile() + configServiceMock.get.mockReturnValue(DEFAULT_BATCH_SIZE) + executeCorporateActionDistributionDomainService = module.get( + ExecuteCorporateActionDistributionDomainService, + ) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should throw error if distribution is not a corporate action", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + snapshotId, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).rejects.toThrow( + DistributionNotCorporateActionError, + ) + }) + + it("should call createBatchPayouts and processBatchPayouts for corporate action distribution", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + const expectedHoldersCount = 150 + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + configServiceMock.get.mockReturnValueOnce(100) + onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId.mockResolvedValueOnce(expectedHoldersCount) + createHoldersDomainServiceMock.execute.mockResolvedValue(undefined) + updateBatchPayoutStatusDomainServiceMock.execute.mockResolvedValue(undefined) + + await executeCorporateActionDistributionDomainService.execute(distribution) + + expect(batchPayoutRepositoryMock.saveBatchPayout).toHaveBeenCalled() + }) + + it("should throw error if batch payouts already exist for distribution", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + const existingBatchPayout = {} as any + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([existingBatchPayout]) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).rejects.toThrow( + `BatchPayouts already exist for distribution ${distribution.id}`, + ) + }) + }) + + describe("getHoldersCount", () => { + it("should return holders count for corporate action distribution", async () => { + const distribution = DistributionUtils.newInstance() + const expectedCount = 150 + + onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId.mockResolvedValue(expectedCount) + + const result = await (executeCorporateActionDistributionDomainService as any).getHoldersCount(distribution) + + expect(result).toBe(expectedCount) + }) + + it("should throw error if no holders found", async () => { + const distribution = DistributionUtils.newInstance() + + onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId.mockResolvedValue(0) + + await expect( + (executeCorporateActionDistributionDomainService as any).getHoldersCount(distribution), + ).rejects.toThrow(`No holders found for distribution ${distribution.id}`) + }) + + it("should throw error for non-corporate action distribution", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + + await expect( + (executeCorporateActionDistributionDomainService as any).getHoldersCount(distribution), + ).rejects.toThrow(DistributionNotCorporateActionError) + }) + }) + + describe("executeHederaCall", () => { + it("should call LifeCycleSDK with correct parameters", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + const mockBatchPayout = { + distribution, + holdersNumber: 50, + } as any + const pageIndex = 1 + const expectedResponse = { failed: faker.string.alphanumeric({ length: 10 }) } as any + onChainLifeCycleCashFlowServiceMock.executeDistribution.mockResolvedValue(expectedResponse) + + const result = await (executeCorporateActionDistributionDomainService as any).executeHederaCall( + mockBatchPayout, + pageIndex, + ) + + if (distribution.details.type === DistributionType.CORPORATE_ACTION) { + expect(onChainLifeCycleCashFlowServiceMock.executeDistribution).toHaveBeenCalledWith( + distribution.asset.lifeCycleCashFlowHederaAddress, + distribution.asset.hederaTokenAddress, + Number(distribution.details.corporateActionId.value), + pageIndex, + mockBatchPayout.holdersNumber, + ) + } + expect(result).toBe(expectedResponse) + }) + + it("should throw error for non-corporate action distribution", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + snapshotId, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + const mockBatchPayout = { + distribution, + holdersNumber: 50, + } as any + const pageIndex = 1 + + await expect( + (executeCorporateActionDistributionDomainService as any).executeHederaCall(mockBatchPayout, pageIndex), + ).rejects.toThrow(DistributionNotCorporateActionError) + + expect(onChainLifeCycleCashFlowServiceMock.executeDistribution).not.toHaveBeenCalled() + }) + + it("should propagate errors from onChainLifeCycleCashFlowService", async () => { + const distribution = DistributionUtils.newInstance() + const mockBatchPayout = { + distribution, + holdersNumber: 50, + } as any + const pageIndex = 1 + const error = new Error("LifeCycle service error") + + onChainLifeCycleCashFlowServiceMock.executeDistribution.mockRejectedValue(error) + + await expect( + (executeCorporateActionDistributionDomainService as any).executeHederaCall(mockBatchPayout, pageIndex), + ).rejects.toThrow("LifeCycle service error") + }) + }) + + describe("error handling", () => { + it("should propagate errors from onchain repository", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + const error = new Error("Blockchain error") + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId.mockRejectedValue(error) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).rejects.toThrow( + "Blockchain error", + ) + }) + + it("should propagate errors from batch payout repository", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + const error = new Error("Database error") + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockRejectedValue(error) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).rejects.toThrow( + "Database error", + ) + }) + + it("should skip execution when execution date has not been reached", async () => { + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.future(), + }, + }) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).resolves.toBeUndefined() + + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).not.toHaveBeenCalled() + }) + + it("should throw AssetPausedError when asset is paused according to smart contract", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockRejectedValue( + new AssetPausedError(distribution.asset.name, distribution.asset.hederaTokenAddress), + ) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).rejects.toThrow( + new AssetPausedError(distribution.asset.name, distribution.asset.hederaTokenAddress), + ) + + expect(validateAssetPauseStateDomainServiceMock.validateDomainPauseState).toHaveBeenCalledWith( + distribution.asset, + distribution.id, + ) + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).not.toHaveBeenCalled() + expect(onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId).not.toHaveBeenCalled() + }) + + it("should execute when asset is not paused according to smart contract", async () => { + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId.mockResolvedValue(10) + onChainLifeCycleCashFlowServiceMock.executeDistribution.mockResolvedValue({} as any) + + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).resolves.toBeUndefined() + + expect(validateAssetPauseStateDomainServiceMock.validateDomainPauseState).toHaveBeenCalledWith( + distribution.asset, + distribution.id, + ) + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).toHaveBeenCalled() + expect(onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId).toHaveBeenCalled() + }) + + it("should execute when execution date is today regardless of time", async () => { + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId.mockResolvedValue(10) + onChainLifeCycleCashFlowServiceMock.executeDistribution.mockResolvedValue({} as any) + + const todayWithFutureTime = new Date() + todayWithFutureTime.setHours(23, 59, 59, 999) + + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: todayWithFutureTime, + }, + }) + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).resolves.toBeUndefined() + + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).toHaveBeenCalled() + expect(onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId).toHaveBeenCalled() + }) + + it("should sync asset pause state when DLT shows paused but backend shows unpaused", async () => { + const unpausedAsset = AssetUtils.newInstance({ isPaused: false }) + const distribution = DistributionUtils.newInstance({ + asset: unpausedAsset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockRejectedValue( + new AssetPausedError(distribution.asset.name, distribution.asset.hederaTokenAddress), + ) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).rejects.toThrow( + new AssetPausedError(distribution.asset.name, distribution.asset.hederaTokenAddress), + ) + + expect(validateAssetPauseStateDomainServiceMock.validateDomainPauseState).toHaveBeenCalledWith( + distribution.asset, + distribution.id, + ) + }) + + it("should sync asset pause state when DLT shows unpaused but backend shows paused", async () => { + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + onchainDistributionRepositoryMock.getHoldersCountForCorporateActionId.mockResolvedValue(10) + onChainLifeCycleCashFlowServiceMock.executeDistribution.mockResolvedValue({} as any) + + const pausedAsset = AssetUtils.newInstance({ isPaused: true }) + const distribution = DistributionUtils.newInstance({ + asset: pausedAsset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: CorporateActionId.create(faker.string.alpha()), + executionDate: faker.date.past(), + }, + }) + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + + await expect(executeCorporateActionDistributionDomainService.execute(distribution)).resolves.toBeUndefined() + + expect(validateAssetPauseStateDomainServiceMock.validateDomainPauseState).toHaveBeenCalledWith( + distribution.asset, + distribution.id, + ) + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).toHaveBeenCalled() + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/execute-payout-distribution.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/execute-payout-distribution.domain-service.spec.ts new file mode 100644 index 000000000..895474430 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/execute-payout-distribution.domain-service.spec.ts @@ -0,0 +1,668 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AmountType, DistributionType, PayoutSubtype, Recurrency } from "@domain/model/distribution" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { HederaService } from "@domain/ports/hedera.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { OnChainDistributionRepositoryPort } from "@domain/ports/on-chain-distribution-repository.port" +import { CreateHoldersDomainService } from "@domain/services/create-holders.domain-service" +import { ExecutePayoutDistributionDomainService } from "@domain/services/execute-payout-distribution.domain-service" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" +import { ValidateAssetPauseStateDomainService } from "@domain/services/validate-asset-pause-state.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { ConfigService } from "@nestjs/config" +import { Test, TestingModule } from "@nestjs/testing" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { DistributionNotPayoutError } from "@domain/errors/distribution.error" +import { AssetPausedError } from "@domain/errors/asset.error" + +describe(ExecutePayoutDistributionDomainService.name, () => { + let executePayoutDistributionDomainService: ExecutePayoutDistributionDomainService + const batchPayoutRepositoryMock = createMock() + const assetTokenizationStudioServiceMock = createMock() + const createHoldersDomainServiceMock = createMock() + const updateBatchPayoutStatusDomainServiceMock = createMock() + const updateDistributionStatusDomainServiceMock = createMock() + const onchainDistributionRepositoryMock = createMock() + const distributionRepositoryMock = createMock() + const onChainLifeCycleCashFlowServiceMock = createMock() + const validateAssetPauseStateDomainServiceMock = createMock() + const configMock = createMock() + const hederaServiceMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ExecutePayoutDistributionDomainService, + { + provide: "BatchPayoutRepository", + useValue: batchPayoutRepositoryMock, + }, + { + provide: "AssetTokenizationStudioService", + useValue: assetTokenizationStudioServiceMock, + }, + { + provide: CreateHoldersDomainService, + useValue: createHoldersDomainServiceMock, + }, + { + provide: "UpdateBatchPayoutStatusDomainService", + useValue: updateBatchPayoutStatusDomainServiceMock, + }, + { + provide: "UpdateDistributionStatusDomainService", + useValue: updateDistributionStatusDomainServiceMock, + }, + { + provide: "OnChainDistributionRepositoryPort", + useValue: onchainDistributionRepositoryMock, + }, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useValue: onChainLifeCycleCashFlowServiceMock, + }, + { + provide: ValidateAssetPauseStateDomainService, + useValue: validateAssetPauseStateDomainServiceMock, + }, + { + provide: ConfigService, + useValue: configMock, + }, + { + provide: "HederaService", + useValue: hederaServiceMock, + }, + ], + }).compile() + + executePayoutDistributionDomainService = module.get( + ExecutePayoutDistributionDomainService, + ) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should throw error if distribution is not a payout distribution", async () => { + const corporateActionId = CorporateActionId.create(faker.string.numeric()) + const executionDate = faker.date.future() + const distribution = DistributionUtils.newInstance({ + details: { type: DistributionType.CORPORATE_ACTION, corporateActionId, executionDate }, + }) + + await expect(executePayoutDistributionDomainService.execute(distribution)).rejects.toThrow( + DistributionNotPayoutError, + ) + }) + + it("should throw error if asset is paused", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + + const pausedError = new AssetPausedError(distribution.asset.id, distribution.id) + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockRejectedValue(pausedError) + + await expect(executePayoutDistributionDomainService.execute(distribution)).rejects.toThrow(AssetPausedError) + expect(validateAssetPauseStateDomainServiceMock.validateDomainPauseState).toHaveBeenCalledWith( + distribution.asset, + distribution.id, + ) + }) + + it("should validate asset pause state before proceeding with payout", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + onchainDistributionRepositoryMock.getHoldersCountForSnapshotId.mockResolvedValue(150) + batchPayoutRepositoryMock.saveBatchPayout.mockResolvedValue(undefined) + assetTokenizationStudioServiceMock.takeSnapshot.mockResolvedValueOnce(Number(snapshotId.value)) + distributionRepositoryMock.updateDistribution.mockResolvedValue(distribution) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + updateDistributionStatusDomainServiceMock.setDistributionStatusToInProgress.mockReturnValue(distribution) + configMock.get.mockReturnValueOnce(100) + + await executePayoutDistributionDomainService.execute(distribution) + + expect(validateAssetPauseStateDomainServiceMock.validateDomainPauseState).toHaveBeenCalledWith( + distribution.asset, + distribution.id, + ) + expect(batchPayoutRepositoryMock.saveBatchPayout).toHaveBeenCalled() + }) + + it("should call createBatchPayouts and processBatchPayouts for manual distribution", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + onchainDistributionRepositoryMock.getHoldersCountForSnapshotId.mockResolvedValue(150) + batchPayoutRepositoryMock.saveBatchPayout.mockResolvedValue(undefined) + assetTokenizationStudioServiceMock.takeSnapshot.mockResolvedValueOnce(Number(snapshotId.value)) + distributionRepositoryMock.updateDistribution.mockResolvedValue(distribution) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + updateDistributionStatusDomainServiceMock.setDistributionStatusToInProgress.mockReturnValue(distribution) + configMock.get.mockReturnValueOnce(100) + + await executePayoutDistributionDomainService.execute(distribution) + + expect(batchPayoutRepositoryMock.saveBatchPayout).toHaveBeenCalled() + }) + + it("should create next recurring distribution for recurring payout", async () => { + jest.useFakeTimers() + + const executeAt = faker.date.future() + const snapshotId = SnapshotId.create(faker.string.numeric()) + + jest.setSystemTime(new Date(executeAt.getTime() - 24 * 60 * 60 * 1000)) + + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.RECURRING, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + executeAt, + recurrency: Recurrency.MONTHLY, + }, + }) + + jest.setSystemTime(new Date(executeAt.getTime() + 24 * 60 * 60 * 1000)) + + validateAssetPauseStateDomainServiceMock.validateDomainPauseState.mockResolvedValue(undefined) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + onchainDistributionRepositoryMock.getHoldersCountForSnapshotId.mockResolvedValue(150) + batchPayoutRepositoryMock.saveBatchPayout.mockResolvedValue(undefined) + assetTokenizationStudioServiceMock.takeSnapshot.mockResolvedValueOnce(Number(snapshotId.value)) + distributionRepositoryMock.updateDistribution.mockResolvedValue(distribution) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + updateDistributionStatusDomainServiceMock.setDistributionStatusToInProgress.mockReturnValue(distribution) + configMock.get.mockReturnValueOnce(100) + + await executePayoutDistributionDomainService.execute(distribution) + + expect(distributionRepositoryMock.saveDistribution).toHaveBeenCalled() + expect(batchPayoutRepositoryMock.saveBatchPayout).toHaveBeenCalled() + jest.useRealTimers() + }) + + it("should throw error if batch payouts already exist for distribution", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + + const existingBatchPayout = {} as any + assetTokenizationStudioServiceMock.takeSnapshot.mockResolvedValueOnce(Number(snapshotId.value)) + distributionRepositoryMock.updateDistribution.mockResolvedValue(distribution) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + updateDistributionStatusDomainServiceMock.setDistributionStatusToInProgress.mockReturnValue(distribution) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([existingBatchPayout]) + + await expect(executePayoutDistributionDomainService.execute(distribution)).rejects.toThrow( + `BatchPayouts already exist for distribution ${distribution.id}`, + ) + }) + }) + + describe("getHoldersCount", () => { + it("should return holders count for manual distribution", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + const expectedCount = 150 + onchainDistributionRepositoryMock.getHoldersCountForSnapshotId.mockResolvedValue(expectedCount) + + const result = await (executePayoutDistributionDomainService as any).getHoldersCount(distribution) + + expect(result).toBe(expectedCount) + }) + + it("should throw error if no holders found", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + onchainDistributionRepositoryMock.getHoldersCountForSnapshotId.mockResolvedValue(0) + + await expect((executePayoutDistributionDomainService as any).getHoldersCount(distribution)).rejects.toThrow( + `No holders found for distribution ${distribution.id}`, + ) + }) + + it("should throw error for non-manual distribution", async () => { + const corporateActionId = CorporateActionId.create(faker.string.numeric()) + const executionDate = faker.date.future() + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId, + executionDate, + }, + }) + + await expect((executePayoutDistributionDomainService as any).getHoldersCount(distribution)).rejects.toThrow( + DistributionNotPayoutError, + ) + }) + }) + + describe("executeHederaCall", () => { + it("should call LifeCycleSDK executeAmountSnapshot method with correct parameters", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + snapshotId: SnapshotId.create(faker.string.alpha()), + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + const mockBatchPayout = { + distribution, + holdersNumber: 50, + } as any + const pageIndex = 1 + const expectedResponse = { failed: faker.string.alphanumeric({ length: 10 }) } as any + onChainLifeCycleCashFlowServiceMock.executeAmountSnapshot.mockResolvedValue(expectedResponse) + + const result = await (executePayoutDistributionDomainService as any).executeHederaCall(mockBatchPayout, pageIndex) + + if (distribution.details.type === DistributionType.PAYOUT) { + expect(onChainLifeCycleCashFlowServiceMock.executeAmountSnapshot).toHaveBeenCalledWith( + distribution.asset.lifeCycleCashFlowHederaAddress, + distribution.asset.hederaTokenAddress, + Number(distribution.details.snapshotId.value), + pageIndex, + mockBatchPayout.holdersNumber, + distribution.details.amount, + ) + } + expect(result).toBe(expectedResponse) + }) + + it("should call LifeCycleSDK executePercentageSnapshot method with correct parameters", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + snapshotId: SnapshotId.create(faker.string.alpha()), + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.PERCENTAGE, + }, + }) + const mockBatchPayout = { + distribution, + holdersNumber: 50, + } as any + const pageIndex = 1 + const expectedResponse = { failed: faker.string.alphanumeric({ length: 10 }) } as any + onChainLifeCycleCashFlowServiceMock.executePercentageSnapshot.mockResolvedValue(expectedResponse) + + const result = await (executePayoutDistributionDomainService as any).executeHederaCall(mockBatchPayout, pageIndex) + + if (distribution.details.type === DistributionType.PAYOUT) { + expect(onChainLifeCycleCashFlowServiceMock.executePercentageSnapshot).toHaveBeenCalledWith( + distribution.asset.lifeCycleCashFlowHederaAddress, + distribution.asset.hederaTokenAddress, + Number(distribution.details.snapshotId.value), + pageIndex, + mockBatchPayout.holdersNumber, + distribution.details.amount, + ) + expect(result).toBe(expectedResponse) + } + }) + + it("should throw error for non-manual distribution", async () => { + const corporateActionId = CorporateActionId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { type: DistributionType.CORPORATE_ACTION, corporateActionId, executionDate: faker.date.future() }, + }) + const mockBatchPayout = { + distribution, + holdersNumber: 50, + } as any + const pageIndex = 1 + + await expect( + (executePayoutDistributionDomainService as any).executeHederaCall(mockBatchPayout, pageIndex), + ).rejects.toThrow(DistributionNotPayoutError) + + expect(onChainLifeCycleCashFlowServiceMock.executeDistribution).not.toHaveBeenCalled() + }) + + it("should propagate errors from onChainLifeCycleCashFlowService", async () => { + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + snapshotId: SnapshotId.create(faker.string.alpha()), + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + const mockBatchPayout = { + distribution, + holdersNumber: 50, + } as any + const pageIndex = 1 + const error = new Error("LifeCycle service error") + + onChainLifeCycleCashFlowServiceMock.executeAmountSnapshot.mockRejectedValue(error) + + await expect( + (executePayoutDistributionDomainService as any).executeHederaCall(mockBatchPayout, pageIndex), + ).rejects.toThrow("LifeCycle service error") + }) + }) + + describe("error handling", () => { + it("should propagate errors from onchain repository", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + + const error = new Error("Blockchain error") + assetTokenizationStudioServiceMock.takeSnapshot.mockResolvedValueOnce(Number(snapshotId.value)) + distributionRepositoryMock.updateDistribution.mockResolvedValue(distribution) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + updateDistributionStatusDomainServiceMock.setDistributionStatusToInProgress.mockReturnValue(distribution) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + onchainDistributionRepositoryMock.getHoldersCountForSnapshotId.mockRejectedValue(error) + + await expect(executePayoutDistributionDomainService.execute(distribution)).rejects.toThrow("Blockchain error") + }) + + it("should propagate errors from batch payout repository", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + + const error = new Error("Database error") + assetTokenizationStudioServiceMock.takeSnapshot.mockResolvedValueOnce(Number(snapshotId.value)) + distributionRepositoryMock.updateDistribution.mockResolvedValue(distribution) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + updateDistributionStatusDomainServiceMock.setDistributionStatusToInProgress.mockReturnValue(distribution) + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockRejectedValue(error) + + await expect(executePayoutDistributionDomainService.execute(distribution)).rejects.toThrow("Database error") + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/import-asset.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/import-asset.domain-service.spec.ts new file mode 100644 index 000000000..c85aa34a1 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/import-asset.domain-service.spec.ts @@ -0,0 +1,526 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ConfigKeys } from "@config/config-keys" +import { AssetHederaTokenAddressAlreadyExistsError } from "@domain/errors/asset.error" +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { LifeCycleCashFlowAddress } from "@domain/model/life-cycle-cash-flow-address.value-object" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { AssetTokenizationStudioService } from "@domain/ports/asset-tokenization-studio.port" +import { GetAssetInfoResponse } from "@domain/ports/get-asset-info-response.interface" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { ImportAssetDomainService } from "@domain/services/import-asset.domain-service" +import { SyncFromOnChainDomainService } from "@domain/services/sync-from-onchain.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { ConfigService } from "@nestjs/config" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" +import { HederaService } from "@domain/ports/hedera.port" + +describe(ImportAssetDomainService.name, () => { + let importAssetDomainService: ImportAssetDomainService + const assetRepositoryMock = createMock() + const onChainLifeCycleCashFlowServiceMock = createMock() + const assetTokenizationStudioServiceMock = createMock() + const hederaServiceMock = createMock() + const configServiceMock = createMock() + const syncFromOnChainDomainServiceMock = createMock() + const mockDate = faker.date.future() + jest.spyOn(global, "Date").mockImplementation(() => mockDate) + + const mockUUID = "1cb83c9e-ad81-424a-9029-5dc861308aa3" + jest.spyOn(crypto, "randomUUID").mockImplementation(() => mockUUID) + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ImportAssetDomainService, + { + provide: "AssetRepository", + useValue: assetRepositoryMock, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useValue: onChainLifeCycleCashFlowServiceMock, + }, + { + provide: "AssetTokenizationStudioService", + useValue: assetTokenizationStudioServiceMock, + }, + { + provide: "HederaService", + useValue: hederaServiceMock, + }, + { + provide: ConfigService, + useValue: configServiceMock, + }, + { + provide: SyncFromOnChainDomainService, + useValue: syncFromOnChainDomainServiceMock, + }, + ], + }).compile() + + importAssetDomainService = module.get(ImportAssetDomainService) + + jest.clearAllMocks() + + onChainLifeCycleCashFlowServiceMock.isPaused.mockResolvedValue(false) + }) + + describe("Import Asset", () => { + it("should import asset successfully with lifeCycleCashFlow addresses and asset type from syncAsset", async () => { + const name = "Test Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaUsdcAddress = fakeHederaAddress() + const lifeCycleCashFlowHederaAddress = fakeHederaAddress() + const lifeCycleCashFlowEvmAddress = faker.finance.ethereumAddress() + const symbol = faker.string.alpha({ length: 3 }) + const getAssetInfoResponse: GetAssetInfoResponse = { + hederaTokenAddress: hederaTokenAddress, + name: name, + symbol: symbol, + assetType: AssetType.EQUITY, + } + const lifeCycleCashFlowAddress = LifeCycleCashFlowAddress.create( + lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress, + ) + const initialAsset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol) + const assetWithLifeCycleCashFlow = initialAsset.withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + assetRepositoryMock.getAssetByName.mockResolvedValue(undefined) + assetRepositoryMock.getAssetByHederaTokenAddress.mockResolvedValue(undefined) + configServiceMock.get.mockReturnValue(hederaUsdcAddress) + hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(evmTokenAddress) + assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(getAssetInfoResponse) + onChainLifeCycleCashFlowServiceMock.deployContract.mockResolvedValue(lifeCycleCashFlowAddress) + assetRepositoryMock.saveAsset.mockResolvedValue(assetWithLifeCycleCashFlow) + + const result = await importAssetDomainService.importAsset(hederaTokenAddress) + + expect(configServiceMock.get).toHaveBeenCalledWith(ConfigKeys.HEDERA_USDC_ADDRESS) + expect(hederaServiceMock.getEvmAddressFromHedera).toHaveBeenCalledWith(hederaTokenAddress) + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalledWith(hederaTokenAddress) + expect(onChainLifeCycleCashFlowServiceMock.isPaused).toHaveBeenCalledWith(hederaTokenAddress) + expect(onChainLifeCycleCashFlowServiceMock.deployContract).toHaveBeenCalledWith( + hederaTokenAddress, + hederaUsdcAddress, + ) + expect(assetRepositoryMock.saveAsset).toHaveBeenCalledWith( + expect.objectContaining({ + name: name, + type: AssetType.EQUITY, + hederaTokenAddress: hederaTokenAddress, + evmTokenAddress: evmTokenAddress, + isPaused: false, + lifeCycleCashFlowHederaAddress: lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: lifeCycleCashFlowEvmAddress, + }), + ) + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + expect(result).toEqual(assetWithLifeCycleCashFlow) + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalled() + }) + + it("should import an asset with BOND type from syncAsset response", async () => { + const name = "Bond Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaUsdcAddress = fakeHederaAddress() + const lifeCycleCashFlowHederaAddress = fakeHederaAddress() + const lifeCycleCashFlowEvmAddress = faker.finance.ethereumAddress() + const getAssetInfoResponse: GetAssetInfoResponse = { + hederaTokenAddress: hederaTokenAddress, + name: name, + symbol: faker.finance.currencySymbol(), + assetType: AssetType.BOND, + } + const lifeCycleCashFlowAddress = LifeCycleCashFlowAddress.create( + lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress, + ) + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = faker.date.future() + const initialAsset = Asset.create(name, AssetType.BOND, hederaTokenAddress, evmTokenAddress, symbol, maturityDate) + const assetWithLifeCycleCashFlow = initialAsset.withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + assetRepositoryMock.getAssetByName.mockResolvedValue(undefined) + assetRepositoryMock.getAssetByHederaTokenAddress.mockResolvedValue(undefined) + configServiceMock.get.mockReturnValue(hederaUsdcAddress) + hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(evmTokenAddress) + assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(getAssetInfoResponse) + onChainLifeCycleCashFlowServiceMock.deployContract.mockResolvedValue(lifeCycleCashFlowAddress) + assetRepositoryMock.saveAsset.mockResolvedValue(assetWithLifeCycleCashFlow) + + const result = await importAssetDomainService.importAsset(hederaTokenAddress) + + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalledWith(hederaTokenAddress) + expect(onChainLifeCycleCashFlowServiceMock.deployContract).toHaveBeenCalledWith( + hederaTokenAddress, + hederaUsdcAddress, + ) + expect(assetRepositoryMock.saveAsset).toHaveBeenCalledWith( + expect.objectContaining({ + name: name, + type: AssetType.BOND, + hederaTokenAddress: hederaTokenAddress, + evmTokenAddress: evmTokenAddress, + lifeCycleCashFlowHederaAddress: lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: lifeCycleCashFlowEvmAddress, + }), + ) + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + expect(result.type).toBe(AssetType.BOND) + }) + + it("should handle errors during syncAsset call", async () => { + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const errorMessage = "Failed to sync asset from Hedera" + assetRepositoryMock.getAssetByName.mockResolvedValue(undefined) + assetRepositoryMock.getAssetByHederaTokenAddress.mockResolvedValue(undefined) + hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(evmTokenAddress) + assetTokenizationStudioServiceMock.getAssetInfo.mockRejectedValue(new Error(errorMessage)) + + await expect(importAssetDomainService.importAsset(hederaTokenAddress)).rejects.toThrow(errorMessage) + + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalledWith(hederaTokenAddress) + expect(assetRepositoryMock.saveAsset).not.toHaveBeenCalled() + expect(syncFromOnChainDomainServiceMock.execute).not.toHaveBeenCalled() + }) + + it("should handle errors during asset creation", async () => { + const hederaTokenAddress = "0.0.1234" + const errorMessage = "Error converting Hedera address" + assetRepositoryMock.getAssetByName.mockResolvedValue(undefined) + assetRepositoryMock.getAssetByHederaTokenAddress.mockResolvedValue(undefined) + + hederaServiceMock.getEvmAddressFromHedera.mockRejectedValue(new Error(errorMessage)) + + await expect(importAssetDomainService.importAsset(hederaTokenAddress)).rejects.toThrow(`${errorMessage}`) + }) + + it("should handle errors during contract deployment", async () => { + const name = "Test Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaUsdcAddress = fakeHederaAddress() + const errorMessage = "Contract deployment failed" + const getAssetInfoResponse: GetAssetInfoResponse = { + hederaTokenAddress: hederaTokenAddress, + name: name, + symbol: faker.finance.currencySymbol(), + assetType: AssetType.EQUITY, + } + assetRepositoryMock.getAssetByName.mockResolvedValue(undefined) + assetRepositoryMock.getAssetByHederaTokenAddress.mockResolvedValue(undefined) + + const symbol = faker.string.alpha({ length: 3 }) + const initialAsset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol) + + configServiceMock.get.mockReturnValue(hederaUsdcAddress) + hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(evmTokenAddress) + assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(getAssetInfoResponse) + assetRepositoryMock.saveAsset.mockResolvedValue(initialAsset) + onChainLifeCycleCashFlowServiceMock.deployContract.mockRejectedValue(new Error(errorMessage)) + + await expect(importAssetDomainService.importAsset(hederaTokenAddress)).rejects.toThrow(`${errorMessage}`) + + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalledWith(hederaTokenAddress) + expect(onChainLifeCycleCashFlowServiceMock.deployContract).toHaveBeenCalledWith( + hederaTokenAddress, + hederaUsdcAddress, + ) + expect(assetRepositoryMock.saveAsset).not.toHaveBeenCalled() + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + expect(syncFromOnChainDomainServiceMock.execute).not.toHaveBeenCalled() + }) + + it("should throw an error if asset with same name already exists", async () => { + const name = faker.commerce.productName() + const hederaTokenAddress = fakeHederaAddress() + const symbol = faker.string.alpha({ length: 3 }) + const evmAddress = faker.finance.ethereumAddress() + const initialAsset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmAddress, symbol) + assetRepositoryMock.getAssetByName.mockResolvedValue(initialAsset) + + await expect(importAssetDomainService.importAsset(hederaTokenAddress)).rejects.toThrow(Error) + + expect(assetRepositoryMock.getAssetByHederaTokenAddress).toHaveBeenCalled() + expect(assetTokenizationStudioServiceMock.getAssetInfo).toHaveBeenCalled() + expect(assetRepositoryMock.getAssetByName).not.toHaveBeenCalledWith(name) + expect(syncFromOnChainDomainServiceMock.execute).not.toHaveBeenCalled() + }) + + it("should throw an error if asset with same token address already exists", async () => { + const name = faker.commerce.productName() + const hederaTokenAddress = fakeHederaAddress() + assetRepositoryMock.getAssetByName.mockResolvedValue(undefined) + const symbol = faker.string.alpha({ length: 3 }) + const evmTokenAddress = faker.finance.ethereumAddress() + const initialAsset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol) + assetRepositoryMock.getAssetByHederaTokenAddress.mockResolvedValue(initialAsset) + + await expect(importAssetDomainService.importAsset(hederaTokenAddress)).rejects.toThrow( + AssetHederaTokenAddressAlreadyExistsError, + ) + + expect(assetRepositoryMock.getAssetByHederaTokenAddress).toHaveBeenCalledWith(hederaTokenAddress) + }) + + it("should import an asset with isPaused true when contract is paused", async () => { + const name = "Paused Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const hederaUsdcAddress = fakeHederaAddress() + const lifeCycleCashFlowHederaAddress = fakeHederaAddress() + const lifeCycleCashFlowEvmAddress = faker.finance.ethereumAddress() + + const getAssetInfoResponse: GetAssetInfoResponse = { + hederaTokenAddress: hederaTokenAddress, + name: name, + symbol: faker.finance.currencySymbol(), + assetType: AssetType.EQUITY, + } + + const lifeCycleCashFlowAddress = LifeCycleCashFlowAddress.create( + lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress, + ) + const symbol = faker.string.alpha({ length: 3 }) + const initialAsset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol).pause() + const assetWithLifeCycleCashFlow = initialAsset.withLifeCycleCashFlow(lifeCycleCashFlowAddress) + + assetRepositoryMock.getAssetByName.mockResolvedValue(undefined) + assetRepositoryMock.getAssetByHederaTokenAddress.mockResolvedValue(undefined) + configServiceMock.get.mockReturnValue(hederaUsdcAddress) + hederaServiceMock.getEvmAddressFromHedera.mockResolvedValue(evmTokenAddress) + assetTokenizationStudioServiceMock.getAssetInfo.mockResolvedValue(getAssetInfoResponse) + onChainLifeCycleCashFlowServiceMock.isPaused.mockResolvedValue(true) + assetRepositoryMock.saveAsset.mockResolvedValue(initialAsset) + onChainLifeCycleCashFlowServiceMock.deployContract.mockResolvedValue(lifeCycleCashFlowAddress) + assetRepositoryMock.updateAsset.mockResolvedValue(assetWithLifeCycleCashFlow) + + const result = await importAssetDomainService.importAsset(hederaTokenAddress) + + expect(onChainLifeCycleCashFlowServiceMock.isPaused).toHaveBeenCalledWith(hederaTokenAddress) + expect(assetRepositoryMock.saveAsset).toHaveBeenCalledWith( + expect.objectContaining({ + name: name, + type: AssetType.EQUITY, + hederaTokenAddress: hederaTokenAddress, + evmTokenAddress: evmTokenAddress, + isPaused: true, + }), + ) + expect(result.isPaused).toBe(true) + expect(syncFromOnChainDomainServiceMock.execute).toHaveBeenCalled() + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/pause-asset.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/pause-asset.domain-service.spec.ts new file mode 100644 index 000000000..cf808f1ae --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/pause-asset.domain-service.spec.ts @@ -0,0 +1,402 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { PauseAssetDomainService } from "@domain/services/pause-asset.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" + +//TODO ruben.martinez uncomment when these tests are fixed on main. +describe.skip(PauseAssetDomainService.name, () => { + let pauseAssetDomainService: PauseAssetDomainService + const assetRepositoryMock = createMock() + const onChainLifeCycleCashFlowServiceMock = createMock() + + const mockDate = faker.date.future() + jest.spyOn(global, "Date").mockImplementation(() => mockDate) + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + PauseAssetDomainService, + { + provide: "AssetRepository", + useValue: assetRepositoryMock, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useValue: onChainLifeCycleCashFlowServiceMock, + }, + ], + }).compile() + + pauseAssetDomainService = module.get(PauseAssetDomainService) + + jest.clearAllMocks() + }) + + describe("pause", () => { + it("should pause an asset successfully", async () => { + const assetId = faker.string.uuid() + const name = "Test Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol) + const pausedAsset = asset.pause() + + assetRepositoryMock.getAsset.mockResolvedValue(asset) + onChainLifeCycleCashFlowServiceMock.pause.mockResolvedValue(true) + assetRepositoryMock.updateAsset.mockResolvedValue(pausedAsset) + + const result = await pauseAssetDomainService.pause(assetId) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.pause).toHaveBeenCalledWith(undefined) + expect(assetRepositoryMock.updateAsset).toHaveBeenCalledWith( + expect.objectContaining({ + id: asset.id, + name: name, + type: AssetType.EQUITY, + hederaTokenAddress: hederaTokenAddress, + evmTokenAddress: evmTokenAddress, + isPaused: true, + }), + ) + expect(result).toEqual(pausedAsset) + expect(result.isPaused).toBe(true) + }) + + it("should return asset without changes when asset is already paused", async () => { + const assetId = faker.string.uuid() + const name = "Already Paused Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const alreadyPausedAsset = Asset.create( + name, + AssetType.EQUITY, + hederaTokenAddress, + evmTokenAddress, + symbol, + ).pause() + + assetRepositoryMock.getAsset.mockResolvedValue(alreadyPausedAsset) + + const result = await pauseAssetDomainService.pause(assetId) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.pause).not.toHaveBeenCalled() + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + expect(result).toEqual(alreadyPausedAsset) + expect(result.isPaused).toBe(true) + }) + + it("should throw error when asset not found", async () => { + const assetId = faker.string.uuid() + + assetRepositoryMock.getAsset.mockResolvedValue(null) + + await expect(pauseAssetDomainService.pause(assetId)).rejects.toThrow(`Asset with ID ${assetId} not found`) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.pause).not.toHaveBeenCalled() + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + }) + + it("should handle on-chain pause failure", async () => { + const assetId = faker.string.uuid() + const name = "Test Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const errorMessage = "On-chain pause failed" + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol) + + assetRepositoryMock.getAsset.mockResolvedValue(asset) + onChainLifeCycleCashFlowServiceMock.pause.mockRejectedValue(new Error(errorMessage)) + + await expect(pauseAssetDomainService.pause(assetId)).rejects.toThrow(errorMessage) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.pause).toHaveBeenCalledWith(undefined) + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + }) + + it("should handle repository update failure", async () => { + const assetId = faker.string.uuid() + const name = "Test Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const errorMessage = "Repository update failed" + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol) + + assetRepositoryMock.getAsset.mockResolvedValue(asset) + onChainLifeCycleCashFlowServiceMock.pause.mockResolvedValue(true) + assetRepositoryMock.updateAsset.mockRejectedValue(new Error(errorMessage)) + + await expect(pauseAssetDomainService.pause(assetId)).rejects.toThrow(errorMessage) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.pause).toHaveBeenCalledWith(undefined) + expect(assetRepositoryMock.updateAsset).toHaveBeenCalled() + }) + + it("should pause asset with lifecycle cash flow addresses", async () => { + const assetId = faker.string.uuid() + const name = "Asset with Lifecycle" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const lifeCycleCashFlowHederaAddress = fakeHederaAddress() + const lifeCycleCashFlowEvmAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = faker.date.future() + const asset = Asset.createExisting( + assetId, + name, + AssetType.BOND, + hederaTokenAddress, + evmTokenAddress, + symbol, + maturityDate, + lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress, + false, + true, + faker.date.past(), + faker.date.recent(), + ) + const pausedAsset = asset.pause() + + assetRepositoryMock.getAsset.mockResolvedValue(asset) + onChainLifeCycleCashFlowServiceMock.pause.mockResolvedValue(true) + assetRepositoryMock.updateAsset.mockResolvedValue(pausedAsset) + + const result = await pauseAssetDomainService.pause(assetId) + + expect(onChainLifeCycleCashFlowServiceMock.pause).toHaveBeenCalledWith(lifeCycleCashFlowHederaAddress) + expect(assetRepositoryMock.updateAsset).toHaveBeenCalledWith( + expect.objectContaining({ + lifeCycleCashFlowHederaAddress: lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: lifeCycleCashFlowEvmAddress, + isPaused: true, + }), + ) + expect(result.isPaused).toBe(true) + expect(result.lifeCycleCashFlowHederaAddress).toBe(lifeCycleCashFlowHederaAddress) + expect(result.lifeCycleCashFlowEvmAddress).toBe(lifeCycleCashFlowEvmAddress) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/retry-failed-holders.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/retry-failed-holders.domain-service.spec.ts new file mode 100644 index 000000000..df3c0587e --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/retry-failed-holders.domain-service.spec.ts @@ -0,0 +1,451 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { RetryFailedHoldersDomainService } from "@domain/services/retry-failed-holders.domain-service" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { HolderUtils } from "@test/shared/holder.utils" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { BatchPayoutStatus } from "@domain/model/batch-payout" +import { HolderStatus } from "@domain/model/holder" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { AmountType, DistributionStatus, DistributionType, PayoutSubtype } from "@domain/model/distribution" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { DistributionNotFoundError, DistributionNotInStatusError } from "@domain/errors/distribution.error" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" + +describe(RetryFailedHoldersDomainService.name, () => { + let retryFailedHoldersDomainService: RetryFailedHoldersDomainService + const distributionRepositoryMock = createMock() + const holderRepositoryMock = createMock() + const onChainLifeCycleCashFlowServiceMock = createMock() + const updateBatchPayoutStatusDomainServiceMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + RetryFailedHoldersDomainService, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + { + provide: "HolderRepository", + useValue: holderRepositoryMock, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useValue: onChainLifeCycleCashFlowServiceMock, + }, + { + provide: "UpdateBatchPayoutStatusDomainService", + useValue: updateBatchPayoutStatusDomainServiceMock, + }, + ], + }).compile() + + retryFailedHoldersDomainService = module.get(RetryFailedHoldersDomainService) + + jest.clearAllMocks() + }) + + describe("execute", () => { + it("should retry failed holders for a corporate action distribution", async () => { + const batchPayout = BatchPayoutUtils.newInstance({ + status: BatchPayoutStatus.IN_PROGRESS, + distribution: DistributionUtils.newInstance({ status: DistributionStatus.FAILED }), + }) + const holders = [ + HolderUtils.newInstance({ + batchPayout: batchPayout, + status: HolderStatus.FAILED, + }), + HolderUtils.newInstance({ + batchPayout: batchPayout, + status: HolderStatus.FAILED, + }), + ] + const distribution = batchPayout.distribution + const corporateActionId = Number((distribution.details as any).corporateActionId.value) + const asset = batchPayout.distribution.asset + const holderAccounts = holders.map((holder) => holder.holderEvmAddress) + const amount = faker.number.int({ min: 1, max: 1000 }).toString() + const executeDistributionResponse = { + failed: [], + succeeded: holderAccounts, + paidAmount: [amount, amount], + transactionId: "0.0.456@1234567891.987654321", + } as any + + distributionRepositoryMock.getDistribution.mockResolvedValue(batchPayout.distribution) + holderRepositoryMock.getHoldersByDistributionIdAndStatus.mockResolvedValue(holders) + onChainLifeCycleCashFlowServiceMock.executeDistributionByAddresses.mockResolvedValue(executeDistributionResponse) + + await retryFailedHoldersDomainService.execute(batchPayout.distribution.id) + + expect(distributionRepositoryMock.getDistribution).toHaveBeenCalledWith(batchPayout.distribution.id) + expect(holderRepositoryMock.getHoldersByDistributionIdAndStatus).toHaveBeenCalledWith( + batchPayout.distribution.id, + HolderStatus.FAILED, + ) + expect(holderRepositoryMock.saveHolders).toHaveBeenCalledTimes(2) + holders.forEach((holder) => holder.retrying()) + expect(holderRepositoryMock.saveHolders).toHaveBeenNthCalledWith(1, holders) + holders.forEach((holder) => holder.succeed(amount)) + expect(holderRepositoryMock.saveHolders).toHaveBeenNthCalledWith(2, holders) + expect(onChainLifeCycleCashFlowServiceMock.executeDistributionByAddresses).toHaveBeenCalledWith( + asset.lifeCycleCashFlowHederaAddress, + asset.hederaTokenAddress, + corporateActionId, + holderAccounts, + ) + expect(updateBatchPayoutStatusDomainServiceMock.execute).toHaveBeenCalledWith(batchPayout) + }) + + it("should retry failed holders for a payout with amount type fixed distribution", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.FAILED, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + snapshotId: SnapshotId.create("some-snapshot-id"), + }, + }) + const batchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS, distribution }) + const holders = [ + HolderUtils.newInstance({ + batchPayout: batchPayout, + status: HolderStatus.FAILED, + }), + HolderUtils.newInstance({ + batchPayout: batchPayout, + status: HolderStatus.FAILED, + }), + ] + const snapshotId = Number((distribution.details as any).snapshotId.value) + const asset = batchPayout.distribution.asset + const holderAccounts = holders.map((holder) => holder.holderEvmAddress) + const executeDistributionResponse = { + failed: holderAccounts, + succeeded: [], + paidAmount: [], + transactionId: "0.0.456@1234567891.987654321", + } as any + + distributionRepositoryMock.getDistribution.mockResolvedValue(batchPayout.distribution) + holderRepositoryMock.getHoldersByDistributionIdAndStatus.mockResolvedValue(holders) + onChainLifeCycleCashFlowServiceMock.executeAmountSnapshotByAddresses.mockResolvedValue( + executeDistributionResponse, + ) + + await retryFailedHoldersDomainService.execute(batchPayout.distribution.id) + + expect(distributionRepositoryMock.getDistribution).toHaveBeenCalledWith(batchPayout.distribution.id) + expect(holderRepositoryMock.getHoldersByDistributionIdAndStatus).toHaveBeenCalledWith( + batchPayout.distribution.id, + HolderStatus.FAILED, + ) + expect(holderRepositoryMock.saveHolders).toHaveBeenCalledTimes(2) + holders.forEach((holder) => holder.retrying()) + expect(holderRepositoryMock.saveHolders).toHaveBeenNthCalledWith(1, holders) + holders.forEach((holder) => holder.failed()) + expect(holderRepositoryMock.saveHolders).toHaveBeenNthCalledWith(2, holders) + expect(onChainLifeCycleCashFlowServiceMock.executeAmountSnapshotByAddresses).toHaveBeenCalledWith( + asset.lifeCycleCashFlowHederaAddress, + asset.hederaTokenAddress, + snapshotId, + holderAccounts, + (distribution.details as any).amount, + ) + expect(updateBatchPayoutStatusDomainServiceMock.execute).toHaveBeenCalledWith(batchPayout) + }) + + it("should retry failed holders for a payout with amount type percentage distribution", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.FAILED, + details: { + type: DistributionType.PAYOUT, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.PERCENTAGE, + snapshotId: SnapshotId.create("some-snapshot-id"), + }, + }) + const batchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS, distribution }) + const holders = [ + HolderUtils.newInstance({ + batchPayout: batchPayout, + status: HolderStatus.FAILED, + }), + HolderUtils.newInstance({ + batchPayout: batchPayout, + status: HolderStatus.FAILED, + }), + ] + const snapshotId = Number((distribution.details as any).snapshotId.value) + const asset = batchPayout.distribution.asset + const holderAccounts = holders.map((holder) => holder.holderEvmAddress) + const holderAmount = faker.number.int({ min: 1, max: 1000 }).toString() + const executeDistributionResponse = { + failed: [], + succeeded: holderAccounts, + paidAmount: [holderAmount, holderAmount], + transactionId: "0.0.456@1234567891.987654321", + } as any + + distributionRepositoryMock.getDistribution.mockResolvedValue(batchPayout.distribution) + holderRepositoryMock.getHoldersByDistributionIdAndStatus.mockResolvedValue(holders) + onChainLifeCycleCashFlowServiceMock.executePercentageSnapshotByAddresses.mockResolvedValue( + executeDistributionResponse, + ) + + await retryFailedHoldersDomainService.execute(batchPayout.distribution.id) + + expect(distributionRepositoryMock.getDistribution).toHaveBeenCalledWith(batchPayout.distribution.id) + expect(holderRepositoryMock.getHoldersByDistributionIdAndStatus).toHaveBeenCalledWith( + batchPayout.distribution.id, + HolderStatus.FAILED, + ) + expect(holderRepositoryMock.saveHolders).toHaveBeenCalledTimes(2) + holders.forEach((holder) => holder.retrying()) + expect(holderRepositoryMock.saveHolders).toHaveBeenNthCalledWith(1, holders) + holders.forEach((holder) => holder.succeed(holderAmount)) + expect(holderRepositoryMock.saveHolders).toHaveBeenNthCalledWith(2, holders) + expect(onChainLifeCycleCashFlowServiceMock.executePercentageSnapshotByAddresses).toHaveBeenCalledWith( + asset.lifeCycleCashFlowHederaAddress, + asset.hederaTokenAddress, + snapshotId, + holderAccounts, + (distribution.details as any).amount, + ) + expect(updateBatchPayoutStatusDomainServiceMock.execute).toHaveBeenCalledWith(batchPayout) + }) + + it("should throw DistributionNotFoundError when distribution does not exist", async () => { + const distributionId = faker.string.uuid() + distributionRepositoryMock.getDistribution.mockResolvedValue(undefined) + + await expect(retryFailedHoldersDomainService.execute(distributionId)).rejects.toThrow( + new DistributionNotFoundError(distributionId), + ) + }) + + it("should throw DistributionNotInStatusError when distribution is not in FAILED status", async () => { + const distribution = DistributionUtils.newInstance({ + status: DistributionStatus.COMPLETED, + }) + distributionRepositoryMock.getDistribution.mockResolvedValue(distribution) + + await expect(retryFailedHoldersDomainService.execute(distribution.id)).rejects.toThrow( + new DistributionNotInStatusError(distribution.id, DistributionStatus.FAILED), + ) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/sync-from-onchain.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/sync-from-onchain.domain-service.spec.ts new file mode 100644 index 000000000..8b8b6dc73 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/sync-from-onchain.domain-service.spec.ts @@ -0,0 +1,524 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetType } from "@domain/model/asset-type.enum" +import { CorporateActionDetails, Distribution, DistributionType } from "@domain/model/distribution" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { + OnChainDistributionRepositoryPort, + OnChainDistributionData, +} from "@domain/ports/on-chain-distribution-repository.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { SyncFromOnChainDomainService } from "@domain/services/sync-from-onchain.domain-service" +import { faker } from "@faker-js/faker" +import { createMock, DeepMocked } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { AssetUtils } from "@test/shared/asset.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" + +describe(SyncFromOnChainDomainService.name, () => { + let service: SyncFromOnChainDomainService + let assetsRepositoryMock: DeepMocked + let distributionsRepositoryMock: DeepMocked + let onChainDistributionRepositoryMock: DeepMocked + let lifeCycleCashFlowPortMock: DeepMocked + + beforeEach(async () => { + assetsRepositoryMock = createMock() + distributionsRepositoryMock = createMock() + onChainDistributionRepositoryMock = createMock() + lifeCycleCashFlowPortMock = createMock() + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + SyncFromOnChainDomainService, + { + provide: "AssetRepository", + useValue: assetsRepositoryMock, + }, + { + provide: "DistributionRepository", + useValue: distributionsRepositoryMock, + }, + { + provide: "OnChainDistributionRepositoryPort", + useValue: onChainDistributionRepositoryMock, + }, + { + provide: "LifeCycleCashFlowPort", + useValue: lifeCycleCashFlowPortMock, + }, + ], + }).compile() + + service = module.get(SyncFromOnChainDomainService) + }) + + afterEach(() => { + jest.restoreAllMocks() + }) + + describe("execute", () => { + it("should do nothing when no assets exist", async () => { + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([]) + + await service.execute() + + expect(assetsRepositoryMock.getAllSyncEnabledAssets).toHaveBeenCalledTimes(1) + expect(onChainDistributionRepositoryMock.getAllDistributionsByAsset).not.toHaveBeenCalled() + }) + + it("creates new distribution when it doesn't exist locally", async () => { + const asset = AssetUtils.newInstance() + const corporateActionId = faker.string.uuid() + const executionDate = faker.date.future() + const remote = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: { value: corporateActionId }, + executionDate, + } as CorporateActionDetails, + }) + + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([asset]) + assetsRepositoryMock.getAsset.mockResolvedValue(asset) + onChainDistributionRepositoryMock.getAllDistributionsByAsset.mockResolvedValue([remote]) + distributionsRepositoryMock.findByCorporateActionId.mockResolvedValue(null) + + await service.execute() + + expect(distributionsRepositoryMock.saveDistribution).toHaveBeenCalledTimes(1) + const saved = distributionsRepositoryMock.saveDistribution.mock.calls[0][0] as Distribution + expect((saved.details as CorporateActionDetails).corporateActionId.value).toBe(corporateActionId) + expect((saved.details as CorporateActionDetails).executionDate.valueOf()).toBe(executionDate.valueOf()) + }) + + it("skips update when executionDate has not changed", async () => { + const asset = AssetUtils.newInstance() + const corporateActionId = faker.string.uuid() + const executionDate = faker.date.future() + const remote = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: { value: corporateActionId }, + executionDate, + } as CorporateActionDetails, + }) + const local = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: { value: corporateActionId }, + executionDate, + } as CorporateActionDetails, + }) + + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([asset]) + onChainDistributionRepositoryMock.getAllDistributionsByAsset.mockResolvedValue([remote]) + distributionsRepositoryMock.findByCorporateActionId.mockResolvedValue(local) + + await service.execute() + + expect(distributionsRepositoryMock.saveDistribution).not.toHaveBeenCalled() + }) + + it("updates executionDate when it has changed", async () => { + const asset = AssetUtils.newInstance() + const corporateActionId = faker.string.uuid() + const executionDate = faker.date.future() + const remote = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: { value: corporateActionId }, + executionDate, + } as CorporateActionDetails, + }) + const local = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: { value: corporateActionId }, + executionDate: faker.date.future({ years: 1 }), + } as CorporateActionDetails, + }) + + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([asset]) + onChainDistributionRepositoryMock.getAllDistributionsByAsset.mockResolvedValue([remote]) + distributionsRepositoryMock.findByCorporateActionId.mockResolvedValue(local) + + await service.execute() + + expect(distributionsRepositoryMock.saveDistribution).toHaveBeenCalledWith( + expect.objectContaining({ + asset, + details: expect.objectContaining({ + executionDate: (remote.details as CorporateActionDetails).executionDate, + }), + }), + ) + }) + + it("should sync distributions for equity assets", async () => { + const equityAsset = AssetUtils.newInstance({ type: AssetType.EQUITY }) + const corporateActionId = faker.string.uuid() + const executionDate = faker.date.future() + const remote = DistributionUtils.newInstance({ + asset: equityAsset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: { value: corporateActionId }, + executionDate, + } as CorporateActionDetails, + }) + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([equityAsset]) + onChainDistributionRepositoryMock.getAllDistributionsByAsset.mockResolvedValue([remote]) + distributionsRepositoryMock.findByCorporateActionId.mockResolvedValue(null) + + await service.execute() + + expect(onChainDistributionRepositoryMock.getAllDistributionsByAsset).toHaveBeenCalledWith(equityAsset) + expect(distributionsRepositoryMock.findByCorporateActionId).toHaveBeenCalledWith( + equityAsset.id, + corporateActionId, + ) + expect(distributionsRepositoryMock.saveDistribution).toHaveBeenCalledWith( + expect.objectContaining({ + asset: equityAsset, + details: expect.objectContaining({ + executionDate, + }), + }), + ) + }) + + it("should create new distribution when it doesn't exist locally", async () => { + const asset = AssetUtils.newInstance() + const corporateActionId = faker.string.uuid() + const executionDate = faker.date.future() + const corporateActionIdObj = { value: corporateActionId } as any + const onChainDistribution = Distribution.createCorporateAction(asset, corporateActionIdObj, executionDate) + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([asset]) + onChainDistributionRepositoryMock.getAllDistributionsByAsset.mockResolvedValue([onChainDistribution]) + distributionsRepositoryMock.findByCorporateActionId.mockResolvedValue(null) + + await service.execute() + + expect(distributionsRepositoryMock.findByCorporateActionId).toHaveBeenCalledWith(asset.id, corporateActionId) + expect(distributionsRepositoryMock.saveDistribution).toHaveBeenCalledWith( + expect.objectContaining({ + asset, + details: expect.objectContaining({ + corporateActionId: expect.objectContaining({ value: corporateActionId }), + executionDate, + }), + }), + ) + }) + + it("should update distribution when execution date has changed", async () => { + const asset = AssetUtils.newInstance() + const corporateActionId = faker.string.uuid() + const oldExecutionDate = faker.date.soon({ days: 1 }) + const newExecutionDate = faker.date.future({ years: 30 }) + const corporateActionIdObj2 = { value: corporateActionId } as any + const onChainDistribution = Distribution.createCorporateAction(asset, corporateActionIdObj2, newExecutionDate) + const existingDistribution = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: { value: corporateActionId } as any, + executionDate: oldExecutionDate, + } as any, + }) + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([asset]) + onChainDistributionRepositoryMock.getAllDistributionsByAsset.mockResolvedValue([onChainDistribution]) + distributionsRepositoryMock.findByCorporateActionId.mockResolvedValue(existingDistribution) + + await service.execute() + + expect(distributionsRepositoryMock.saveDistribution).toHaveBeenCalledWith( + expect.objectContaining({ + id: existingDistribution.id, + details: expect.objectContaining({ + executionDate: newExecutionDate, + }), + }), + ) + }) + + it("should skip update when execution date hasn't changed", async () => { + const asset = AssetUtils.newInstance() + const corporateActionId = faker.string.uuid() + const executionDate = faker.date.future() + const corporateActionIdObj3 = { value: corporateActionId } as any + const onChainDistribution = Distribution.createCorporateAction(asset, corporateActionIdObj3, executionDate) + const existingDistribution = DistributionUtils.newInstance({ + asset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId: { value: corporateActionId } as any, + executionDate, + } as any, + }) + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([asset]) + onChainDistributionRepositoryMock.getAllDistributionsByAsset.mockResolvedValue([onChainDistribution]) + distributionsRepositoryMock.findByCorporateActionId.mockResolvedValue(existingDistribution) + + await service.execute() + + expect(distributionsRepositoryMock.updateDistribution).not.toHaveBeenCalled() + expect(distributionsRepositoryMock.saveDistribution).not.toHaveBeenCalled() + }) + + it("should handle multiple assets correctly", async () => { + const bondAsset = AssetUtils.newInstance({ type: AssetType.BOND }) + const equityAsset = AssetUtils.newInstance({ type: AssetType.EQUITY }) + const bondCorporateActionId = { value: "bond-1" } as any + const equityCorporateActionId = { value: "equity-1" } as any + const bondDistribution = Distribution.createCorporateAction(bondAsset, bondCorporateActionId, faker.date.future()) + const equityDistribution = Distribution.createCorporateAction( + equityAsset, + equityCorporateActionId, + faker.date.future(), + ) + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([bondAsset, equityAsset]) + onChainDistributionRepositoryMock.getAllDistributionsByAsset + .mockResolvedValueOnce([bondDistribution]) + .mockResolvedValueOnce([equityDistribution]) + distributionsRepositoryMock.findByCorporateActionId.mockResolvedValue(null) + + await service.execute() + + expect(onChainDistributionRepositoryMock.getAllDistributionsByAsset).toHaveBeenCalledTimes(2) + expect(onChainDistributionRepositoryMock.getAllDistributionsByAsset).toHaveBeenCalledWith(bondAsset) + expect(onChainDistributionRepositoryMock.getAllDistributionsByAsset).toHaveBeenCalledWith(equityAsset) + expect(distributionsRepositoryMock.saveDistribution).toHaveBeenCalledTimes(2) + }) + + it("should handle empty distributions from on-chain", async () => { + const asset = AssetUtils.newInstance() + assetsRepositoryMock.getAllSyncEnabledAssets.mockResolvedValue([asset]) + onChainDistributionRepositoryMock.getAllDistributionsByAsset.mockResolvedValue([]) + + await service.execute() + + expect(onChainDistributionRepositoryMock.getAllDistributionsByAsset).toHaveBeenCalledWith(asset) + expect(distributionsRepositoryMock.findByCorporateActionId).not.toHaveBeenCalled() + expect(distributionsRepositoryMock.saveDistribution).not.toHaveBeenCalled() + expect(distributionsRepositoryMock.updateDistribution).not.toHaveBeenCalled() + }) + }) +}) + +function fakeRemote(): OnChainDistributionData { + return { + corporateActionID: faker.string.uuid(), + assetId: faker.string.uuid(), + executionDate: faker.date.future(), + } +} diff --git a/apps/mass-payout/backend/test/unit/domain/services/transition-batch-payout-to-partially-completed.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/transition-batch-payout-to-partially-completed.domain-service.spec.ts new file mode 100644 index 000000000..8dda6bbf6 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/transition-batch-payout-to-partially-completed.domain-service.spec.ts @@ -0,0 +1,310 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Test, TestingModule } from "@nestjs/testing" +import { TransitionBatchPayoutToPartiallyCompletedDomainService } from "@domain/services/transition-batch-payout-to-partially-completed.domain-service" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { createMock, DeepMocked } from "@golevelup/ts-jest" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { BatchPayoutStatus } from "@domain/model/batch-payout" + +describe(TransitionBatchPayoutToPartiallyCompletedDomainService.name, () => { + let service: TransitionBatchPayoutToPartiallyCompletedDomainService + let batchPayoutRepositoryMock: DeepMocked + let updateDistributionStatusDomainServiceMock: DeepMocked + + beforeEach(async () => { + batchPayoutRepositoryMock = createMock() + updateDistributionStatusDomainServiceMock = createMock() + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + TransitionBatchPayoutToPartiallyCompletedDomainService, + { + provide: "BatchPayoutRepository", + useValue: batchPayoutRepositoryMock, + }, + { + provide: "UpdateDistributionStatusDomainService", + useValue: updateDistributionStatusDomainServiceMock, + }, + ], + }).compile() + + service = module.get( + TransitionBatchPayoutToPartiallyCompletedDomainService, + ) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("execute", () => { + describe("when batch payout can transition to PARTIALLY_COMPLETED", () => { + it("should transition IN_PROGRESS batch payout to PARTIALLY_COMPLETED", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS }) + const expectedBatchPayout = BatchPayoutUtils.newInstance({ + ...originalBatchPayout, + status: BatchPayoutStatus.PARTIALLY_COMPLETED, + }) + batchPayoutRepositoryMock.saveBatchPayout.mockResolvedValue(expectedBatchPayout) + + const result = await service.execute(originalBatchPayout) + + expect(batchPayoutRepositoryMock.saveBatchPayout).toHaveBeenCalledWith( + expect.objectContaining({ + id: originalBatchPayout.id, + status: BatchPayoutStatus.PARTIALLY_COMPLETED, + }), + ) + expect(updateDistributionStatusDomainServiceMock.execute).toHaveBeenCalledWith(expectedBatchPayout.distribution) + expect(result).toEqual(expectedBatchPayout) + }) + + it("should transition PARTIALLY_COMPLETED batch payout to PARTIALLY_COMPLETED", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.PARTIALLY_COMPLETED }) + const expectedBatchPayout = BatchPayoutUtils.newInstance({ + ...originalBatchPayout, + status: BatchPayoutStatus.PARTIALLY_COMPLETED, + }) + batchPayoutRepositoryMock.saveBatchPayout.mockResolvedValue(expectedBatchPayout) + + const result = await service.execute(originalBatchPayout) + + expect(batchPayoutRepositoryMock.saveBatchPayout).toHaveBeenCalledWith( + expect.objectContaining({ + id: originalBatchPayout.id, + status: BatchPayoutStatus.PARTIALLY_COMPLETED, + }), + ) + expect(updateDistributionStatusDomainServiceMock.execute).toHaveBeenCalledWith(expectedBatchPayout.distribution) + expect(result).toEqual(expectedBatchPayout) + }) + }) + + describe("when batch payout cannot transition to PARTIALLY_COMPLETED", () => { + it("should not modify COMPLETED batch payout and not update distribution", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.COMPLETED }) + + const result = await service.execute(originalBatchPayout) + + expect(batchPayoutRepositoryMock.saveBatchPayout).not.toHaveBeenCalled() + expect(updateDistributionStatusDomainServiceMock.execute).not.toHaveBeenCalled() + expect(result).toBe(originalBatchPayout) + }) + + it("should not modify FAILED batch payout and not update distribution", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.FAILED }) + + const result = await service.execute(originalBatchPayout) + + expect(batchPayoutRepositoryMock.saveBatchPayout).not.toHaveBeenCalled() + expect(updateDistributionStatusDomainServiceMock.execute).not.toHaveBeenCalled() + expect(result).toBe(originalBatchPayout) + }) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/unpause-asset.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/unpause-asset.domain-service.spec.ts new file mode 100644 index 000000000..e33ffd20a --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/unpause-asset.domain-service.spec.ts @@ -0,0 +1,395 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from "@domain/model/asset" +import { AssetType } from "@domain/model/asset-type.enum" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { LifeCycleCashFlowPort } from "@domain/ports/life-cycle-cash-flow.port" +import { UnpauseAssetDomainService } from "@domain/services/unpause-asset.domain-service" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { fakeHederaAddress } from "@test/shared/utils" + +describe(UnpauseAssetDomainService.name, () => { + let unpauseAssetDomainService: UnpauseAssetDomainService + const assetRepositoryMock = createMock() + const onChainLifeCycleCashFlowServiceMock = createMock() + + const mockDate = faker.date.future() + jest.spyOn(global, "Date").mockImplementation(() => mockDate) + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + UnpauseAssetDomainService, + { + provide: "AssetRepository", + useValue: assetRepositoryMock, + }, + { + provide: "OnChainLifeCycleCashFlowService", + useValue: onChainLifeCycleCashFlowServiceMock, + }, + ], + }).compile() + + unpauseAssetDomainService = module.get(UnpauseAssetDomainService) + + jest.clearAllMocks() + }) + + describe("unpause", () => { + it("should unpause an asset successfully", async () => { + const assetId = faker.string.uuid() + const name = "Test Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol).pause() + const unpausedAsset = asset.unpause() + + assetRepositoryMock.getAsset.mockResolvedValue(asset) + onChainLifeCycleCashFlowServiceMock.unpause.mockResolvedValue(true) + assetRepositoryMock.updateAsset.mockResolvedValue(unpausedAsset) + + const result = await unpauseAssetDomainService.unpause(assetId) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.unpause).toHaveBeenCalledWith(asset.lifeCycleCashFlowHederaAddress) + expect(assetRepositoryMock.updateAsset).toHaveBeenCalledWith( + expect.objectContaining({ + id: asset.id, + name: name, + type: AssetType.EQUITY, + hederaTokenAddress: hederaTokenAddress, + evmTokenAddress: evmTokenAddress, + isPaused: false, + }), + ) + expect(result).toEqual(unpausedAsset) + expect(result.isPaused).toBe(false) + }) + + it("should return asset without changes when asset is already unpaused", async () => { + const assetId = faker.string.uuid() + const name = "Already Unpaused Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const alreadyUnpausedAsset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol) + + assetRepositoryMock.getAsset.mockResolvedValue(alreadyUnpausedAsset) + + const result = await unpauseAssetDomainService.unpause(assetId) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.unpause).not.toHaveBeenCalled() + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + expect(result).toEqual(alreadyUnpausedAsset) + expect(result.isPaused).toBe(false) + }) + + it("should throw error when asset not found", async () => { + const assetId = faker.string.uuid() + + assetRepositoryMock.getAsset.mockResolvedValue(null) + + await expect(unpauseAssetDomainService.unpause(assetId)).rejects.toThrow(`Asset with ID ${assetId} not found`) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.unpause).not.toHaveBeenCalled() + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + }) + + it("should handle on-chain unpause failure", async () => { + const assetId = faker.string.uuid() + const name = "Test Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const errorMessage = "On-chain unpause failed" + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol).pause() + + assetRepositoryMock.getAsset.mockResolvedValue(asset) + onChainLifeCycleCashFlowServiceMock.unpause.mockRejectedValue(new Error(errorMessage)) + + await expect(unpauseAssetDomainService.unpause(assetId)).rejects.toThrow(errorMessage) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.unpause).toHaveBeenCalledWith(asset.lifeCycleCashFlowHederaAddress) + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + }) + + it("should handle repository update failure", async () => { + const assetId = faker.string.uuid() + const name = "Test Asset" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const errorMessage = "Repository update failed" + + const symbol = faker.string.alpha({ length: 3 }) + const asset = Asset.create(name, AssetType.EQUITY, hederaTokenAddress, evmTokenAddress, symbol).pause() + + assetRepositoryMock.getAsset.mockResolvedValue(asset) + onChainLifeCycleCashFlowServiceMock.unpause.mockResolvedValue(true) + assetRepositoryMock.updateAsset.mockRejectedValue(new Error(errorMessage)) + + await expect(unpauseAssetDomainService.unpause(assetId)).rejects.toThrow(errorMessage) + + expect(assetRepositoryMock.getAsset).toHaveBeenCalledWith(assetId) + expect(onChainLifeCycleCashFlowServiceMock.unpause).toHaveBeenCalledWith(asset.lifeCycleCashFlowHederaAddress) + expect(assetRepositoryMock.updateAsset).toHaveBeenCalled() + }) + + it("should unpause asset with lifecycle cash flow addresses", async () => { + const assetId = faker.string.uuid() + const name = "Asset with Lifecycle" + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + const lifeCycleCashFlowHederaAddress = fakeHederaAddress() + const lifeCycleCashFlowEvmAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = faker.date.future() + const asset = Asset.createExisting( + assetId, + name, + AssetType.BOND, + hederaTokenAddress, + evmTokenAddress, + symbol, + maturityDate, + lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress, + true, + true, + faker.date.past(), + faker.date.recent(), + ) + const unpausedAsset = asset.unpause() + + assetRepositoryMock.getAsset.mockResolvedValue(asset) + onChainLifeCycleCashFlowServiceMock.unpause.mockResolvedValue(true) + assetRepositoryMock.updateAsset.mockResolvedValue(unpausedAsset) + + const result = await unpauseAssetDomainService.unpause(assetId) + + expect(onChainLifeCycleCashFlowServiceMock.unpause).toHaveBeenCalledWith(lifeCycleCashFlowHederaAddress) + expect(assetRepositoryMock.updateAsset).toHaveBeenCalledWith( + expect.objectContaining({ + lifeCycleCashFlowHederaAddress: lifeCycleCashFlowHederaAddress, + lifeCycleCashFlowEvmAddress: lifeCycleCashFlowEvmAddress, + isPaused: false, + }), + ) + expect(result.isPaused).toBe(false) + expect(result.lifeCycleCashFlowHederaAddress).toBe(lifeCycleCashFlowHederaAddress) + expect(result.lifeCycleCashFlowEvmAddress).toBe(lifeCycleCashFlowEvmAddress) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/update-asset.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/update-asset.domain-service.spec.ts new file mode 100644 index 000000000..a60befb26 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/update-asset.domain-service.spec.ts @@ -0,0 +1,325 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Test, TestingModule } from "@nestjs/testing" +import { faker } from "@faker-js/faker" +import { createMock } from "@golevelup/ts-jest" +import { Asset } from "@domain/model/asset" +import { AssetRepository } from "@domain/ports/asset-repository.port" +import { UpdateAssetDomainService } from "@domain/services/update-asset.domain-service" +import { fakeHederaAddress } from "@test/shared/utils" +import { AssetNameAlreadyExistsError, AssetNotFoundError } from "@domain/errors/asset.error" +import { AssetType } from "@domain/model/asset-type.enum" + +describe(UpdateAssetDomainService.name, () => { + let updateAssetDomainService: UpdateAssetDomainService + const assetRepositoryMock = createMock() + + const mockDate = faker.date.future() + jest.spyOn(global, "Date").mockImplementation(() => mockDate) + + const mockUUID = "1cb83c9e-ad81-424a-9029-5dc861308aa3" + jest.spyOn(crypto, "randomUUID").mockImplementation(() => mockUUID) + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + UpdateAssetDomainService, + { + provide: "AssetRepository", + useValue: assetRepositoryMock, + }, + ], + }).compile() + + updateAssetDomainService = module.get(UpdateAssetDomainService) + + jest.clearAllMocks() + }) + + describe("updateAsset", () => { + it("should update an asset's name successfully", async () => { + const assetId = faker.string.uuid() + const oldName = faker.company.name() + const newName = faker.company.name() + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol = faker.string.alpha({ length: 3 }) + const maturityDate = faker.date.future() + const existingAsset = Asset.create( + oldName, + AssetType.BOND, + hederaTokenAddress, + evmTokenAddress, + symbol, + maturityDate, + ) + + assetRepositoryMock.getAsset.mockResolvedValue(existingAsset) + assetRepositoryMock.getAssetByName.mockResolvedValue(undefined) + + const result = await updateAssetDomainService.updateAsset(assetId, newName) + + expect(result).toBeInstanceOf(Asset) + expect(result.id).toBe(existingAsset.id) + expect(result.name).toBe(newName) + expect(result.hederaTokenAddress).toBe(hederaTokenAddress) + expect(result.evmTokenAddress).toBe(evmTokenAddress) + expect(result.updatedAt).toBe(mockDate) + expect(assetRepositoryMock.updateAsset).toHaveBeenCalledTimes(1) + }) + + it("should throw AssetNotFoundError when asset does not exist", async () => { + const assetId = faker.string.uuid() + const newName = faker.company.name() + + assetRepositoryMock.getAsset.mockResolvedValue(undefined) + + await expect(updateAssetDomainService.updateAsset(assetId, newName)).rejects.toThrow( + new AssetNotFoundError(assetId), + ) + + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + }) + + it("should throw AssetNameAlreadyExistsError when new name is already taken", async () => { + const assetId = faker.string.uuid() + const oldName = faker.company.name() + const newName = faker.company.name() + const hederaTokenAddress = fakeHederaAddress() + const evmTokenAddress = faker.finance.ethereumAddress() + + const symbol1 = faker.string.alpha({ length: 3 }) + const maturityDate1 = faker.date.future() + const existingAsset = Asset.create( + oldName, + AssetType.BOND, + hederaTokenAddress, + evmTokenAddress, + symbol1, + maturityDate1, + ) + const symbol2 = faker.string.alpha({ length: 3 }) + const maturityDate2 = faker.date.future() + const otherAsset = Asset.create( + newName, + AssetType.BOND, + fakeHederaAddress(), + faker.finance.ethereumAddress(), + symbol2, + maturityDate2, + ) + + assetRepositoryMock.getAsset.mockResolvedValue(existingAsset) + assetRepositoryMock.getAssetByName.mockResolvedValue(otherAsset) + + await expect(updateAssetDomainService.updateAsset(assetId, newName)).rejects.toThrow( + new AssetNameAlreadyExistsError(newName), + ) + + expect(assetRepositoryMock.updateAsset).not.toHaveBeenCalled() + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/update-batch-payout-status.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/update-batch-payout-status.domain-service.spec.ts new file mode 100644 index 000000000..32dcbff6c --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/update-batch-payout-status.domain-service.spec.ts @@ -0,0 +1,396 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Test, TestingModule } from "@nestjs/testing" +import { UpdateBatchPayoutStatusDomainService } from "@domain/services/update-batch-payout-status.domain-service" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { createMock, DeepMocked } from "@golevelup/ts-jest" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { HolderUtils } from "@test/shared/holder.utils" +import { BatchPayoutStatus } from "@domain/model/batch-payout" +import { HolderStatus } from "@domain/model/holder" + +describe(UpdateBatchPayoutStatusDomainService.name, () => { + let service: UpdateBatchPayoutStatusDomainService + let batchPayoutRepositoryMock: DeepMocked + let holderRepositoryMock: DeepMocked + let updateDistributionStatusDomainServiceMock: DeepMocked + + beforeEach(async () => { + batchPayoutRepositoryMock = createMock() + holderRepositoryMock = createMock() + updateDistributionStatusDomainServiceMock = createMock() + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + UpdateBatchPayoutStatusDomainService, + { + provide: "BatchPayoutRepository", + useValue: batchPayoutRepositoryMock, + }, + { + provide: "HolderRepository", + useValue: holderRepositoryMock, + }, + { + provide: "UpdateDistributionStatusDomainService", + useValue: updateDistributionStatusDomainServiceMock, + }, + ], + }).compile() + + service = module.get(UpdateBatchPayoutStatusDomainService) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("execute", () => { + describe("when there are failed holders with FAILED status", () => { + it("should update batch payout status to FAILED and update distribution status", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS }) + const holders = [ + HolderUtils.newInstance({ + batchPayout: originalBatchPayout, + status: HolderStatus.FAILED, + }), + HolderUtils.newInstance({ + batchPayout: originalBatchPayout, + status: HolderStatus.SUCCESS, + }), + ] + const expectedBatchPayout = BatchPayoutUtils.newInstance({ + ...originalBatchPayout, + status: BatchPayoutStatus.FAILED, + }) + holderRepositoryMock.getHoldersByBatchPayout.mockResolvedValue(holders) + batchPayoutRepositoryMock.updateBatchPayout.mockResolvedValue(expectedBatchPayout) + + const result = await service.execute(originalBatchPayout) + + expect(holderRepositoryMock.getHoldersByBatchPayout).toHaveBeenCalledWith(originalBatchPayout.id) + expect(batchPayoutRepositoryMock.updateBatchPayout).toHaveBeenCalledWith( + expect.objectContaining({ + id: originalBatchPayout.id, + status: BatchPayoutStatus.FAILED, + }), + ) + expect(updateDistributionStatusDomainServiceMock.execute).toHaveBeenCalledWith(originalBatchPayout.distribution) + expect(result).toEqual(expectedBatchPayout) + }) + }) + + describe("when all failed holders have SUCCESS status", () => { + it("should update batch payout status to COMPLETED and update distribution status", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS }) + const holders = [ + HolderUtils.newInstance({ + batchPayout: originalBatchPayout, + status: HolderStatus.SUCCESS, + }), + HolderUtils.newInstance({ + batchPayout: originalBatchPayout, + status: HolderStatus.SUCCESS, + }), + ] + const expectedBatchPayout = BatchPayoutUtils.newInstance({ + ...originalBatchPayout, + status: BatchPayoutStatus.COMPLETED, + }) + holderRepositoryMock.getHoldersByBatchPayout.mockResolvedValue(holders) + batchPayoutRepositoryMock.updateBatchPayout.mockResolvedValue(expectedBatchPayout) + + const result = await service.execute(originalBatchPayout) + + expect(holderRepositoryMock.getHoldersByBatchPayout).toHaveBeenCalledWith(originalBatchPayout.id) + expect(batchPayoutRepositoryMock.updateBatchPayout).toHaveBeenCalledWith( + expect.objectContaining({ + id: originalBatchPayout.id, + status: BatchPayoutStatus.COMPLETED, + }), + ) + expect(updateDistributionStatusDomainServiceMock.execute).toHaveBeenCalledWith(originalBatchPayout.distribution) + expect(result).toEqual(expectedBatchPayout) + }) + }) + + describe("when failed holders have mixed statuses without FAILED", () => { + it("should not change batch payout status but still update distribution status", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS }) + const holders = [ + HolderUtils.newInstance({ + batchPayout: originalBatchPayout, + status: HolderStatus.PENDING, + }), + HolderUtils.newInstance({ + batchPayout: originalBatchPayout, + status: HolderStatus.SUCCESS, + }), + ] + holderRepositoryMock.getHoldersByBatchPayout.mockResolvedValue(holders) + batchPayoutRepositoryMock.updateBatchPayout.mockResolvedValue(originalBatchPayout) + + const result = await service.execute(originalBatchPayout) + + expect(holderRepositoryMock.getHoldersByBatchPayout).toHaveBeenCalledWith(originalBatchPayout.id) + expect(batchPayoutRepositoryMock.updateBatchPayout).toHaveBeenCalledWith(originalBatchPayout) + expect(updateDistributionStatusDomainServiceMock.execute).toHaveBeenCalledWith(originalBatchPayout.distribution) + expect(result).toEqual(originalBatchPayout) + }) + }) + + describe("when there are no failed holders", () => { + it("should update batch payout status to COMPLETED and update distribution status", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS }) + const holders = [] + const expectedBatchPayout = BatchPayoutUtils.newInstance({ + ...originalBatchPayout, + status: BatchPayoutStatus.COMPLETED, + }) + holderRepositoryMock.getHoldersByBatchPayout.mockResolvedValue(holders) + batchPayoutRepositoryMock.updateBatchPayout.mockResolvedValue(expectedBatchPayout) + + const result = await service.execute(originalBatchPayout) + + expect(holderRepositoryMock.getHoldersByBatchPayout).toHaveBeenCalledWith(originalBatchPayout.id) + expect(batchPayoutRepositoryMock.updateBatchPayout).toHaveBeenCalledWith( + expect.objectContaining({ + id: originalBatchPayout.id, + status: BatchPayoutStatus.COMPLETED, + }), + ) + expect(updateDistributionStatusDomainServiceMock.execute).toHaveBeenCalledWith(originalBatchPayout.distribution) + expect(result).toEqual(expectedBatchPayout) + }) + }) + + describe("when all failed holders have PENDING status", () => { + it("should not change batch payout status but still update distribution status", async () => { + const originalBatchPayout = BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS }) + const holders = [ + HolderUtils.newInstance({ + batchPayout: originalBatchPayout, + status: HolderStatus.PENDING, + }), + HolderUtils.newInstance({ + batchPayout: originalBatchPayout, + status: HolderStatus.PENDING, + }), + ] + holderRepositoryMock.getHoldersByBatchPayout.mockResolvedValue(holders) + batchPayoutRepositoryMock.updateBatchPayout.mockResolvedValue(originalBatchPayout) + + const result = await service.execute(originalBatchPayout) + + expect(holderRepositoryMock.getHoldersByBatchPayout).toHaveBeenCalledWith(originalBatchPayout.id) + expect(batchPayoutRepositoryMock.updateBatchPayout).toHaveBeenCalledWith(originalBatchPayout) + expect(updateDistributionStatusDomainServiceMock.execute).toHaveBeenCalledWith(originalBatchPayout.distribution) + expect(result).toEqual(originalBatchPayout) + }) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/update.distribution-status.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/update.distribution-status.domain-service.spec.ts new file mode 100644 index 000000000..f67ff91e8 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/update.distribution-status.domain-service.spec.ts @@ -0,0 +1,337 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { BatchPayoutStatus } from "@domain/model/batch-payout" +import { DistributionStatus } from "@domain/model/distribution" +import { HolderStatus } from "@domain/model/holder" +import { BatchPayoutRepository } from "@domain/ports/batch-payout-repository.port" +import { DistributionRepository } from "@domain/ports/distribution-repository.port" +import { HolderRepository } from "@domain/ports/holder-repository.port" +import { UpdateDistributionStatusDomainService } from "@domain/services/update-distribution-status.domain-service" +import { createMock, DeepMocked } from "@golevelup/ts-jest" +import { Test, TestingModule } from "@nestjs/testing" +import { BatchPayoutUtils } from "@test/shared/batch-payout.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { HolderUtils } from "@test/shared/holder.utils" + +describe(UpdateDistributionStatusDomainService.name, () => { + let service: UpdateDistributionStatusDomainService + let distributionRepositoryMock: DeepMocked + let batchPayoutRepositoryMock: DeepMocked + let holderRepositoryMock: DeepMocked + + beforeEach(async () => { + distributionRepositoryMock = createMock() + batchPayoutRepositoryMock = createMock() + holderRepositoryMock = createMock() + + const module: TestingModule = await Test.createTestingModule({ + providers: [ + UpdateDistributionStatusDomainService, + { + provide: "DistributionRepository", + useValue: distributionRepositoryMock, + }, + { + provide: "BatchPayoutRepository", + useValue: batchPayoutRepositoryMock, + }, + { + provide: "HolderRepository", + useValue: holderRepositoryMock, + }, + ], + }).compile() + + service = module.get(UpdateDistributionStatusDomainService) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("execute", () => { + describe("when there are no batch payouts", () => { + it("should return the distribution without changes", async () => { + const originalDistribution = DistributionUtils.newInstance() + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue([]) + + const result = await service.execute(originalDistribution) + + expect(result).toBe(originalDistribution) + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).toHaveBeenCalledTimes(1) + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).toHaveBeenCalledWith(originalDistribution) + expect(distributionRepositoryMock.updateDistribution).not.toHaveBeenCalled() + expect(holderRepositoryMock.getAllHoldersByDistributionId).not.toHaveBeenCalled() + }) + }) + + describe("when all batch payouts are completed", () => { + it("should update distribution status to COMPLETED", async () => { + const originalDistribution = DistributionUtils.newInstance() + const completedBatchPayouts = [ + BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.COMPLETED }), + BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.COMPLETED }), + ] + const expectedDistribution = DistributionUtils.newInstance({ status: DistributionStatus.COMPLETED }) + + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue(completedBatchPayouts) + distributionRepositoryMock.updateDistribution.mockResolvedValue(expectedDistribution) + + const result = await service.execute(originalDistribution) + + expect(result).toEqual(expectedDistribution) + expect(result.status).toBe(DistributionStatus.COMPLETED) + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).toHaveBeenCalledWith(originalDistribution) + expect(distributionRepositoryMock.updateDistribution).toHaveBeenCalled() + }) + }) + + describe("when there are failed holders", () => { + it("should update distribution status to FAILED when there are failed holders", async () => { + const originalDistribution = DistributionUtils.newInstance() + const batchPayouts = [ + BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.COMPLETED }), + BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS }), + ] + const holders = [HolderUtils.newInstance({ status: HolderStatus.FAILED })] + const expectedDistribution = DistributionUtils.newInstance({ status: DistributionStatus.FAILED }) + + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue(batchPayouts) + holderRepositoryMock.getAllHoldersByDistributionId.mockResolvedValue(holders) + distributionRepositoryMock.updateDistribution.mockResolvedValue(expectedDistribution) + + const result = await service.execute(originalDistribution) + + expect(result).toEqual(expectedDistribution) + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).toHaveBeenCalledWith(originalDistribution) + expect(holderRepositoryMock.getAllHoldersByDistributionId).toHaveBeenCalledWith(originalDistribution.id) + expect(distributionRepositoryMock.updateDistribution).toHaveBeenCalled() + }) + }) + + describe("when there are in progress batch payouts without failed holders", () => { + it("should update distribution status to IN_PROGRESS", async () => { + const originalDistribution = DistributionUtils.newInstance() + const batchPayouts = [ + BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.COMPLETED }), + BatchPayoutUtils.newInstance({ status: BatchPayoutStatus.IN_PROGRESS }), + ] + const holders = [HolderUtils.newInstance({ status: HolderStatus.PENDING })] + const expectedDistribution = DistributionUtils.newInstance({ status: DistributionStatus.IN_PROGRESS }) + + batchPayoutRepositoryMock.getBatchPayoutsByDistribution.mockResolvedValue(batchPayouts) + holderRepositoryMock.getAllHoldersByDistributionId.mockResolvedValue(holders) + distributionRepositoryMock.updateDistribution.mockResolvedValue(expectedDistribution) + + const result = await service.execute(originalDistribution) + + expect(result).toEqual(expectedDistribution) + expect(batchPayoutRepositoryMock.getBatchPayoutsByDistribution).toHaveBeenCalledWith(originalDistribution) + expect(holderRepositoryMock.getAllHoldersByDistributionId).toHaveBeenCalledWith(originalDistribution.id) + expect(distributionRepositoryMock.updateDistribution).toHaveBeenCalled() + }) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/domain/services/validate-asset-pause-state.domain-service.spec.ts b/apps/mass-payout/backend/test/unit/domain/services/validate-asset-pause-state.domain-service.spec.ts new file mode 100644 index 000000000..c99ae2590 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/domain/services/validate-asset-pause-state.domain-service.spec.ts @@ -0,0 +1,73 @@ +/* + * Copyright 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { AssetPausedError } from "@domain/errors/asset.error" +import { ValidateAssetPauseStateDomainService } from "@domain/services/validate-asset-pause-state.domain-service" +import { faker } from "@faker-js/faker/." +import { Test, TestingModule } from "@nestjs/testing" +import { AssetUtils } from "@test/shared/asset.utils" + +describe(ValidateAssetPauseStateDomainService.name, () => { + let validateAssetPauseStateDomainService: ValidateAssetPauseStateDomainService + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ValidateAssetPauseStateDomainService], + }).compile() + + validateAssetPauseStateDomainService = module.get( + ValidateAssetPauseStateDomainService, + ) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("validateDomainPauseState", () => { + it("should resolve when asset is not paused in domain", async () => { + const asset = AssetUtils.newInstance({ isPaused: false }) + const distributionId = faker.string.uuid() + + await expect( + validateAssetPauseStateDomainService.validateDomainPauseState(asset, distributionId), + ).resolves.toBeUndefined() + }) + + it("should throw AssetPausedError when asset is paused in domain", async () => { + const asset = AssetUtils.newInstance({ isPaused: true }) + const distributionId = faker.string.uuid() + + await expect( + validateAssetPauseStateDomainService.validateDomainPauseState(asset, distributionId), + ).rejects.toThrow(new AssetPausedError(asset.name, asset.hederaTokenAddress)) + }) + + it("should include distribution ID in error context when asset is paused", async () => { + const asset = AssetUtils.newInstance({ isPaused: true }) + const distributionId = faker.string.uuid() + + try { + await validateAssetPauseStateDomainService.validateDomainPauseState(asset, distributionId) + fail("Expected AssetPausedError to be thrown") + } catch (error) { + expect(error).toBeInstanceOf(AssetPausedError) + expect(error.message).toContain(asset.name) + expect(error.message).toContain(asset.hederaTokenAddress) + } + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/infrastructure/adapters/on-chain-distribution.repository.spec.ts b/apps/mass-payout/backend/test/unit/infrastructure/adapters/on-chain-distribution.repository.spec.ts new file mode 100644 index 000000000..2b36fee0c --- /dev/null +++ b/apps/mass-payout/backend/test/unit/infrastructure/adapters/on-chain-distribution.repository.spec.ts @@ -0,0 +1,598 @@ +/* + * 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 use, reproduce, modify, distribute, and perform + * the Work and to prepare Derivative Works based upon the Work, and to + * permit persons to whom the Work is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Work. + * + * 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, trademark, patent, + * attribution and other 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 notice 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. When 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. + */ + +import { OnChainDistributionRepository } from "@infrastructure/adapters/on-chain-distribution.repository" +import { AssetType } from "@domain/model/asset-type.enum" +import { Asset } from "@domain/model/asset" +import { CorporateActionDetails, DistributionType, PayoutSubtype, AmountType } from "@domain/model/distribution" +import { Bond, Equity } from "@hashgraph/asset-tokenization-sdk" +import { AssetUtils } from "@test/shared/asset.utils" +import { DistributionUtils } from "@test/shared/distribution.utils" +import { CorporateActionId } from "@domain/model/value-objects/corporate-action-id" +import { SnapshotId } from "@domain/model/value-objects/snapshot-id" +import { faker } from "@faker-js/faker" + +jest.mock("@hashgraph/asset-tokenization-sdk", () => ({ + Bond: { + getAllCoupons: jest.fn(), + getTotalCouponHolders: jest.fn(), + }, + Equity: { + getAllDividends: jest.fn(), + getTotalDividendHolders: jest.fn(), + }, + Security: { + getTotalTokenHoldersAtSnapshot: jest.fn(), + }, + GetAllCouponsRequest: jest.fn(), + GetAllDividendsRequest: jest.fn(), + GetTotalCouponHoldersRequest: jest.fn(), + GetTotalDividendHoldersRequest: jest.fn(), + GetTotalTokenHoldersAtSnapshotRequest: jest.fn(), +})) + +const mockBond = Bond as jest.Mocked +const mockEquity = Equity as jest.Mocked +import { Security } from "@hashgraph/asset-tokenization-sdk" +const mockSecurity = Security as jest.Mocked + +describe(OnChainDistributionRepository.name, () => { + let repository: OnChainDistributionRepository + let bondAsset: Asset + let equityAsset: Asset + + beforeEach(() => { + repository = new OnChainDistributionRepository() + bondAsset = AssetUtils.newInstance({ type: AssetType.BOND }) + equityAsset = AssetUtils.newInstance({ type: AssetType.EQUITY }) + jest.clearAllMocks() + }) + + describe("getAllDistributionsByAsset", () => { + it("should call getCouponsForAsset for BOND assets", async () => { + const mockCoupons = [ + { + couponId: faker.number.int(), + executionDate: faker.date.future(), + recordDate: faker.date.recent(), + rate: faker.number.float({ min: 0.01, max: 0.1 }).toString(), + }, + ] + mockBond.getAllCoupons.mockResolvedValue(mockCoupons) + + await repository.getAllDistributionsByAsset(bondAsset) + + expect(mockBond.getAllCoupons).toHaveBeenCalledWith(expect.any(Object)) + }) + + it("should call getDividendsForAsset for EQUITY assets", async () => { + const mockDividends = [ + { + dividendId: faker.number.int(), + executionDate: faker.date.future(), + amountPerUnitOfSecurity: faker.number.float({ min: 1, max: 100 }).toString(), + recordDate: faker.date.recent(), + }, + ] + mockEquity.getAllDividends.mockResolvedValue(mockDividends) + + await repository.getAllDistributionsByAsset(equityAsset) + + expect(mockEquity.getAllDividends).toHaveBeenCalledWith(expect.any(Object)) + }) + + it("should return empty array for unsupported asset types", async () => { + const unsupportedAsset = AssetUtils.newInstance({ type: "UNSUPPORTED" as AssetType }) + + const result = await repository.getAllDistributionsByAsset(unsupportedAsset) + + expect(result).toEqual([]) + }) + }) + + describe("getCouponsForAsset (BOND)", () => { + it("should return all future coupons when multiple future coupons exist", async () => { + const now = new Date() + const closestDate = new Date(now.getTime() + 24 * 60 * 60 * 1000) + const furtherDate = new Date(now.getTime() + 48 * 60 * 60 * 1000) + + const mockCoupons = [ + { + couponId: 2, + executionDate: furtherDate, + recordDate: faker.date.recent(), + rate: faker.number.float({ min: 0.01, max: 0.1 }).toString(), + }, + { + couponId: 1, + executionDate: closestDate, + recordDate: faker.date.recent(), + rate: faker.number.float({ min: 0.01, max: 0.1 }).toString(), + }, + ] + mockBond.getAllCoupons.mockResolvedValue(mockCoupons) + + const result = await repository.getAllDistributionsByAsset(bondAsset) + + expect(result).toHaveLength(2) + expect((result[0].details as CorporateActionDetails).executionDate).toEqual(closestDate) + expect((result[0].details as any).corporateActionId.value).toBe("1") + expect((result[1].details as CorporateActionDetails).executionDate).toEqual(furtherDate) + expect((result[1].details as any).corporateActionId.value).toBe("2") + }) + + it("should return empty array when no future coupons exist", async () => { + const now = new Date() + const pastDate = new Date(now.getTime() - 24 * 60 * 60 * 1000) + + const mockCoupons = [ + { + couponId: 1, + executionDate: pastDate, + recordDate: faker.date.recent(), + rate: faker.number.float({ min: 0.01, max: 0.1 }).toString(), + }, + ] + mockBond.getAllCoupons.mockResolvedValue(mockCoupons) + + const result = await repository.getAllDistributionsByAsset(bondAsset) + + expect(result).toEqual([]) + }) + + it("should return empty array when no coupons exist", async () => { + mockBond.getAllCoupons.mockResolvedValue([]) + + const result = await repository.getAllDistributionsByAsset(bondAsset) + + expect(result).toEqual([]) + }) + + it("should filter out past coupons and return only the closest future one", async () => { + const now = new Date() + const pastDate = new Date(now.getTime() - 24 * 60 * 60 * 1000) + const closestFutureDate = new Date(now.getTime() + 12 * 60 * 60 * 1000) + const furtherFutureDate = new Date(now.getTime() + 48 * 60 * 60 * 1000) + + const mockCoupons = [ + { + couponId: 1, + executionDate: pastDate, + recordDate: faker.date.recent(), + rate: faker.number.float({ min: 0.01, max: 0.1 }).toString(), + }, + { + couponId: 3, + executionDate: furtherFutureDate, + recordDate: faker.date.recent(), + rate: faker.number.float({ min: 0.01, max: 0.1 }).toString(), + }, + { + couponId: 2, + executionDate: closestFutureDate, + recordDate: faker.date.recent(), + rate: faker.number.float({ min: 0.01, max: 0.1 }).toString(), + }, + ] + mockBond.getAllCoupons.mockResolvedValue(mockCoupons) + + const result = await repository.getAllDistributionsByAsset(bondAsset) + + expect(result).toHaveLength(2) + expect((result[0].details as CorporateActionDetails).executionDate).toEqual(closestFutureDate) + expect((result[0].details as any).corporateActionId.value).toBe("2") + expect((result[1].details as CorporateActionDetails).executionDate).toEqual(furtherFutureDate) + expect((result[1].details as any).corporateActionId.value).toBe("3") + }) + }) + + describe("getDividendsForAsset (EQUITY)", () => { + it("should return all future dividends when multiple future dividends exist", async () => { + const now = new Date() + const closestDate = new Date(now.getTime() + 24 * 60 * 60 * 1000) + const furtherDate = new Date(now.getTime() + 48 * 60 * 60 * 1000) + + const mockDividends = [ + { + dividendId: 2, + executionDate: furtherDate, + amountPerUnitOfSecurity: faker.number.float({ min: 1, max: 100 }).toString(), + recordDate: faker.date.recent(), + }, + { + dividendId: 1, + executionDate: closestDate, + amountPerUnitOfSecurity: faker.number.float({ min: 1, max: 100 }).toString(), + recordDate: faker.date.recent(), + }, + ] + mockEquity.getAllDividends.mockResolvedValue(mockDividends) + + const result = await repository.getAllDistributionsByAsset(equityAsset) + + expect(result).toHaveLength(2) + expect((result[0].details as CorporateActionDetails).executionDate).toEqual(closestDate) + expect((result[0].details as any).corporateActionId.value).toBe("1") + expect((result[1].details as CorporateActionDetails).executionDate).toEqual(furtherDate) + expect((result[1].details as any).corporateActionId.value).toBe("2") + }) + + it("should return empty array when no future dividends exist", async () => { + const now = new Date() + const pastDate = new Date(now.getTime() - 24 * 60 * 60 * 1000) + + const mockDividends = [ + { + dividendId: 1, + executionDate: pastDate, + amountPerUnitOfSecurity: faker.number.float({ min: 1, max: 100 }).toString(), + recordDate: faker.date.recent(), + }, + ] + mockEquity.getAllDividends.mockResolvedValue(mockDividends) + + const result = await repository.getAllDistributionsByAsset(equityAsset) + + expect(result).toEqual([]) + }) + + it("should return empty array when no dividends exist", async () => { + mockEquity.getAllDividends.mockResolvedValue([]) + + const result = await repository.getAllDistributionsByAsset(equityAsset) + + expect(result).toEqual([]) + }) + + it("should filter out past dividends and return only the closest future one", async () => { + const now = new Date() + const pastDate = new Date(now.getTime() - 24 * 60 * 60 * 1000) + const closestFutureDate = new Date(now.getTime() + 12 * 60 * 60 * 1000) + const furtherFutureDate = new Date(now.getTime() + 48 * 60 * 60 * 1000) + + const mockDividends = [ + { + dividendId: 1, + executionDate: pastDate, + amountPerUnitOfSecurity: faker.number.float({ min: 1, max: 100 }).toString(), + recordDate: faker.date.recent(), + }, + { + dividendId: 3, + executionDate: furtherFutureDate, + amountPerUnitOfSecurity: faker.number.float({ min: 1, max: 100 }).toString(), + recordDate: faker.date.recent(), + }, + { + dividendId: 2, + executionDate: closestFutureDate, + amountPerUnitOfSecurity: faker.number.float({ min: 1, max: 100 }).toString(), + recordDate: faker.date.recent(), + }, + ] + mockEquity.getAllDividends.mockResolvedValue(mockDividends) + + const result = await repository.getAllDistributionsByAsset(equityAsset) + + expect(result).toHaveLength(2) + expect((result[0].details as CorporateActionDetails).executionDate).toEqual(closestFutureDate) + expect((result[0].details as any).corporateActionId.value).toBe("2") + expect((result[1].details as CorporateActionDetails).executionDate).toEqual(furtherFutureDate) + expect((result[1].details as any).corporateActionId.value).toBe("3") + }) + }) + + describe("getHoldersCountForCorporateActionId", () => { + it("should return holders count for BOND corporate action distribution", async () => { + const corporateActionId = CorporateActionId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + asset: bondAsset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId, + executionDate: faker.date.future(), + }, + }) + const expectedCount = 250 + mockBond.getTotalCouponHolders.mockResolvedValue(expectedCount) + + const result = await repository.getHoldersCountForCorporateActionId(distribution) + + expect(result).toBe(expectedCount) + }) + + it("should return holders count for EQUITY corporate action distribution", async () => { + const corporateActionId = CorporateActionId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + asset: equityAsset, + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId, + executionDate: faker.date.future(), + }, + }) + const expectedCount = 180 + mockEquity.getTotalDividendHolders.mockResolvedValue(expectedCount) + + const result = await repository.getHoldersCountForCorporateActionId(distribution) + + expect(result).toBe(expectedCount) + }) + + it("should throw error for non-corporate action distribution", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + + await expect(repository.getHoldersCountForCorporateActionId(distribution)).rejects.toThrow( + `Distribution ${distribution.id} is not a corporate action distribution`, + ) + }) + }) + + describe("getHoldersCountForSnapshotId", () => { + it("should return holders count for payout distribution with snapshot", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + const expectedCount = 320 + mockSecurity.getTotalTokenHoldersAtSnapshot.mockResolvedValue(expectedCount) + + const result = await repository.getHoldersCountForSnapshotId(distribution) + + expect(result).toBe(expectedCount) + }) + + it("should throw error for non-payout distribution", async () => { + const corporateActionId = CorporateActionId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.CORPORATE_ACTION, + corporateActionId, + executionDate: faker.date.future(), + }, + }) + + await expect(repository.getHoldersCountForSnapshotId(distribution)).rejects.toThrow( + `Distribution ${distribution.id} is not a payout distribution`, + ) + }) + + it("should throw error for payout distribution without snapshotId", async () => { + const snapshotId = SnapshotId.create(faker.string.numeric()) + const distribution = DistributionUtils.newInstance({ + details: { + type: DistributionType.PAYOUT, + snapshotId, + subtype: PayoutSubtype.IMMEDIATE, + amount: faker.number.int({ min: 1, max: 1000 }).toString(), + amountType: AmountType.FIXED, + }, + }) + ;(distribution.details as any).snapshotId = undefined + + await expect(repository.getHoldersCountForSnapshotId(distribution)).rejects.toThrow( + `SnapshotId is missing for distribution ${distribution.id}`, + ) + }) + }) +}) diff --git a/apps/mass-payout/backend/test/unit/infrastructure/cron/mass-payout-cron.service.spec.ts b/apps/mass-payout/backend/test/unit/infrastructure/cron/mass-payout-cron.service.spec.ts new file mode 100644 index 000000000..42631b2c4 --- /dev/null +++ b/apps/mass-payout/backend/test/unit/infrastructure/cron/mass-payout-cron.service.spec.ts @@ -0,0 +1,251 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Test, TestingModule } from "@nestjs/testing" +import { createMock } from "@golevelup/ts-jest" +import { MassPayoutCronService } from "@infrastructure/cron/mass-payout-cron.service" +import { ProcessScheduledPayoutsUseCase } from "@application/use-cases/process-scheduled-payouts.use-case" + +describe(MassPayoutCronService.name, () => { + let massPayoutCronService: MassPayoutCronService + const processScheduledPayoutsUseCaseMock = createMock() + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + MassPayoutCronService, + { + provide: ProcessScheduledPayoutsUseCase, + useValue: processScheduledPayoutsUseCaseMock, + }, + ], + }).compile() + + massPayoutCronService = module.get(MassPayoutCronService) + }) + + afterEach(() => { + jest.clearAllMocks() + }) + + describe("handleScheduledPayouts", () => { + it("should handle errors from the use case and let them propagate", async () => { + const error = new Error("Use case execution failed") + processScheduledPayoutsUseCaseMock.execute.mockRejectedValue(error) + + await expect(massPayoutCronService.handleScheduledPayouts()).rejects.toThrow("Use case execution failed") + + expect(processScheduledPayoutsUseCaseMock.execute).toHaveBeenCalledTimes(1) + }) + + it("should call the use case without any parameters", async () => { + processScheduledPayoutsUseCaseMock.execute.mockResolvedValue(undefined) + + await massPayoutCronService.handleScheduledPayouts() + + expect(processScheduledPayoutsUseCaseMock.execute).toHaveBeenCalledWith() + expect(processScheduledPayoutsUseCaseMock.execute.mock.calls[0]).toHaveLength(0) + }) + }) +}) diff --git a/apps/mass-payout/backend/tsconfig.build.json b/apps/mass-payout/backend/tsconfig.build.json new file mode 100644 index 000000000..64f86c6bd --- /dev/null +++ b/apps/mass-payout/backend/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] +} diff --git a/apps/mass-payout/backend/tsconfig.json b/apps/mass-payout/backend/tsconfig.json new file mode 100644 index 000000000..63e546422 --- /dev/null +++ b/apps/mass-payout/backend/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "module": "commonjs", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ES2021", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": false, + "noImplicitAny": false, + "strictBindCallApply": false, + "forceConsistentCasingInFileNames": false, + "noFallthroughCasesInSwitch": false, + "paths": { + "@domain/*": ["./src/domain/*"], + "@application/*": ["./src/application/*"], + "@infrastructure/*": ["./src/infrastructure/*"], + "@config/*": ["./src/config/*"], + "@shared/*": ["./src/shared/*"], + "@test/*": ["./test/*"] + }, + "esModuleInterop": true + } +} diff --git a/apps/mass-payout/frontend/.env.example b/apps/mass-payout/frontend/.env.example new file mode 100644 index 000000000..126ec88cb --- /dev/null +++ b/apps/mass-payout/frontend/.env.example @@ -0,0 +1,3 @@ +NODE_ENV=local +VITE_API_URL=http://localhost:3000 +VITE_PORT=5173 diff --git a/apps/mass-payout/frontend/README.md b/apps/mass-payout/frontend/README.md new file mode 100644 index 000000000..d2a29b7e9 --- /dev/null +++ b/apps/mass-payout/frontend/README.md @@ -0,0 +1,67 @@ +# Frontend - Scheduler Payment Distribution + +Admin panel for the Scheduler Payment Distribution service built with Vite, React, and Chakra UI. + +## Table of Contents + +- [Installation](#installation) +- [Running the app](#running-the-app) +- [Test](#test) + +### Installation + +While you can install dependencies directly in this directory, it's recommended to install from the root of the monorepo: + +```bash +# From the root directory +npm install +``` + +Create a `.env` file in the frontend directory: + +```bash +cp .env.example .env +``` + +Available environment variables: + +- `VITE_API_URL`: Backend API URL +- `VITE_PORT`: Port for the development server + +### Running the App + +From the root directory: + +```bash +npm run start:frontend +``` + +Or directly from the frontend directory: + +```bash +npm run dev +``` + +### Building for Production + +From the root directory: + +```bash +npm run build +``` + +Or directly from the frontend directory: + +```bash +npm run build +``` + +## Testing + +```bash +# Run tests +npm run test + +# Run tests with coverage +npm run test:cov +``` diff --git a/apps/mass-payout/frontend/eslint.config.mjs b/apps/mass-payout/frontend/eslint.config.mjs new file mode 100644 index 000000000..8bd1bfd18 --- /dev/null +++ b/apps/mass-payout/frontend/eslint.config.mjs @@ -0,0 +1,159 @@ +import js from '@eslint/js'; +import typescript from '@typescript-eslint/eslint-plugin'; +import typescriptParser from '@typescript-eslint/parser'; +import prettier from 'eslint-plugin-prettier'; +import unusedImports from 'eslint-plugin-unused-imports'; +import react from 'eslint-plugin-react'; +import reactHooks from 'eslint-plugin-react-hooks'; +import globals from 'globals'; + +export default [ + // Ignore files + { + ignores: [ + '**/node_modules/**', + '**/dist/**', + '**/build/**', + '**/*.config.js', + '**/*.config.mjs', + '**/*.config.cjs', + '**/coverage/**', + ], + }, + + // TypeScript/React + { + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + sourceType: 'module', + parser: typescriptParser, + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module', + ecmaFeatures: { + jsx: true, + }, + }, + globals: { + ...globals.browser, + ...globals.node, + ...globals.es2020, + // TypeScript/React + React: 'readonly', + JSX: 'readonly', + RequestInit: 'readonly', + }, + }, + plugins: { + '@typescript-eslint': typescript, + prettier, + 'unused-imports': unusedImports, + react, + 'react-hooks': reactHooks, + }, + settings: { + react: { + version: 'detect', + }, + }, + rules: { + ...js.configs.recommended.rules, + ...typescript.configs.recommended.rules, + ...react.configs.recommended.rules, + ...reactHooks.configs.recommended.rules, + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + '@typescript-eslint/no-var-requires': 'off', + 'unused-imports/no-unused-imports': 'error', + 'prettier/prettier': [ + 'error', + { + endOfLine: 'auto', + }, + ], + 'react/react-in-jsx-scope': 'off', + 'react/prop-types': 'off', + 'react-hooks/exhaustive-deps': 'off', + }, + }, + + // test + { + files: [ + '**/*.test.{ts,tsx}', + '**/*.spec.{ts,tsx}', + '**/__tests__/**/*.{ts,tsx}', + '**/test-utils/**/*.{ts,tsx}', + ], + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + ...globals.es2020, + ...globals.jest, + React: 'readonly', + JSX: 'readonly', + }, + }, + rules: { + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + ignoreRestSiblings: true, + }, + ], + 'no-console': 'off', + 'react-hooks/exhaustive-deps': 'off', + }, + }, + + // mocks + { + files: [ + '**/mocks/**/*.{ts,tsx}', + '**/__mocks__/**/*.{ts,tsx}', + '**/test-utils/**/*.{ts,tsx}', + ], + languageOptions: { + globals: { + ...globals.browser, + ...globals.node, + ...globals.es2020, + ...globals.jest, + }, + }, + rules: { + '@typescript-eslint/ban-ts-comment': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-unused-vars': 'off', + 'no-console': 'off', + }, + }, + + // deprecated + { + files: ['**/deprecated/**/*.{ts,tsx}'], + rules: { + 'no-undef': 'off', + 'react/jsx-no-undef': 'off', + '@typescript-eslint/no-var-requires': 'off', + 'react-hooks/exhaustive-deps': 'off', + }, + }, +]; diff --git a/apps/mass-payout/frontend/index.html b/apps/mass-payout/frontend/index.html new file mode 100644 index 000000000..e6beb99f4 --- /dev/null +++ b/apps/mass-payout/frontend/index.html @@ -0,0 +1,217 @@ + + + + + + + + + Scheduler Payment Distribution + + +
+ + + diff --git a/apps/mass-payout/frontend/jest.config.cjs b/apps/mass-payout/frontend/jest.config.cjs new file mode 100644 index 000000000..b13c7e0ec --- /dev/null +++ b/apps/mass-payout/frontend/jest.config.cjs @@ -0,0 +1,35 @@ +process.env.TZ = 'GMT'; + +module.exports = { + testEnvironment: 'jest-environment-jsdom', + preset: 'ts-jest', + ci: true, + testTimeout: 30000, + transform: { + '^.+\\.(ts|tsx)$': [ + 'ts-jest', + { + isolatedModules: true, + tsconfig: { + module: 'esnext', + moduleResolution: 'node', + }, + }, + ], + '^.+\\.svg$': '/svgTransform.js', + '^.+\\.(js|jsx)$': 'babel-jest', + }, + moduleFileExtensions: ['tsx', 'ts', 'js', 'jsx'], + setupFilesAfterEnv: ['/jest.setup.tsx'], + moduleNameMapper: { + '\\.(css|less|scss|sass|ttf|png)$': 'ts-jest', + '^@/(.*)$': '/src/$1', + }, + collectCoverageFrom: [ + '**/views/**/*.{ts,tsx}', + '**/components/**/*.{ts,tsx}', + '**/layouts/**/*.{ts,tsx}', + '!**/node_modules/**', + '!**/vendor/**', + ], +}; diff --git a/apps/mass-payout/frontend/jest.setup.tsx b/apps/mass-payout/frontend/jest.setup.tsx new file mode 100644 index 000000000..5a17f0066 --- /dev/null +++ b/apps/mass-payout/frontend/jest.setup.tsx @@ -0,0 +1,126 @@ +import '@testing-library/jest-dom'; +import React from 'react'; +import { mockTranslations } from './mockTranslations'; + +(globalThis as any).importMeta = { + env: { + VITE_API_URL: 'http://localhost:3000/api', + }, +}; + +Object.defineProperty(globalThis, 'import', { + value: { + meta: { + env: { + VITE_API_URL: 'http://localhost:3000/api', + }, + }, + }, + writable: true, + configurable: true, +}); + +(global as any).import = { + meta: { + env: { + VITE_API_URL: 'http://localhost:3000/api', + }, + }, +}; + +jest.mock('i18next', () => ({ + use: jest.fn().mockReturnThis(), + init: jest.fn(), + t: jest.fn((key) => mockTranslations[key] || key), + changeLanguage: jest.fn(), + language: 'en', + getFixedT: jest.fn(), +})); + +jest.mock('react-i18next', () => ({ + useTranslation: (namespace?: string) => ({ + t: jest.fn((key) => { + const fullKey = namespace ? `${namespace}:${key}` : key; + return mockTranslations[key] || mockTranslations[fullKey] || key; + }), + i18n: { + changeLanguage: jest.fn(), + language: 'en', + }, + }), + Trans: ({ children }: { children: React.ReactNode }) => children, + initReactI18next: { + type: 'i18next', + init: jest.fn(), + }, + I18nextProvider: ({ children }: { children: React.ReactNode }) => children, +})); + +jest.mock('i18next-browser-languagedetector', () => jest.fn()); + +jest.mock('./src/i18n/config', () => ({ + __esModule: true, + default: { + use: jest.fn().mockReturnThis(), + init: jest.fn(), + t: jest.fn((key) => mockTranslations[key] || key), + changeLanguage: jest.fn(), + language: 'en', + getFixedT: jest.fn(), + }, +})); + +jest.mock('./src/router/RouterManager', () => ({ + RouterManager: { + to: jest.fn(), + getUrl: jest.fn(), + goBack: jest.fn(), + }, +})); + +jest.mock('lodash/omit', () => ({ + __esModule: true, + default: (obj: Record, keys: string | string[]) => { + const result = { ...obj }; + if (Array.isArray(keys)) { + keys.forEach((key: string) => delete result[key]); + } else { + delete result[keys]; + } + return result; + }, +})); + +Object.defineProperty(window, 'matchMedia', { + writable: true, + value: jest.fn().mockImplementation((query) => ({ + matches: false, + media: query, + onchange: null, + addListener: jest.fn(), + removeListener: jest.fn(), + addEventListener: jest.fn(), + removeEventListener: jest.fn(), + dispatchEvent: jest.fn(), + })), +}); + +const noop = () => {}; +Object.defineProperty(window, 'scrollTo', { value: noop, writable: true }); + +const originalError = console.error; +beforeAll(() => { + console.error = (...args: any[]) => { + if ( + typeof args[0] === 'string' && + args[0].includes('ReactDOMTestUtils.act') + ) { + return; + } + originalError.call(console, ...args); + }; +}); + +afterAll(() => { + console.error = originalError; +}); diff --git a/apps/mass-payout/frontend/mockTranslations.ts b/apps/mass-payout/frontend/mockTranslations.ts new file mode 100644 index 000000000..d96e70994 --- /dev/null +++ b/apps/mass-payout/frontend/mockTranslations.ts @@ -0,0 +1,227 @@ +export const mockTranslations: Record = { + // Asset Detail translations + 'detail.status.active': 'Active', + 'detail.status.paused': 'Paused', + distributionsStatus: 'Distributions status:', + 'detail.buttons.pausePayments': 'Pause Lifecycle', + 'detail.buttons.unpausePayments': 'Unpause Lifecycle', + 'detail.buttons.makePayment': 'Make a Payment', + 'detail.tabs.details': 'Details', + 'detail.tabs.details.title': 'Details', + 'detail.tabs.details.name': 'Name', + 'detail.tabs.details.symbol': 'Symbol', + 'detail.tabs.details.maturityDate': 'Maturity Date', + 'detail.tabs.details.assetId': 'Asset ID', + 'detail.tabs.details.assetEvmAdress': 'Asset EVM Address', + 'detail.tabs.details.distributionsSC': 'Distributions SC', + 'detail.tabs.details.lifecycleEvmAdress': 'Lifecycle EVM Address', + 'detail.tabs.details.type': 'Type', + 'detail.tabs.distributions': 'Distributions', + 'detail.tabs.dividends': 'Distributions', + 'detail.tabs.coupons': 'Coupons', + 'detail.tabs.payments': 'Payments', + 'detail.tabs.failedHolders': 'Corporate Actions Distribution Details', + 'detail.search.placeholder': 'Search by wallet address...', + 'detail.buttons.newDistribution': 'New Distribution', + + // Loading and error messages + loading: 'Loading asset...', + error: 'Error loading asset or asset not found', + + // Routes translations + 'routes:ASSETS': 'Assets', + 'routes:ASSET_DETAIL': 'Asset Detail', + + // FailedHolders translations + 'failedHolders:title': 'Corporate Actions Distribution Details', + 'failedHolders:failedMessage': + 'This payment has failed holders that need to be retried', + + // AssetPayments translations + 'detail.tabs.paymentsTab.subtitle': 'Payments', + 'detail.tabs.paymentsTab.paymentId': 'Payment ID', + 'detail.tabs.paymentsTab.paymentType': 'Payment Type', + 'detail.tabs.paymentsTab.creationDate': 'Creation date', + 'detail.tabs.paymentsTab.paidAmount': 'Paid amount', + 'detail.tabs.paymentsTab.status': 'Status', + 'detail.tabs.paymentsTab.batchCount': 'Batch Count', + 'detail.tabs.paymentsTab.holders': 'Holders', + + // Popup translations + 'detail.popup.pause.title': 'Pause Asset', + 'detail.popup.pause.description': + 'Are you sure you want to pause this asset?', + 'detail.popup.pause.confirmText': 'Pause', + 'detail.popup.pause.cancelText': 'Cancel', + 'detail.popup.unpause.title': 'Unpause Asset', + 'detail.popup.unpause.description': + 'Are you sure you want to unpause this asset?', + 'detail.popup.unpause.confirmText': 'Unpause', + 'detail.popup.unpause.cancelText': 'Cancel', + + // ImportAsset translations + importAsset: 'Import Asset', + title: 'Import Asset', + 'header.details': 'Details', + 'header.review': 'Review', + 'details.title': 'Asset Details', + 'details.subtitle': 'Enter the asset details', + 'details.description': 'Please provide the asset ID to import the asset', + 'details.assetInfo': 'Asset Information', + 'details.assetName': 'Asset Name: {{name}}', + 'details.symbol': 'Symbol: {{symbol}}', + 'details.assetType': 'Asset Type: {{type}}', + 'form.assetId.label': 'Asset ID', + 'form.assetId.placeholder': 'Enter Asset ID', + 'form.assetId.required': 'Asset ID is required', + 'buttons.nextStep': 'Next Step', + 'buttons.previousStep': 'Previous Step', + 'buttons.cancel': 'Cancel', + 'review.assetConfiguration': 'Asset Configuration', + + // ImportAsset translations with namespace + 'importAsset:title': 'Import Asset', + 'importAsset:header.details': 'Details', + 'importAsset:header.review': 'Review', + 'importAsset:details.title': 'Asset Details', + 'importAsset:details.subtitle': 'Enter the asset details', + 'importAsset:details.description': + 'Please provide the asset ID to import the asset', + 'importAsset:details.assetInfo': 'Asset Information', + 'importAsset:details.assetName': 'Asset Name: {{name}}', + 'importAsset:details.symbol': 'Symbol: {{symbol}}', + 'importAsset:details.assetType': 'Asset Type: {{type}}', + 'importAsset:form.assetId.label': 'Asset ID', + 'importAsset:form.assetId.placeholder': 'Enter Asset ID', + 'importAsset:form.assetId.required': 'Asset ID is required', + 'importAsset:buttons.nextStep': 'Next Step', + 'importAsset:buttons.previousStep': 'Previous Step', + 'importAsset:buttons.cancel': 'Cancel', + 'importAsset:review.assetConfiguration': 'Asset Configuration', + + // NewDistribution translations + 'newDistribution.title': 'New Distribution', + 'newDistribution.assetId': 'Asset ID', + 'newDistribution.assetName': 'Asset Name', + 'newDistribution.assetType': 'Asset Type', + 'newDistribution.selectType': 'Select Distribution Type', + 'newDistribution.configuration': 'Payment Configuration', + 'newDistribution.subtitle': 'Configure your payment details', + 'newDistribution.description': + 'Please provide the payment configuration details', + 'newDistribution.paymentType': 'Payment Type', + 'newDistribution.fixed': 'Fixed Amount', + 'newDistribution.percentage': 'Percentage', + 'newDistribution.amount': 'Amount', + 'newDistribution.popup.title': 'Create Distribution', + 'newDistribution.popup.subtitle': 'Please confirm the payment details', + 'newDistribution.popup.description': + 'Are you sure you want to create this distribution?', + 'newDistribution.popup.confirm': 'Create', + 'newDistribution.popup.cancel': 'Cancel', + 'newDistribution.buttons.makePayment': 'Make Payment', + 'newDistribution.buttons.cancel': 'Cancel', + 'newDistribution.buttons.createDistribution': 'Create Distribution', + 'newDistribution.form.distributionType.label': 'Distribution Type', + 'newDistribution.form.distributionType.placeholder': 'Select type', + 'newDistribution.form.distributionType.required': + 'Distribution type is required', + 'newDistribution.concept': 'Concept', + 'newDistribution.conceptPlaceholder': 'Enter payment concept', + 'newDistribution.selectInfo': + 'Choose the type of distribution you want to create', + 'newDistribution.distributionType.manual': 'Manual', + 'newDistribution.distributionType.scheduled': 'Scheduled', + 'newDistribution.distributionType.recurring': 'Recurring', + 'newDistribution.distributionType.automated': 'Automated', + 'newDistribution.recurringOptions.label': 'Recurring Frequency', + 'newDistribution.recurringOptions.hourly': 'Hourly', + 'newDistribution.recurringOptions.daily': 'Daily', + 'newDistribution.recurringOptions.weekly': 'Weekly', + 'newDistribution.recurringOptions.monthly': 'Monthly', + 'newDistribution.trigerCondition': 'Trigger Condition', + 'newDistribution.triggerConditionOptions.onDeposit': 'On Deposit', + 'newDistribution.scheduledExecutionTime': 'Scheduled Execution Time', + 'newDistribution.selectDateAndTime': 'Select date and time', + 'newDistribution.startTime': 'Start Time', + 'newDistribution.validation.amountRequired': 'Amount is required', + 'newDistribution.validation.minimumAmountFixed': 'Minimum amount is $0.01', + 'newDistribution.validation.minimumAmountPercentage': + 'Minimum percentage is 0.01%', + 'newDistribution.validation.scheduledDateRequired': + 'Scheduled date is required', + 'newDistribution.validation.futureDateRequired': 'Date must be in the future', + 'newDistribution.validation.startDateRequired': 'Start date is required', + 'newDistribution.popup.confirmText': 'Create', + 'newDistribution.popup.cancelText': 'Cancel', + + // NewDistribution with namespace + 'newDistribution:title': 'New Distribution', + 'newDistribution:assetId': 'Asset ID', + 'newDistribution:assetName': 'Asset Name', + 'newDistribution:assetType': 'Asset Type', + 'newDistribution:selectType': 'Select Distribution Type', + 'newDistribution:configuration': 'Payment Configuration', + 'newDistribution:subtitle': 'Configure your payment details', + 'newDistribution:paymentType': 'Payment Type', + 'newDistribution:fixed': 'Fixed Amount', + 'newDistribution:percentage': 'Percentage', + 'newDistribution:amount': 'Amount', + 'newDistribution:popup.title': 'Create Distribution', + 'newDistribution:popup.subtitle': 'Please confirm the payment details', + 'newDistribution:popup.description': + 'Are you sure you want to create this distribution?', + 'newDistribution:popup.confirm': 'Create', + 'newDistribution:popup.cancel': 'Cancel', + 'newDistribution:buttons.makePayment': 'Make Payment', + 'newDistribution:buttons.cancel': 'Cancel', + 'newDistribution:buttons.createDistribution': 'Create Distribution', + 'newDistribution:form.distributionType.label': 'Distribution Type', + 'newDistribution:form.distributionType.placeholder': 'Select type', + 'newDistribution:form.distributionType.required': + 'Distribution type is required', + + // AssetDistributions translations + 'subTabs.upcoming': 'Upcoming', + 'subTabs.ongoing': 'Ongoing', + 'subTabs.completed': 'Completed', + 'Pause Distributions': 'Pause Distributions', + 'Unpause Distributions': 'Unpause Distributions', + 'New Distribution': 'New Distribution', + 'Not importing corporate actions': 'Not importing corporate actions', + 'Importing corporate actions': 'Importing corporate actions', + 'Upcoming Distributions': 'Upcoming Distributions', + 'Ongoing Distributions': 'Ongoing Distributions', + 'Completed Distributions': 'Completed Distributions', + 'detail.buttons.unpauseDistributions': 'Unpause Distributions', + 'detail.buttons.pauseDistributions': 'Pause Distributions', + 'detail.buttons.notImportCorporateActions': 'Import Corporate Actions', + 'detail.buttons.importCorporateActions': 'Import Corporate Actions', + + // DistributionsDetails translations + 'Distribution Details': 'Distribution Details', + 'Distribution ID': 'Distribution ID', + 'Payment ID': 'Payment ID', + 'Receiver Address (Hedera)': 'Receiver Address (Hedera)', + 'Receiver Address (EVM)': 'Receiver Address (EVM)', + Amount: 'Amount', + 'Execution Date': 'Execution Date', + 'Transaction Hash': 'Transaction Hash', + Status: 'Status', + 'Go Back': 'Go Back', + 'Retry All': 'Retry All', + Holders: 'Holders', + + // DistributionsDetails with namespace + 'distributionsDetails:title': 'Distribution Details', + 'distributionsDetails:Distribution Details': 'Distribution Details', + 'distributionsDetails:Holders': 'Holders', + + // Common table and UI translations + Search: 'Search', + Previous: 'Previous', + Next: 'Next', + Loading: 'Loading', + Error: 'Error', + 'No data available': 'No data available', +}; diff --git a/apps/mass-payout/frontend/package.json b/apps/mass-payout/frontend/package.json new file mode 100644 index 000000000..579fc228d --- /dev/null +++ b/apps/mass-payout/frontend/package.json @@ -0,0 +1,78 @@ +{ + "name": "@mass-payout/frontend", + "version": "1.0.0", + "description": "UI for scheduler payment distribution", + "private": true, + "scripts": { + "setup": "npm install", + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview", + "lint": "eslint src --ext ts,tsx --cache", + "lint:fix": "eslint \"src/**/*.{ts,tsx}\" --fix", + "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"", + "test": "NODE_ENV=test jest --ci --runInBand", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "clean": "rimraf dist", + "clean:deps": "rimraf node_modules" + }, + "dependencies": { + "@chakra-ui/react": "2.6.1", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@phosphor-icons/react": "2.1.7", + "@tanstack/react-query": "^5.28.4", + "add": "^2.0.6", + "framer-motion": "^10.16.4", + "i18next": "23.10.1", + "i18next-browser-languagedetector": "7.2.0", + "io-bricks-ui": "2.7.4", + "named-urls": "2.0.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-hook-form": "7.41.5", + "react-i18next": "13.2.0", + "react-router-dom": "6.10.0", + "use-react-router-breadcrumbs": "^4.0.1", + "zustand": "4.5.2" + }, + "devDependencies": { + "@babel/preset-env": "^7.21.4", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.5", + "@chakra-ui/cli": "^2.4.1", + "@esbuild-plugins/node-globals-polyfill": "^0.2.3", + "@esbuild-plugins/node-modules-polyfill": "^0.2.2", + "@testing-library/jest-dom": "6.4.2", + "@testing-library/react": "14.2.1", + "@testing-library/user-event": "14.5.2", + "@types/add": "^2", + "@types/jest": "29.5.1", + "@types/node": "20.11.30", + "@types/react": "18.2.73", + "@types/react-dom": "18.2.22", + "@typescript-eslint/eslint-plugin": "7.4.0", + "@typescript-eslint/parser": "7.4.0", + "@vitejs/plugin-react-swc": "3.6.0", + "@vitest/coverage-v8": "1.4.0", + "eslint": "8.57.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-prettier": "5.1.3", + "eslint-plugin-react": "7.34.1", + "eslint-plugin-unused-imports": "3.2.0", + "eslint-plugin-react-hooks": "4.6.0", + "history": "5.3.0", + "jest": "29.5.0", + "jest-environment-jsdom": "29.5.0", + "jsdom": "24.0.0", + "prettier": "3.2.5", + "ts-jest": "29.1.0", + "typescript": "5.3.3", + "vite": "5.2.6", + "vite-plugin-compression2": "1.3.3", + "vite-plugin-environment": "^1.1.3", + "vite-tsconfig-paths": "4.3.2", + "vitest": "1.4.0" + } +} diff --git a/apps/mass-payout/frontend/src/App.tsx b/apps/mass-payout/frontend/src/App.tsx new file mode 100644 index 000000000..1e3e453a5 --- /dev/null +++ b/apps/mass-payout/frontend/src/App.tsx @@ -0,0 +1,209 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import AppRouter from './router'; + +export const App = () => { + return ; +}; diff --git a/apps/mass-payout/frontend/src/assets/logo.svg b/apps/mass-payout/frontend/src/assets/logo.svg new file mode 100644 index 000000000..734724201 --- /dev/null +++ b/apps/mass-payout/frontend/src/assets/logo.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/mass-payout/frontend/src/components/FormStepContainer.tsx b/apps/mass-payout/frontend/src/components/FormStepContainer.tsx new file mode 100644 index 000000000..1d194ff78 --- /dev/null +++ b/apps/mass-payout/frontend/src/components/FormStepContainer.tsx @@ -0,0 +1,212 @@ +/* + 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. + +*/ + +import { StackProps, VStack } from '@chakra-ui/react'; + +export const FormStepContainer = ({ children }: StackProps) => ( + + {children} + +); diff --git a/apps/mass-payout/frontend/src/components/GobackButton.tsx b/apps/mass-payout/frontend/src/components/GobackButton.tsx new file mode 100644 index 000000000..fd65139b8 --- /dev/null +++ b/apps/mass-payout/frontend/src/components/GobackButton.tsx @@ -0,0 +1,263 @@ +/* + 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. + +*/ + +import { IconButton, Text, PhosphorIcon } from 'io-bricks-ui'; +import { Flex, FlexProps } from '@chakra-ui/react'; +import { ArrowLeft } from '@phosphor-icons/react'; +import { Link as RouterLink } from 'react-router-dom'; +import type { To } from 'react-router-dom'; +import { RouterManager } from '../router/RouterManager'; +import { RouteName } from '../router/RouteName'; +import { useLocationStore } from '@/store/locationStore'; + +export interface GobackButtonProps extends FlexProps { + label: string; + to?: To; +} + +export const GobackButton = (props: GobackButtonProps) => { + const { label, to, ...buttonProps } = props; + const { getGoBackPath, getGoBackAction } = useLocationStore(); + + const navigationActions = { + 'navigate-to-assets': () => RouterManager.to(RouteName.Assets), + 'navigate-to-landing': () => RouterManager.goLanding(), + 'navigate-back': () => RouterManager.goBack(), + } as const; + + const handleGoBack = () => { + const action = getGoBackAction(); + const navigationFunction = + navigationActions[action] || navigationActions['navigate-back']; + navigationFunction(); + }; + + return ( + + } + size="md" + variant="secondary" + {...(to + ? { + as: RouterLink, + to: getGoBackPath(typeof to === 'string' ? to : undefined), + } + : { + onClick: handleGoBack, + })} + /> + + {label} + + + ); +}; diff --git a/packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/AccessControlTimeTravel.sol b/apps/mass-payout/frontend/src/components/History.tsx similarity index 92% rename from packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/AccessControlTimeTravel.sol rename to apps/mass-payout/frontend/src/components/History.tsx index 73154c06c..404fe3846 100644 --- a/packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/AccessControlTimeTravel.sol +++ b/apps/mass-payout/frontend/src/components/History.tsx @@ -203,36 +203,29 @@ */ -// SPDX-License-Identifier: BSD-3-Clause-Attribution -pragma solidity 0.8.18; - -import { - AccessControlFacet -} from '../../../layer_1/accessControl/AccessControlFacet.sol'; -import { - TimeTravelStorageWrapper -} from '../timeTravel/TimeTravelStorageWrapper.sol'; -import {LocalContext} from '../../../layer_0/context/LocalContext.sol'; - -contract AccessControlFacetTimeTravel is - AccessControlFacet, - TimeTravelStorageWrapper -{ - function _blockTimestamp() - internal - view - override(LocalContext, TimeTravelStorageWrapper) - returns (uint256) - { - return TimeTravelStorageWrapper._blockTimestamp(); - } - - function _blockNumber() - internal - view - override(LocalContext, TimeTravelStorageWrapper) - returns (uint256) - { - return TimeTravelStorageWrapper._blockNumber(); - } +import { useBreadcrumbs } from '@/hooks/useBreadcrumbs'; +import { Flex, VStack } from '@chakra-ui/react'; +import type { StackProps } from '@chakra-ui/react'; +import { Breadcrumb } from 'io-bricks-ui'; +import type { Options } from 'use-react-router-breadcrumbs'; +import { GobackButtonProps, GobackButton } from './GobackButton'; + +export interface HistoryProps extends StackProps { + label: GobackButtonProps['label']; + to?: GobackButtonProps['to']; + excludePaths?: Options['excludePaths']; } + +export const History = (props: HistoryProps) => { + const { label, to, excludePaths, ...stackProps } = props; + const routes = useBreadcrumbs({ excludePaths }); + + return ( + + + + + + + ); +}; diff --git a/apps/mass-payout/frontend/src/components/__tests__/FormStepContainer.test.tsx b/apps/mass-payout/frontend/src/components/__tests__/FormStepContainer.test.tsx new file mode 100644 index 000000000..5f332d38c --- /dev/null +++ b/apps/mass-payout/frontend/src/components/__tests__/FormStepContainer.test.tsx @@ -0,0 +1,220 @@ +/* + 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. + +*/ + +import { FormStepContainer } from '../FormStepContainer'; +import { render } from '../../test-utils'; +import { Text } from 'io-bricks-ui'; + +describe(`${FormStepContainer.name}`, () => { + test('should render correctly', () => { + const component = render( + + TESTING + , + ); + + expect(component.asFragment()).toMatchSnapshot(); + }); +}); diff --git a/apps/mass-payout/frontend/src/components/__tests__/GobackButton.test.tsx b/apps/mass-payout/frontend/src/components/__tests__/GobackButton.test.tsx new file mode 100644 index 000000000..52e564f8c --- /dev/null +++ b/apps/mass-payout/frontend/src/components/__tests__/GobackButton.test.tsx @@ -0,0 +1,276 @@ +/* + 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. + +*/ + +import { GobackButton, GobackButtonProps } from '../GobackButton'; +import { render } from '../../test-utils'; +import { RouteName } from '../../router/RouteName'; +import { RouterManager } from '../../router/RouterManager'; +import { RoutePath } from '../../router/RoutePath'; +import userEvent from '@testing-library/user-event'; +import { waitFor } from '@testing-library/react'; + +jest.mock('../../router/RouterManager', () => ({ + RouterManager: { + ...jest.requireActual('../../router/RouterManager').RouterManager, + goBack: jest.fn(), + getUrl: jest.fn(), + }, +})); + +const defaultProps: GobackButtonProps = { + label: RouteName.Assets, +}; + +describe(`${GobackButton.name}`, () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test('should render correctly without to prop', () => { + const component = render(); + + expect(component.asFragment()).toMatchSnapshot('withoutTo'); + }); + + test('should render correctly with to prop', () => { + const component = render( + , + ); + + expect(component.asFragment()).toMatchSnapshot('withTo'); + }); + + test('should have a label', () => { + const component = render(); + + const label = component.getByTestId('go-back-button-label'); + expect(label).toHaveTextContent(defaultProps.label); + }); + + test('if have to prop should redirect to desired route', () => { + const component = render( + , + ); + + expect(component.getByRole('link')).toHaveAttribute( + 'href', + RoutePath.ASSETS, + ); + }); + + test('if not have to prop shoul render as a button and goback to previous route on click', async () => { + const component = render(); + + const button = component.getByTestId('go-back-button-button'); + userEvent.click(button); + + await waitFor(() => { + expect(RouterManager.goBack).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/packages/ats/contracts/scripts/commands/DeployTransparentProxyCommand.ts b/apps/mass-payout/frontend/src/components/__tests__/History.test.tsx similarity index 93% rename from packages/ats/contracts/scripts/commands/DeployTransparentProxyCommand.ts rename to apps/mass-payout/frontend/src/components/__tests__/History.test.tsx index b219f25c7..93ebe0665 100644 --- a/packages/ats/contracts/scripts/commands/DeployTransparentProxyCommand.ts +++ b/apps/mass-payout/frontend/src/components/__tests__/History.test.tsx @@ -203,26 +203,29 @@ */ -import { BaseBlockchainCommand, BaseBlockchainCommandParams } from '../index' - -interface DeployUpgradeableProxyCommandParams - extends BaseBlockchainCommandParams { - proxyAdminAddress: string - implementationAddress: string -} - -export default class DeployUpgradeableProxyCommand extends BaseBlockchainCommand { - public readonly proxyAdminAddress: string - public readonly implementationAddress: string - - constructor({ - proxyAdminAddress, - implementationAddress, - signer, - overrides, - }: DeployUpgradeableProxyCommandParams) { - super({ signer, overrides }) - this.proxyAdminAddress = proxyAdminAddress - this.implementationAddress = implementationAddress - } -} +import { History, HistoryProps } from '../History'; +import { render } from '../../test-utils'; + +const defaultProps: HistoryProps = { + label: 'Go Back', +}; + +describe(`${History.name}`, () => { + test('should render correctly', () => { + const component = render(); + + expect(component.asFragment()).toMatchSnapshot(); + }); + + test('should have a goback button', () => { + const component = render(); + + expect(component.getByTestId('go-back-button')).toBeInTheDocument(); + }); + + test('should have a breadcrumb', () => { + const component = render(); + + expect(component.getByTestId('breadcrumb-desktop')).toBeInTheDocument(); + }); +}); diff --git a/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/FormStepContainer.test.tsx.snap b/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/FormStepContainer.test.tsx.snap new file mode 100644 index 000000000..3a0c3bf87 --- /dev/null +++ b/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/FormStepContainer.test.tsx.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`FormStepContainer should render correctly 1`] = ` + +
+

+ TESTING +

+
+
+`; diff --git a/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/GobackButton.test.tsx.snap b/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/GobackButton.test.tsx.snap new file mode 100644 index 000000000..4ecf4f7e2 --- /dev/null +++ b/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/GobackButton.test.tsx.snap @@ -0,0 +1,83 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`GobackButton should render correctly with to prop: withTo 1`] = ` + +
+ +

+ ASSETS +

+
+
+`; + +exports[`GobackButton should render correctly without to prop: withoutTo 1`] = ` + +
+ +

+ ASSETS +

+
+
+`; diff --git a/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/History.test.tsx.snap b/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/History.test.tsx.snap new file mode 100644 index 000000000..e9255c158 --- /dev/null +++ b/apps/mass-payout/frontend/src/components/__tests__/__snapshots__/History.test.tsx.snap @@ -0,0 +1,59 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`History should render correctly 1`] = ` + +
+ +
+
+ +

+ Go Back +

+
+
+
+
+`; diff --git a/apps/mass-payout/frontend/src/env.d.ts b/apps/mass-payout/frontend/src/env.d.ts new file mode 100644 index 000000000..3a411fd75 --- /dev/null +++ b/apps/mass-payout/frontend/src/env.d.ts @@ -0,0 +1,215 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +/** + * Type definitions for Vite environment variables + */ +interface ImportMetaEnv { + readonly VITE_API_URL: string; + readonly VITE_PORT: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} diff --git a/packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/ScheduledTasksTimeTravel.sol b/apps/mass-payout/frontend/src/hooks/useBreadcrumbs.tsx similarity index 85% rename from packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/ScheduledTasksTimeTravel.sol rename to apps/mass-payout/frontend/src/hooks/useBreadcrumbs.tsx index 0b1991c15..7894a3038 100644 --- a/packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/ScheduledTasksTimeTravel.sol +++ b/apps/mass-payout/frontend/src/hooks/useBreadcrumbs.tsx @@ -203,33 +203,81 @@ */ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.18; - -import { - ScheduledTasks -} from '../../../layer_2/scheduledTasks/scheduledTasks/ScheduledTasks.sol'; -import { - TimeTravelStorageWrapper -} from '../timeTravel/TimeTravelStorageWrapper.sol'; -import {LocalContext} from '../../../layer_0/context/LocalContext.sol'; - -contract ScheduledTasksTimeTravel is ScheduledTasks, TimeTravelStorageWrapper { - function _blockTimestamp() - internal - view - override(LocalContext, TimeTravelStorageWrapper) - returns (uint256) - { - return TimeTravelStorageWrapper._blockTimestamp(); +import { useLocation } from 'react-router-dom'; +import { Link as RouterLink } from 'react-router-dom'; +import { RoutePath } from '../router/RoutePath'; +import { RouteName } from '../router/RouteName'; +import i18n from 'i18next'; + +export interface BreadcrumbItem { + label: string; + link: { + as: typeof RouterLink; + to: string; + }; + isActive?: boolean; +} + +interface RouterBreadcrumbsOptions { + excludePaths?: string[]; +} + +const t = (key: RouteName) => i18n.t(`routes:${key}`); + +const routeBreadcrumbMap: Record = { + [RoutePath.LANDING]: t(RouteName.Landing), + [RoutePath.ASSETS]: t(RouteName.Assets), + [RoutePath.IMPORT_ASSET]: t(RouteName.ImportAsset), +}; + +export const useBreadcrumbs = ( + options?: RouterBreadcrumbsOptions, +): BreadcrumbItem[] => { + const location = useLocation(); + const { excludePaths = [] } = options || {}; + + const pathSegments = location.pathname.split('/').filter(Boolean); + const breadcrumbs: BreadcrumbItem[] = []; + + let currentPath = ''; + + for (let i = 0; i < pathSegments.length; i++) { + const segment = pathSegments[i]; + currentPath += `/${segment}`; + + if (excludePaths.includes(currentPath)) { + continue; } - function _blockNumber() - internal - view - override(LocalContext, TimeTravelStorageWrapper) - returns (uint256) - { - return TimeTravelStorageWrapper._blockNumber(); + let breadcrumbLabel = routeBreadcrumbMap[currentPath]; + + if ( + !breadcrumbLabel && + currentPath.startsWith('/assets/') && + currentPath !== '/assets' + ) { + if (currentPath.endsWith('/make-payment')) { + breadcrumbLabel = 'Make Payment'; + } else { + breadcrumbLabel = t(RouteName.AssetDetail); + } } -} + + if (!breadcrumbLabel) { + breadcrumbLabel = segment.charAt(0).toUpperCase() + segment.slice(1); + } + + const isLastElement = i === pathSegments.length - 1; + + breadcrumbs.push({ + label: breadcrumbLabel, + link: { + as: RouterLink, + to: isLastElement ? '#' : currentPath, + }, + isActive: isLastElement, + }); + } + + return breadcrumbs; +}; diff --git a/apps/mass-payout/frontend/src/hooks/useTable.tsx b/apps/mass-payout/frontend/src/hooks/useTable.tsx new file mode 100644 index 000000000..bc56c7f06 --- /dev/null +++ b/apps/mass-payout/frontend/src/hooks/useTable.tsx @@ -0,0 +1,236 @@ +/* + 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. + +*/ + +import type { Dispatch, SetStateAction } from 'react'; +import { useState } from 'react'; +import type { PaginationState, SortingState } from '@tanstack/react-table'; + +export interface UseTableReturn { + pagination: { + pageIndex: number; + pageSize: number; + }; + setPagination: Dispatch>; + sorting: SortingState; + setSorting: Dispatch>; +} + +export const useTable = (): UseTableReturn => { + const [{ pageIndex, pageSize }, setPagination] = useState({ + pageIndex: 0, + pageSize: 8, + }); + const [sorting, setSorting] = useState([]); + + return { + pagination: { + pageIndex, + pageSize, + }, + setPagination, + sorting, + setSorting, + }; +}; diff --git a/apps/mass-payout/frontend/src/i18n/config.ts b/apps/mass-payout/frontend/src/i18n/config.ts new file mode 100644 index 000000000..82d517be1 --- /dev/null +++ b/apps/mass-payout/frontend/src/i18n/config.ts @@ -0,0 +1,236 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import LanguageDetector from 'i18next-browser-languagedetector'; +import enTranslation from './locales/en'; +import assetsTranslation from './locales/assets'; +import routesTranslation from './locales/routes'; +import distributionsTranslation from './locales/distributions'; +import importAssetTranslation from './locales/importAsset'; +import distributionsDetailsTranslation from './locales/distributionsDetails'; + +i18n + .use(LanguageDetector) + .use(initReactI18next) + .init({ + resources: { + en: { + translation: enTranslation, + routes: routesTranslation, + assets: assetsTranslation, + distributions: distributionsTranslation, + importAsset: importAssetTranslation, + distributionsDetails: distributionsDetailsTranslation, + }, + }, + fallbackLng: 'en', + + interpolation: { + escapeValue: false, + }, + }); + +export default i18n; diff --git a/apps/mass-payout/frontend/src/i18n/locales/assets.ts b/apps/mass-payout/frontend/src/i18n/locales/assets.ts new file mode 100644 index 000000000..7f44ed6a5 --- /dev/null +++ b/apps/mass-payout/frontend/src/i18n/locales/assets.ts @@ -0,0 +1,408 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +const assetsTranslation = { + title: 'Assets', + importAsset: 'Asset import', + cancelTooltipText: 'Cancel', + distributionsStatus: 'Distributions status:', + subTabs: { + upcoming: 'Upcoming', + ongoing: 'Ongoing', + completed: 'Completed', + }, + table: { + headers: { + distributionId: 'Distribution ID', + assetType: 'Asset Type', + name: 'Name', + hederaAdress: 'Asset Address (Hedera)', + maturityDate: 'Maturity date', + status: 'Status', + symbol: 'Symbol', + evmTokenAddress: 'Asset Address (EVM)', + distributionsHedera: 'Distributions SC (Hedera)', + distributionsEVM: 'Distributions SC (EVM)', + upcomingDistributions: 'Upcoming distributions', + ongoingDistributions: 'Ongoing distributions', + completedDistributions: 'Completed distributions', + }, + }, + filters: { + selectByType: 'Select by type', + searchPlaceholder: 'Search assets name, ID...', + options: { + allTypes: 'All types', + bond: 'Bond', + equity: 'Equity', + }, + distributionTypeOptions: { + allTypes: 'All types', + manual: 'Manual', + scheduled: 'Scheduled', + recurring: 'Recurring', + automated: 'Automated', + corpAction: 'Corporate Action', + }, + }, + noDistributionsYet: 'No distributions yet', + detail: { + tabs: { + details: { + title: 'Details', + symbol: 'Symbol', + maturityDate: 'Maturity date', + assetEvmAdress: 'Asset EVM Address', + lifecycleEvmAdress: 'Life cycle EVM Address', + name: 'Name', + assetId: 'Asset ID', + distributionsSC: 'Distributions SC', + type: 'Type', + }, + coupons: 'Coupons', + dividends: 'Dividends', + distributions: 'Distributions', + payments: 'Payments', + paymentsTab: { + subtitle: 'Payments List', + creationDate: 'Creation date', + paymentType: 'Payment type', + paidAmount: 'Paid amount', + batchCount: 'Batch count', + holders: 'Holders', + status: 'Status', + }, + }, + buttons: { + pauseDistributions: 'Pause Distributions', + unpauseDistributions: 'Resume Distributions', + makePayment: 'Make a Payment', + newDistribution: 'New Distribution', + importCorporateActions: 'Importing Corporate Actions', + notImportCorporateActions: 'Not importing Corporate Actions', + }, + status: { + active: 'Active', + paused: 'Paused', + completed: 'Completed', + scheduled: 'Scheduled', + inProgress: 'In Progress', + failed: 'Failed', + cancelled: 'Cancelled', + }, + popup: { + pause: { + title: 'Pause Distributions?', + description: + 'Are you sure you want to pause this asset’s cash flow lifecycle? This will pause the LifeCycleCashFlow smart contract, and all payment attempts — of any type — will fail while it is paused.\n\nNo data will be lost, and you can resume the lifecycle at any time.', + confirmText: 'Accept', + cancelText: 'Cancel', + }, + unpause: { + title: 'Resume Distributions?', + description: + "You are about to resume this asset's cash flow lifecycle. This will unpause the LifeCycleCashFlow smart contract, allowing all scheduled and future payment attempts to be processed.\n\nMake sure the asset's configuration is correct before proceeding.", + confirmText: 'Accept', + cancelText: 'Cancel', + }, + importCorporateActions: { + title: 'Import corporate actions for {{name}}', + description: + 'This will automatically import the corporate actions for this asset once a day.\n\nThe process runs in the background and may update asset data without further notice.', + confirmText: 'Accept', + cancelText: 'Cancel', + }, + stopImportCorporateActions: { + title: 'Stop importing corporate actions for {{name}}', + description: + 'This will stop the automatic import of corporate actions for this asset.', + confirmText: 'Stop importing', + cancelText: 'Cancel', + }, + cancelDistribution: { + title: 'Are you sure you want to cancel this distribution?', + description: + 'This action is permanent — the distribution will not be executed, and it cannot be resumed.', + confirmText: 'Accept', + cancelText: 'Cancel', + }, + }, + }, + newDistribution: { + title: 'New Distribution', + subtitle: 'Asset type: {{asset}} | ID: {{id}}', + configuration: 'New Distribution Configuration', + description: + 'Make a one-time distribution to holders of this asset.This action does not affect the automated lifecycle schedule.', + assetId: 'Asset ID:', + assetName: 'Asset name:', + assetType: 'Asset type:', + paymentType: 'Choose payout type:', + fixed: 'Fixed', + percentage: 'Percentage', + amount: 'Total amount', + selectType: 'Select type', + selectInfo: + '*This will send a payment automatically to holders when USDC is received.', + distributionType: { + manual: 'Manual', + scheduled: 'Scheduled', + recurring: 'Recurring', + automated: 'Automated', + }, + recurringOptions: { + label: 'Recurrency', + placeholder: 'Choose recurrency', + hourly: 'Hourly', + daily: 'Daily', + weekly: 'Weekly', + monthly: 'Monthly', + }, + triggerConditionOptions: { + onDeposit: 'On deposit', + }, + scheduledExecutionTime: 'Scheduled execution time', + startTime: 'Start time', + trigerCondition: 'Trigger condition', + concept: 'Concept', + conceptPlaceholder: 'Optional concept', + validation: { + amountRequired: 'Amount is required', + minimumAmountFixed: 'Minimum amount is $0.01', + minimumAmountPercentage: 'Minimum amount is 0.01%', + scheduledDateRequired: 'Scheduled date is required', + startDateRequired: 'Start date is required', + futureDateRequired: 'Date must be in the future', + }, + selectDateAndTime: 'Select date and time', + selectStartDateAndTime: 'Select start date and time', + buttons: { + cancel: 'Cancel', + createDistribution: 'Create Distribution', + }, + popup: { + title: 'Confirm new Distribution?', + subtitle: 'You are about to make the following distribution:', + assetId: 'Asset ID:', + assetName: 'Asset Name:', + assetType: 'Asset Type:', + amount: 'Amount:', + concept: 'Concept:', + warning: + 'Please review the details carefully. This action cannot be undone.', + confirmText: 'Confirm Distribution', + cancelText: 'Cancel', + }, + }, + toast: { + pauseSuccess: 'Asset paused successfully', + pauseError: 'Failed to pause asset', + unpauseSuccess: 'Asset unpaused successfully', + unpauseError: 'Failed to unpause asset', + }, + tooltipText: + 'Import an asset to start automated corporate actions (e.g. lifecycle payments, distributions). Additional configurations can be set afterward.', +}; + +export default assetsTranslation; diff --git a/apps/mass-payout/frontend/src/i18n/locales/distributions.ts b/apps/mass-payout/frontend/src/i18n/locales/distributions.ts new file mode 100644 index 000000000..24e5ed865 --- /dev/null +++ b/apps/mass-payout/frontend/src/i18n/locales/distributions.ts @@ -0,0 +1,279 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +const distributionsTranslation = { + title: 'Distributions', + table: { + headers: { + distributionId: 'Distribution ID', + title: 'Distributions', + distributionType: 'Distribution Type', + assetType: 'Asset Type', + assetName: 'Asset Name', + assetId: 'Asset ID', + assetEvmAddress: 'Asset EVM Address', + lifecycleCashFlowId: 'Life cycle cash flow ID', + couponId: 'Coupon ID', + dividendId: 'Dividend ID', + amount: 'Amount', + status: 'Status', + concept: 'Concept', + type: 'Type', + trigger: 'Trigger', + configuratedAmount: 'Configured amount', + distributedAmount: 'Distributed amount', + recipientHolders: 'Recipient Holders', + nextExecutionTime: 'Next Execution time', + executionStartTime: 'Execution Start time', + executionEndTime: 'Execution End time', + actions: 'Actions', + view: 'View', + }, + }, + filters: { + selectByType: 'Select by type', + searchPlaceholder: 'Search assets name, ID...', + options: { + allTypes: 'All types', + manual: 'Manual', + corporateAction: 'Corporate Action', + }, + }, + detail: { + title: 'Distribution details', + tabs: { + details: 'Details', + holders: 'Holders', + }, + sections: { + distributionBasicInformation: 'Distribution basic information', + assetDetails: 'Asset details', + }, + fields: { + distributionId: 'ID', + type: 'Type', + executionDate: 'Execution date', + maturityDate: 'Maturity date', + totalAmount: 'Total amount', + batchCount: 'Batch count', + holders: 'Holders', + assetId: 'Asset ID', + lifecycleCashFlowId: 'Lifecycle cash flow ID', + name: 'Name', + assetType: 'Type', + }, + search: { + placeholder: 'Search wallet address...', + }, + status: { + completed: 'Completed', + scheduled: 'Scheduled', + inProgress: 'In Progress', + failed: 'Failed', + cancelled: 'Cancelled', + }, + }, +}; + +export default distributionsTranslation; diff --git a/apps/mass-payout/frontend/src/i18n/locales/distributionsDetails.ts b/apps/mass-payout/frontend/src/i18n/locales/distributionsDetails.ts new file mode 100644 index 000000000..6d0b4ac21 --- /dev/null +++ b/apps/mass-payout/frontend/src/i18n/locales/distributionsDetails.ts @@ -0,0 +1,222 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +const distributionsDetailsTranslation = { + title: 'Distributions details', + failedMessage: 'This is a message', + table: { + headers: { + paymentId: 'Payment ID', + receieverAddressHedera: 'Receiver Address (Hedera)', + receieverAddressEvm: 'Receiver Address (EVM)', + amount: 'Amount', + executionDate: 'Execution/Attempt Date', + txHash: 'Tx Hash', + status: 'Status', + }, + }, + retryButton: 'Retry all', +}; + +export default distributionsDetailsTranslation; diff --git a/apps/mass-payout/frontend/src/i18n/locales/en.ts b/apps/mass-payout/frontend/src/i18n/locales/en.ts new file mode 100644 index 000000000..5841ceae5 --- /dev/null +++ b/apps/mass-payout/frontend/src/i18n/locales/en.ts @@ -0,0 +1,213 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +const enTranslation = { + app: { + title: 'Scheduler Payment Distribution', + description: 'Admin panel for managing scheduler payment distribution', + testButton: 'Test-button', + }, +}; + +export default enTranslation; diff --git a/apps/mass-payout/frontend/src/i18n/locales/importAsset.ts b/apps/mass-payout/frontend/src/i18n/locales/importAsset.ts new file mode 100644 index 000000000..1a252d21e --- /dev/null +++ b/apps/mass-payout/frontend/src/i18n/locales/importAsset.ts @@ -0,0 +1,255 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +const importAssetTranslation = { + title: 'Asset import', + header: { + details: 'Select an asset', + review: 'Review and Confirm', + }, + details: { + title: 'Asset Configuration', + subtitle: 'Enter the asset ID.', + assetInfo: 'Asset Info', + assetName: 'Asset Name: {{name}}', + symbol: 'Symbol: {{symbol}}', + assetType: 'Asset Type: {{type}}', + description: + '*Importing this asset enables automated mass payouts for lifecycle management , including corporate actions (e.g., coupon payments, redemptions) and configurable triggers (e.g., manual, scheduled, or streaming).
To activate this functionality, the Distributions contract must be granted the necessary permissions on the Asset Smart Contract. Configurations can be reviewed and adjusted in the next step before finalization.', + }, + stepAssetDetails: { + assetId: 'Asset ID', + assetName: 'Name', + lifeCycleCashFlowId: 'Life Cycle Cash Flow ID', + type: 'Type', + symbol: 'Symbol', + }, + form: { + assetId: { + label: 'Asset ID', + placeholder: '0.0.XXXXXX', + required: 'Asset ID is required', + }, + assetName: { + label: 'Asset name', + placeholder: '[Asset name]', + required: 'Asset name is required', + }, + }, + buttons: { + cancel: 'Cancel', + nextStep: 'Next step', + previousStep: 'Previous step', + importAsset: 'Import Asset', + importing: 'Importing...', + }, + review: { + assetConfiguration: 'Asset configuration', + title: 'Review Asset Details', + assetId: 'Asset ID', + assetName: 'Asset Name', + }, +}; + +export default importAssetTranslation; diff --git a/apps/mass-payout/frontend/src/i18n/locales/routes.ts b/apps/mass-payout/frontend/src/i18n/locales/routes.ts new file mode 100644 index 000000000..1503a7469 --- /dev/null +++ b/apps/mass-payout/frontend/src/i18n/locales/routes.ts @@ -0,0 +1,216 @@ +/* + 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. + +*/ + +import { RouteName } from '../../router/RouteName'; + +export default { + configuration: 'Configuration', + [RouteName.Assets]: 'Assets', + [RouteName.Distributions]: 'Distributions', + [RouteName.ImportAsset]: 'Import Asset', + [RouteName.AssetDetail]: 'Asset Details', + [RouteName.NewDistribution]: 'New Distribution', + [RouteName.DistributionsDetails]: 'Distributions Details', +}; diff --git a/apps/mass-payout/frontend/src/layouts/MainLayout.tsx b/apps/mass-payout/frontend/src/layouts/MainLayout.tsx new file mode 100644 index 000000000..a436e11cd --- /dev/null +++ b/apps/mass-payout/frontend/src/layouts/MainLayout.tsx @@ -0,0 +1,222 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Outlet } from 'react-router-dom'; +import { Stack } from '@chakra-ui/react'; +import { Sidebar } from './components/Sidebar'; +import { Header } from './components/Header'; + +export const MainLayout = () => { + return ( + <> + + +
+ + + + + + ); +}; diff --git a/apps/mass-payout/frontend/src/layouts/__test__/MainLayout.test.tsx b/apps/mass-payout/frontend/src/layouts/__test__/MainLayout.test.tsx new file mode 100644 index 000000000..0c57b105d --- /dev/null +++ b/apps/mass-payout/frontend/src/layouts/__test__/MainLayout.test.tsx @@ -0,0 +1,214 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { render } from '@/test-utils'; +import { MainLayout } from '../MainLayout'; + +describe('', () => { + test('should render correctly', async () => { + const component = render(); + + expect(component.asFragment()).toMatchSnapshot(); + }); +}); diff --git a/apps/mass-payout/frontend/src/layouts/__test__/__snapshots__/MainLayout.test.tsx.snap b/apps/mass-payout/frontend/src/layouts/__test__/__snapshots__/MainLayout.test.tsx.snap new file mode 100644 index 000000000..3a72bb0bc --- /dev/null +++ b/apps/mass-payout/frontend/src/layouts/__test__/__snapshots__/MainLayout.test.tsx.snap @@ -0,0 +1,98 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` should render correctly 1`] = ` + +
+
+
+ +

+ Assets +

+
+
+
+
+
+
+ Hedera +
+
+
+

+ Admin +

+ + + +
+
+
+
+
+
+
+`; diff --git a/apps/mass-payout/frontend/src/layouts/components/Header.tsx b/apps/mass-payout/frontend/src/layouts/components/Header.tsx new file mode 100644 index 000000000..4671b8f83 --- /dev/null +++ b/apps/mass-payout/frontend/src/layouts/components/Header.tsx @@ -0,0 +1,242 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Divider, Flex, HStack } from '@chakra-ui/react'; +import { + Header as HeaderBase, + Text, + Logo, + PhosphorIcon, + Weight, +} from 'io-bricks-ui'; +import { User } from '@phosphor-icons/react'; + +export const Header = () => { + return ( + } + rightContent={ + + + + + Admin + + + + + } + // seems to be that Header does not accept variants + sx={{ + bg: 'neutral.50', + h: 16, + pl: 6, + pr: 8, + py: 4, + zIndex: 100, + }} + /> + ); +}; diff --git a/apps/mass-payout/frontend/src/layouts/components/Sidebar.tsx b/apps/mass-payout/frontend/src/layouts/components/Sidebar.tsx new file mode 100644 index 000000000..294d36ea2 --- /dev/null +++ b/apps/mass-payout/frontend/src/layouts/components/Sidebar.tsx @@ -0,0 +1,258 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Stack } from '@chakra-ui/react'; +import { Sidebar as BaseSidebar, SidebarItem } from 'io-bricks-ui'; +import { Briefcase /*, ChartLine*/ } from '@phosphor-icons/react'; +import { useTranslation } from 'react-i18next'; +import { useLocation } from 'react-router-dom'; +import { RouteName } from '../../router/RouteName'; +import { RoutePath } from '../../router/RoutePath'; +import { RouterManager } from '../../router/RouterManager'; + +export const Sidebar = () => { + const { t } = useTranslation('routes'); + const location = useLocation(); + + const routes = [ + { + label: t(RouteName.Assets), + icon: Briefcase, + isActive: location.pathname === RoutePath.ASSETS, + to: RouteName.Assets, + }, + ]; + + return ( + + {routes.map((props, index) => ( + RouterManager.to(props.to)} + textAlign={'center'} + /> + ))} + + } + sx={{ + bg: 'neutral.50', + boxShadow: '2px 0px 5px 0px #4141411A', + position: 'relative', + apply: 'textStyles.ElementsRegularXS', + flexDirection: 'column', + justifyContent: 'space-between', + pt: 20, + pb: 10, + w: '104px', + minW: '104px', + h: '100vh', + }} + /> + ); +}; diff --git a/apps/mass-payout/frontend/src/main.tsx b/apps/mass-payout/frontend/src/main.tsx new file mode 100644 index 000000000..855c4a207 --- /dev/null +++ b/apps/mass-payout/frontend/src/main.tsx @@ -0,0 +1,230 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import { ChakraProvider } from '@chakra-ui/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { App } from './App'; +import theme from './theme'; +import './i18n/config'; + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + refetchOnWindowFocus: false, + retry: false, + }, + }, +}); + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + + + , +); diff --git a/apps/mass-payout/frontend/src/router/RouteName.ts b/apps/mass-payout/frontend/src/router/RouteName.ts new file mode 100644 index 000000000..491b599e1 --- /dev/null +++ b/apps/mass-payout/frontend/src/router/RouteName.ts @@ -0,0 +1,213 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export enum RouteName { + Landing = 'LANDING', + Assets = 'ASSETS', + Distributions = 'DISTRIBUTIONS', + ImportAsset = 'IMPORT_ASSET', + AssetDetail = 'ASSET_DETAIL', + NewDistribution = 'NEW_DISTRIBUTION', + DistributionsDetails = 'DISTRIBUTIONS_DETAILS', +} diff --git a/apps/mass-payout/frontend/src/router/RoutePath.ts b/apps/mass-payout/frontend/src/router/RoutePath.ts new file mode 100644 index 000000000..95f0ac68f --- /dev/null +++ b/apps/mass-payout/frontend/src/router/RoutePath.ts @@ -0,0 +1,216 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { RouteName } from './RouteName'; + +export const RoutePath: Record = { + [RouteName.Landing]: '/', + [RouteName.Assets]: '/assets', + [RouteName.Distributions]: '/distributions', + [RouteName.ImportAsset]: '/assets/import', + [RouteName.AssetDetail]: '/assets/:id', + [RouteName.NewDistribution]: '/assets/:id/new-distribution', + [RouteName.DistributionsDetails]: + '/assets/:id/:type/:itemId/distributions-details', +}; diff --git a/apps/mass-payout/frontend/src/router/RouterManager.ts b/apps/mass-payout/frontend/src/router/RouterManager.ts new file mode 100644 index 000000000..80f3a6e00 --- /dev/null +++ b/apps/mass-payout/frontend/src/router/RouterManager.ts @@ -0,0 +1,244 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import type { ReverseParams } from 'named-urls'; +import { reverse } from 'named-urls'; +import { router } from '.'; +import { RouteName } from './RouteName'; +import { RoutePath } from './RoutePath'; + +export interface RouteParams { + params?: ReverseParams; + extra?: string; + state?: object; +} + +export class BaseRouterManager { + constructor(private routes: Record = RoutePath) {} + + #getPath(name: RouteName, { params, extra = '' }: RouteParams) { + const pattern = this.routes[name] + extra; + return reverse(pattern, params); + } + + to(name: RouteName, { state, ...params }: RouteParams = {}) { + const pathname = this.#getPath(name, params); + return router.navigate({ pathname }, { state }); + } + + getUrl(name: RouteName, params: RouteParams = {}) { + const path = this.#getPath(name, params); + return reverse(path); + } + + goBack() { + return router.navigate(-1); + } + + goLanding() { + return this.to(RouteName.Landing); + } +} + +export const RouterManager = new BaseRouterManager(RoutePath); diff --git a/apps/mass-payout/frontend/src/router/Routes.tsx b/apps/mass-payout/frontend/src/router/Routes.tsx new file mode 100644 index 000000000..c207255b4 --- /dev/null +++ b/apps/mass-payout/frontend/src/router/Routes.tsx @@ -0,0 +1,280 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { lazy } from 'react'; +import i18n from 'i18next'; + +import { RouteName } from './RouteName'; +import { RoutePath } from './RoutePath'; +import { MainLayout } from '@/layouts/MainLayout'; + +// Lazy load components +const Landing = lazy(() => + import('@/views/Landing/Landing').then((module) => ({ + default: module.Landing, + })), +); +const Assets = lazy(() => + import('@/views/Assets/Assets/Assets').then((module) => ({ + default: module.Assets, + })), +); +const AssetDetail = lazy(() => + import('@/views/Assets/AssetDetail/AssetDetail').then((module) => ({ + default: module.AssetDetail, + })), +); +const NewDistribution = lazy(() => + import('@/views/Assets/NewDistribution/NewDistribution').then((module) => ({ + default: module.NewDistribution, + })), +); +const ImportAsset = lazy(() => + import('@/views/Assets/ImportAsset/ImportAsset').then((module) => ({ + default: module.ImportAsset, + })), +); +const DistributionsDetails = lazy( + () => import('@/views/Assets/DistributionsDetails/DistributionsDetails'), +); + +const t = (key: RouteName) => i18n.t(`routes:${key}`); + +export const routes = [ + { + element: , + children: [ + { + path: RoutePath.LANDING, + breadcrumb: t(RouteName.Landing), + element: , + }, + { + path: RoutePath.ASSETS, + breadcrumb: t(RouteName.Assets), + element: , + }, + { + path: RoutePath.ASSET_DETAIL, + breadcrumb: t(RouteName.AssetDetail), + element: , + }, + { + path: RoutePath.NEW_DISTRIBUTION, + breadcrumb: t(RouteName.NewDistribution), + element: , + }, + { + path: RoutePath.IMPORT_ASSET, + breadcrumb: t(RouteName.ImportAsset), + element: , + }, + { + path: RoutePath.DISTRIBUTIONS_DETAILS, + breadcrumb: t(RouteName.DistributionsDetails), + element: , + }, + ], + }, +]; diff --git a/apps/mass-payout/frontend/src/router/index.tsx b/apps/mass-payout/frontend/src/router/index.tsx new file mode 100644 index 000000000..6bdbf9c5d --- /dev/null +++ b/apps/mass-payout/frontend/src/router/index.tsx @@ -0,0 +1,219 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Suspense } from 'react'; +import { RouterProvider, createBrowserRouter } from 'react-router-dom'; +import { routes } from './Routes'; + +export const router = createBrowserRouter(routes); + +const AppRouter = () => { + return ( + + + + ); +}; + +export default AppRouter; diff --git a/apps/mass-payout/frontend/src/services/AssetService.ts b/apps/mass-payout/frontend/src/services/AssetService.ts new file mode 100644 index 000000000..110a479a3 --- /dev/null +++ b/apps/mass-payout/frontend/src/services/AssetService.ts @@ -0,0 +1,428 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { apiRequest, buildUrl } from './api'; +import { BackendUrls } from './BackendUrls'; +import { AmountType, DistributionSubtype } from './DistributionService'; + +export enum AssetType { + EQUITY = 'Equity', + BOND = 'Bond', +} + +export interface Asset { + id: string; + name: string; + type: AssetType; + symbol: string; + hederaTokenAddress: string; + evmTokenAddress: string; + lifeCycleCashFlowHederaAddress?: string; + lifeCycleCashFlowEvmAddress: string; + maturityDate?: string; + isPaused: boolean; + syncEnabled: boolean; + createdAt: string; + updatedAt: string; +} + +export interface SortParam { + id: string; + desc: boolean; +} + +export interface GetAssetsParams { + filters?: { + value?: string; + }; + page?: number; + sort?: SortParam[]; + size?: number; +} + +export interface PaginatedResponse { + queryData: T[]; + page: { + totalElements: number; + totalPages: number; + pageIndex: number; + pageSize: number; + }; +} + +export interface AssetDistribution { + id: string; + asset: Asset; + type: string; + corporateActionID: string; + executionDate: string; + status: string; + concept: string; + amount?: string; + amountType?: string; + subtype?: string; + actions?: string; + trigger?: string; + createdAt: string; + updatedAt: string; +} + +export interface GetAssetDistributionsParams { + assetId: string; + page?: number; + size?: number; + search?: string; +} + +export interface CreateManualPayoutParams { + assetId: string; + subtype: DistributionSubtype; + executeAt?: string; + amount: string; + amountType: AmountType; + recurrency?: 'HOURLY' | 'DAILY' | 'WEEKLY' | 'MONTHLY'; + concept?: string; +} + +export interface AssetMetadata { + hederaTokenAddress: string; + name: string; + symbol: string; + assetType: AssetType; + maturityDate?: string; +} + +export class AssetService { + static async getAssets( + params: GetAssetsParams = {}, + ): Promise> { + const { filters, page = 0, sort = [], size = 10 } = params; + + const query = new URLSearchParams(); + filters?.value && query.append('search', filters.value); + query.append('page', (page + 1).toString()); // Backend expects 1-based + query.append('limit', size.toString()); + + if (sort.length > 0) { + sort.forEach((col: SortParam) => + query.append('sort', `${col.id},${col.desc ? 'desc' : 'asc'}`), + ); + } + + const url = buildUrl(BackendUrls.GetAssets, {}); + const response = await apiRequest<{ + items: Asset[]; + total: number; + page: number; + limit: number; + totalPages: number; + }>(`${url}?${query.toString()}`, { + method: 'GET', + }); + + return { + queryData: response.items, + page: { + totalElements: response.total, + totalPages: response.totalPages, + pageIndex: response.page - 1, // Convert back to 0-based + pageSize: response.limit, + }, + }; + } + + static async getAsset(assetId: string): Promise { + const url = buildUrl(BackendUrls.GetAsset, { assetId }); + return apiRequest(url, { + method: 'GET', + }); + } + + static async getAssetMetadata( + hederaTokenAddress: string, + ): Promise { + const url = buildUrl(BackendUrls.GetAssetMetadata, { hederaTokenAddress }); + return apiRequest(url, { + method: 'GET', + }); + } + + static async importAsset(hederaTokenAddress: string): Promise { + return apiRequest(BackendUrls.ImportAsset, { + method: 'POST', + body: { hederaTokenAddress }, + }); + } + + static async pauseAsset(assetId: string): Promise { + const url = buildUrl(BackendUrls.PauseAsset, { assetId }); + return apiRequest(url, { + method: 'PATCH', + }); + } + + static async unpauseAsset(assetId: string): Promise { + const url = buildUrl(BackendUrls.UnpauseAsset, { assetId }); + return apiRequest(url, { + method: 'PATCH', + }); + } + + static async getAssetDistributions( + params: GetAssetDistributionsParams, + ): Promise> { + const { assetId, page = 0, size = 10, search } = params; + + const query = new URLSearchParams(); + if (search) query.append('search', search); + query.append('page', (page + 1).toString()); + query.append('limit', size.toString()); + + const url = buildUrl(BackendUrls.GetAssetDistributions, { assetId }); + const response = await apiRequest<{ + items: AssetDistribution[]; + total: number; + page: number; + limit: number; + totalPages: number; + }>(`${url}?${query.toString()}`, { + method: 'GET', + }); + + return { + queryData: response.items, + page: { + totalElements: response.total, + totalPages: response.totalPages, + pageIndex: response.page - 1, + pageSize: response.limit, + }, + }; + } + + static async createManualPayout( + params: CreateManualPayoutParams, + ): Promise { + const { assetId, ...body } = params; + const url = buildUrl(BackendUrls.CreateManualPayout, { assetId }); + return apiRequest(url, { + method: 'POST', + body, + }); + } + + static async enableAssetSync(assetId: string): Promise { + const url = buildUrl(BackendUrls.EnableAssetSync, { assetId }); + return apiRequest(url, { + method: 'PATCH', + }); + } + + static async disableAssetSync(assetId: string): Promise { + const url = buildUrl(BackendUrls.DisableAssetSync, { assetId }); + return apiRequest(url, { + method: 'PATCH', + }); + } +} diff --git a/apps/mass-payout/frontend/src/services/BackendUrls.ts b/apps/mass-payout/frontend/src/services/BackendUrls.ts new file mode 100644 index 000000000..8c3456699 --- /dev/null +++ b/apps/mass-payout/frontend/src/services/BackendUrls.ts @@ -0,0 +1,224 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export enum BackendUrls { + // AssetService + GetAssets = '/assets', + GetAsset = '/assets/:assetId', + GetAssetMetadata = '/assets/:hederaTokenAddress/metadata', + ImportAsset = '/assets/import', + PauseAsset = '/assets/:assetId/pause', + UnpauseAsset = '/assets/:assetId/unpause', + EnableAssetSync = '/assets/:assetId/enable-sync', + DisableAssetSync = '/assets/:assetId/disable-sync', + GetAssetDistributions = '/assets/:assetId/distributions', + CreateManualPayout = '/assets/:assetId/distributions/payout', + + // DistributionService + GetDistributions = '/distributions', + GetDistribution = '/distributions/:distributionId', + GetDistributionHolders = '/distributions/:distributionId/holders', + CancelDistribution = '/distributions/:distributionId/cancel', + RetryDistribution = '/distributions/:distributionId/retry', +} diff --git a/apps/mass-payout/frontend/src/services/DistributionService.ts b/apps/mass-payout/frontend/src/services/DistributionService.ts new file mode 100644 index 000000000..69b77107d --- /dev/null +++ b/apps/mass-payout/frontend/src/services/DistributionService.ts @@ -0,0 +1,384 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { apiRequest, buildUrl } from './api'; +import { Asset, SortParam } from './AssetService'; +import { BackendUrls } from './BackendUrls'; + +export type ProcessStatus = + | 'SCHEDULED' + | 'IN_PROGRESS' + | 'COMPLETED' + | 'FAILED'; +export type DistributionType = 'PAYOUT' | 'CORPORATE_ACTION'; +export type DistributionSubtype = + | 'IMMEDIATE' + | 'RECURRING' + | 'ONE_OFF' + | 'AUTOMATED'; +export type AmountType = 'FIXED' | 'PERCENTAGE'; + +export interface Distribution { + id: string; + asset: Asset; + corporateActionID?: string; + status: ProcessStatus; + createdAt: string; + updatedAt: string; + amount?: string; + amountType?: AmountType; + subtype?: DistributionSubtype; + executionDate?: string; + concept?: string; +} + +export interface GetDistributionsResponse { + items: Distribution[]; + total: number; + page: number; + limit: number; + totalPages: number; +} + +export interface GetDistributionsParams { + filters?: { value?: string }; + page?: number; + sort?: SortParam[]; + size?: number; + status?: ProcessStatus; +} + +export interface PaginatedResponse { + queryData: T[]; + page: { + totalElements: number; + totalPages: number; + pageIndex: number; + pageSize: number; + }; +} + +export interface Holder { + id: string; + batchPayout: { + id: string; + distribution: Distribution; + hederaTransactionId: string; + status: string; + createdAt: string; + updatedAt: string; + hederaTransactionAddress?: string; + }; + amount: string; + holderHederaAddress: string; + holderEvmAddress: string; + retryCounter: number; + status: 'PENDING' | 'RETRYING' | 'SUCCESS' | 'FAILED'; + lastError: string | null; + nextRetryAt: Date | null; + updatedAt: string; +} + +export interface GetHoldersParams { + distributionId: string; + page?: number; + size?: number; + search?: string; +} + +export class DistributionService { + static async getDistributions( + params: GetDistributionsParams = {}, + ): Promise> { + const { filters, page = 0, sort = [], size = 10, status } = params; + + const query = new URLSearchParams(); + filters?.value && query.append('search', filters.value); + query.append('page', (page + 1).toString()); // Backend expects 1-based + query.append('limit', size.toString()); + status && query.append('status', status); + + if (sort.length > 0) { + const firstSort = sort[0]; + query.append('orderBy', firstSort.id); + query.append('order', firstSort.desc ? 'DESC' : 'ASC'); + } + + const url = buildUrl(BackendUrls.GetDistributions, {}); + const response = await apiRequest<{ + items: Distribution[]; + total: number; + page: number; + limit: number; + totalPages: number; + }>(`${url}?${query.toString()}`, { + method: 'GET', + }); + + return { + queryData: response.items, + page: { + totalElements: response.total, + totalPages: response.totalPages, + pageIndex: response.page - 1, // Convert back to 0-based + pageSize: response.limit, + }, + }; + } + + static async getDistribution(distributionId: string): Promise { + const url = buildUrl(BackendUrls.GetDistribution, { distributionId }); + return apiRequest(url, { + method: 'GET', + }); + } + + static async getDistributionHolders( + params: GetHoldersParams, + ): Promise> { + const { distributionId, page = 0, size = 10, search } = params; + + const query = new URLSearchParams(); + search && query.append('search', search); + query.append('page', (page + 1).toString()); // Backend expects 1-based + query.append('limit', size.toString()); + + const url = buildUrl(BackendUrls.GetDistributionHolders, { + distributionId, + }); + const response = await apiRequest<{ + items: Holder[]; + total: number; + page: number; + limit: number; + totalPages: number; + }>(`${url}?${query.toString()}`, { + method: 'GET', + }); + + return { + queryData: response.items, + page: { + totalElements: response.total, + totalPages: response.totalPages, + pageIndex: response.page - 1, // Convert back to 0-based + pageSize: response.limit, + }, + }; + } + + static async cancelDistribution(distributionId: string): Promise { + const url = buildUrl(BackendUrls.CancelDistribution, { distributionId }); + return apiRequest(url, { + method: 'PATCH', + }); + } + + static async retryDistribution(distributionId: string): Promise { + const url = buildUrl(BackendUrls.RetryDistribution, { distributionId }); + return apiRequest(url, { + method: 'PATCH', + }); + } +} diff --git a/apps/mass-payout/frontend/src/services/api.ts b/apps/mass-payout/frontend/src/services/api.ts new file mode 100644 index 000000000..5ac66ead8 --- /dev/null +++ b/apps/mass-payout/frontend/src/services/api.ts @@ -0,0 +1,294 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +const getApiBaseUrl = () => { + if ( + typeof process !== 'undefined' && + process.env && + process.env.NODE_ENV === 'test' + ) { + return process.env.VITE_API_URL || 'http://localhost:3000'; + } + + try { + // @ts-ignore + if ( + typeof window !== 'undefined' && + (window as any).import?.meta?.env?.VITE_API_URL + ) { + // @ts-ignore + return (window as any).import.meta.env.VITE_API_URL; + } + } catch (error) { + // Fallback si import.meta no está disponible + } + return 'http://localhost:3000'; +}; + +const API_BASE_URL = getApiBaseUrl(); + +export class ApiError extends Error { + constructor( + public status: number, + message: string, + ) { + super(message); + this.name = 'ApiError'; + } +} + +const handleResponse = async (response: Response) => { + if (!response.ok) { + throw new ApiError( + response.status, + `HTTP error! status: ${response.status}`, + ); + } + return response; +}; + +export interface ApiRequestOptions { + method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'; + headers?: Record; + body?: Record | unknown[] | string | number | boolean | null; +} + +export const apiRequest = async ( + endpoint: string, + options: ApiRequestOptions = {}, +): Promise => { + const { method = 'GET', headers = {}, body } = options; + + const config: RequestInit = { + method, + headers: { + 'Content-Type': 'application/json', + ...headers, + }, + }; + + if (body && method !== 'GET') { + config.body = JSON.stringify(body); + } + + const response = await fetch(`${API_BASE_URL}${endpoint}`, config); + await handleResponse(response); + + const contentType = response.headers.get('content-type'); + if (contentType && contentType.includes('application/json')) { + return response.json(); + } + + return {} as T; +}; + +export const buildUrl = ( + template: string, + params: Record, +): string => { + return Object.entries(params).reduce( + (url, [key, value]) => url.replace(`:${key}`, value), + template, + ); +}; diff --git a/packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/BondUSAReadTimeTravel.sol b/apps/mass-payout/frontend/src/store/locationStore.tsx similarity index 86% rename from packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/BondUSAReadTimeTravel.sol rename to apps/mass-payout/frontend/src/store/locationStore.tsx index 61a01c120..43897d6cf 100644 --- a/packages/ats/contracts/contracts/test/testTimeTravel/facetsTimeTravel/BondUSAReadTimeTravel.sol +++ b/apps/mass-payout/frontend/src/store/locationStore.tsx @@ -203,31 +203,58 @@ */ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.18; - -import {BondUSARead} from '../../../layer_3/bondUSA/BondUSARead.sol'; -import { - TimeTravelStorageWrapper -} from '../timeTravel/TimeTravelStorageWrapper.sol'; -import {LocalContext} from '../../../layer_0/context/LocalContext.sol'; - -contract BondUSAReadTimeTravel is BondUSARead, TimeTravelStorageWrapper { - function _blockTimestamp() - internal - view - override(LocalContext, TimeTravelStorageWrapper) - returns (uint256) - { - return TimeTravelStorageWrapper._blockTimestamp(); - } +import { create } from 'zustand'; + +interface LocationStore { + locations: string[]; + setLocations: (location: string) => void; + getCurrentUrl: () => string; + shouldNavigateToAssets: () => boolean; + shouldReplaceGobackRoute: () => boolean; + getGoBackPath: (fallbackPath?: string) => string; + getGoBackAction: () => + | 'navigate-to-assets' + | 'navigate-to-landing' + | 'navigate-back'; +} - function _blockNumber() - internal - view - override(LocalContext, TimeTravelStorageWrapper) - returns (uint256) - { - return TimeTravelStorageWrapper._blockNumber(); +export const useLocationStore = create((set, get) => ({ + locations: [], + setLocations: (location: string) => + set((state: LocationStore) => ({ + ...state, + locations: [...state.locations, location], + })), + getCurrentUrl: () => { + return window.location.href; + }, + shouldNavigateToAssets: () => { + const currentUrl = new URL(get().getCurrentUrl()); + const hasTabDistributions = + currentUrl.searchParams.get('tab') === 'distributions'; + return hasTabDistributions && currentUrl.pathname.includes('/assets/'); + }, + shouldReplaceGobackRoute: () => { + const { locations } = get(); + return ( + locations[locations.length - 2]?.includes('/create') || + locations[locations.length - 2]?.includes('/add') + ); + }, + getGoBackPath: (fallbackPath?: string) => { + const { shouldNavigateToAssets, shouldReplaceGobackRoute } = get(); + if (shouldNavigateToAssets()) return '/assets'; + if (shouldReplaceGobackRoute()) return '/'; + return fallbackPath || '/'; + }, + getGoBackAction: () => { + const { shouldNavigateToAssets, shouldReplaceGobackRoute } = get(); + if (shouldNavigateToAssets()) { + return 'navigate-to-assets'; } -} + if (shouldReplaceGobackRoute()) { + return 'navigate-to-landing'; + } + return 'navigate-back'; + }, +})); diff --git a/apps/mass-payout/frontend/src/test-utils.tsx b/apps/mass-payout/frontend/src/test-utils.tsx new file mode 100644 index 000000000..504f4e12d --- /dev/null +++ b/apps/mass-payout/frontend/src/test-utils.tsx @@ -0,0 +1,293 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import React from 'react'; +import { ChakraProvider } from '@chakra-ui/react'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import type { RenderOptions, RenderResult } from '@testing-library/react'; +import { render, waitFor } from '@testing-library/react'; +import type { MemoryHistory } from 'history'; +import { createMemoryHistory } from 'history'; +import { I18nextProvider } from 'react-i18next'; +import { Router } from 'react-router-dom'; +import i18n from './i18n/config'; +import theme from './theme'; +import userEvent from '@testing-library/user-event'; + +export const selectCalendar = async ( + component: RenderResult, + id: string, + day: string | number = new Date().getDate(), +) => { + const calendar = component.getByTestId(id); + await userEvent.click(calendar); + + await waitFor(() => { + const daysToSelect = component.getAllByTestId(`day-${day}`); + + const dayToSelect = daysToSelect.find( + (day) => !day.hasAttribute('disabled'), + ); + + if (dayToSelect) { + userEvent.click(dayToSelect); + } + }); + + await userEvent.click(document.body); +}; + +export const testQueryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + refetchOnMount: true, + }, + }, +}); + +export const queryWrapper = ({ children }: { children: React.ReactNode }) => ( + {children} +); + +const memoryHistory = createMemoryHistory(); + +export const AllProviders = ({ + children, + history = memoryHistory, +}: { + children?: React.ReactNode; + history?: MemoryHistory; +}) => { + return ( + + + + + {children} + + + + + ); +}; + +const customRender = ( + ui: React.ReactElement, + { + options, + history, + }: { + options?: RenderOptions; + history?: MemoryHistory; + } = {}, +): RenderResult => + render(ui, { + wrapper: ({ children }) => ( + {children} + ), + ...options, + }); + +export { customRender as render }; diff --git a/apps/mass-payout/frontend/src/test-utils/mocks/AssetMocks.ts b/apps/mass-payout/frontend/src/test-utils/mocks/AssetMocks.ts new file mode 100644 index 000000000..5b8d0e018 --- /dev/null +++ b/apps/mass-payout/frontend/src/test-utils/mocks/AssetMocks.ts @@ -0,0 +1,317 @@ +/* + * 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 + * (which shall not include communications that are reasonably + * considered separate from, or merely link (or bind by name) to the + * interfaces of, the Work and related works). + * + * "Derivative Works" shall mean any work, whether in Source or Object + * form, that is based upon (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 any separate works contained therein. + * + * "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 use, reproduce, modify, distribute, and prepare + * Derivative Works of the Work, and to publicly perform and display the + * Work and such Derivative Works in any medium or format, whether now + * known or hereafter devised, provided that You properly attribute the + * work as specified by the author or licensor (but not in any way that + * suggests the author or licensor endorses You or Your use of the work). + * + * 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 notice 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 Support. When 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 support. + * + * 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. + */ + +import { Asset, AssetType } from '@/services/AssetService'; + +/** + * Centralized mock data for Asset-related tests + * This provides reusable mock objects that reflect the actual backend structure + */ +export interface BackendMocks { + asset: Asset; + assets: Asset[]; + assetService: { + getAssets: jest.MockedFunction; + getAsset: jest.MockedFunction; + pauseAsset: jest.MockedFunction; + unpauseAsset: jest.MockedFunction; + }; +} + +/** + * Mock asset data that reflects the actual backend Asset interface + */ +export const mockAsset: Asset = { + id: '0.0.890123', + name: 'Test Asset', + type: AssetType.EQUITY, + hederaTokenAddress: '0.0.123456', + evmTokenAddress: '0x1234567890abcdef1234567890abcdef12345678', + lifeCycleCashFlowHederaAddress: '0.0.654321', + lifeCycleCashFlowEvmAddress: '0xabcdef1234567890abcdef1234567890abcdef12', + isPaused: false, + syncEnabled: true, + createdAt: '2024-01-15T10:30:00Z', + updatedAt: '2024-01-15T10:30:00Z', + symbol: 'TEST', +}; + +/** + * Mock assets array for testing list scenarios + */ +export const mockAssets: Asset[] = [ + mockAsset, + { + id: '0.0.456789', + name: 'Bond Asset', + type: AssetType.BOND, + hederaTokenAddress: '0.0.789012', + evmTokenAddress: '0x9876543210fedcba9876543210fedcba98765432', + lifeCycleCashFlowHederaAddress: '0.0.210987', + lifeCycleCashFlowEvmAddress: '0xfedcba0987654321fedcba0987654321fedcba09', + isPaused: true, + syncEnabled: false, + createdAt: '2024-01-10T08:15:00Z', + updatedAt: '2024-01-12T14:45:00Z', + symbol: 'BOND', + }, +]; + +/** + * Mock AssetService for testing + */ +export const mockAssetService = { + getAssets: jest.fn(), + getAsset: jest.fn(), + pauseAsset: jest.fn(), + unpauseAsset: jest.fn(), +}; + +/** + * Complete BackendMocks object for easy import + */ +export const backendMocks: BackendMocks = { + asset: mockAsset, + assets: mockAssets, + assetService: mockAssetService, +}; + +/** + * Utility function to create a custom mock asset with overrides + */ +export const createMockAsset = (overrides: Partial = {}): Asset => ({ + ...mockAsset, + ...overrides, +}); + +/** + * Utility function to create multiple mock assets + */ +export const createMockAssets = ( + count: number, + baseOverrides: Partial = {}, +): Asset[] => { + return Array.from({ length: count }, (_, index) => + createMockAsset({ + ...baseOverrides, + id: `0.0.${890123 + index}`, + name: `Test Asset ${index + 1}`, + }), + ); +}; + +/** + * Reset all mocks to their initial state + */ +export const resetAssetMocks = (): void => { + Object.values(mockAssetService).forEach((mock) => { + if (jest.isMockFunction(mock)) { + mock.mockClear(); + } + }); +}; diff --git a/apps/mass-payout/frontend/src/test-utils/mocks/DistributionMocks.ts b/apps/mass-payout/frontend/src/test-utils/mocks/DistributionMocks.ts new file mode 100644 index 000000000..891032485 --- /dev/null +++ b/apps/mass-payout/frontend/src/test-utils/mocks/DistributionMocks.ts @@ -0,0 +1,409 @@ +/* + * 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 use, reproduce, modify, distribute, and prepare + * Derivative Works of the Work, and to publicly perform and display the + * Work and such Derivative Works in any medium or format, whether now + * known or hereafter devised, provided that You properly attribute the + * Work in the manner specified by the author or licensor (but not in any + * way that suggests that they endorse You or Your use of the Work). + * + * 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 notice 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +/** + * Mock distribution data for testing + */ +export interface MockDistribution { + id: string; + asset: { + id: string; + name: string; + type: string; + hederaTokenAddress: string; + evmTokenAddress: string; + lifeCycleCashFlowHederaAddress: string; + lifeCycleCashFlowEvmAddress: string; + isPaused: boolean; + createdAt: string; + updatedAt: string; + }; + corporateActionID: string | null; + executionDate: string; + status: string; + createdAt: string; + updatedAt: string; + batchCount?: number; + holders?: number; + progress?: number; +} + +/** + * Mock distributions with realistic test data + */ +export const mockDistributions: MockDistribution[] = [ + { + id: '650e8400-e29b-41d4-a716-446655440001', + asset: { + id: '0.0.123456', + name: 'Hedera Treasury Bond 2025', + type: 'Bond', + hederaTokenAddress: '0.0.123456', + evmTokenAddress: '0x1234567890123456789012345678901234567890', + lifeCycleCashFlowHederaAddress: '0.0.789012', + lifeCycleCashFlowEvmAddress: '0x7890123456789012345678901234567890123456', + isPaused: false, + createdAt: '2024-10-06T10:30:00Z', + updatedAt: '2024-10-06T10:30:00Z', + }, + corporateActionID: 'CA-001', + executionDate: '2024-10-06T10:00:00Z', + status: 'In Progress', + createdAt: '2024-10-06T08:00:00Z', + updatedAt: '2024-10-06T10:30:00Z', + batchCount: 50, + holders: 90, + progress: 75, + }, + { + id: '650e8400-e29b-41d4-a716-446655440002', + asset: { + id: '0.0.234567', + name: 'DLT Infrastructure Equity Fund', + type: 'Equity', + hederaTokenAddress: '0.0.234567', + evmTokenAddress: '0x2345678901234567890123456789012345678901', + lifeCycleCashFlowHederaAddress: '0.0.890123', + lifeCycleCashFlowEvmAddress: '0x8901234567890123456789012345678901234567', + isPaused: false, + createdAt: '2024-10-05T10:30:00Z', + updatedAt: '2024-10-05T10:30:00Z', + }, + corporateActionID: 'CA-002', + executionDate: '2024-10-05T10:00:00Z', + status: 'Completed', + createdAt: '2024-10-05T08:00:00Z', + updatedAt: '2024-10-05T12:00:00Z', + batchCount: 50, + holders: 90, + progress: 100, + }, + { + id: '650e8400-e29b-41d4-a716-446655440003', + asset: { + id: '0.0.345678', + name: 'Consensus Node Validator Shares', + type: 'Equity', + hederaTokenAddress: '0.0.345678', + evmTokenAddress: '0x3456789012345678901234567890123456789012', + lifeCycleCashFlowHederaAddress: '0.0.901234', + lifeCycleCashFlowEvmAddress: '0x9012345678901234567890123456789012345678', + isPaused: true, + createdAt: '2024-10-04T10:30:00Z', + updatedAt: '2024-10-04T10:30:00Z', + }, + corporateActionID: 'CA-003', + executionDate: '2024-10-04T10:00:00Z', + status: 'Failed', + createdAt: '2024-10-04T08:00:00Z', + updatedAt: '2024-10-04T11:00:00Z', + batchCount: 50, + holders: 90, + progress: 25, + }, + { + id: '650e8400-e29b-41d4-a716-446655440004', + asset: { + id: '0.0.456789', + name: 'Mirror Node Network Equity', + type: 'Equity', + hederaTokenAddress: '0.0.456789', + evmTokenAddress: '0x4567890123456789012345678901234567890123', + lifeCycleCashFlowHederaAddress: '0.0.012345', + lifeCycleCashFlowEvmAddress: '0x0123456789012345678901234567890123456789', + isPaused: false, + createdAt: '2024-10-03T10:30:00Z', + updatedAt: '2024-10-03T10:30:00Z', + }, + corporateActionID: null, // Manual distribution + executionDate: '2024-10-03T10:00:00Z', + status: 'In Progress', + createdAt: '2024-10-03T08:00:00Z', + updatedAt: '2024-10-03T10:30:00Z', + batchCount: 50, + holders: 90, + progress: 60, + }, +]; + +/** + * Mock paginated response for distributions + */ +export const mockDistributionsPaginatedResponse = { + queryData: mockDistributions, + page: { + totalElements: mockDistributions.length, + totalPages: 1, + pageIndex: 0, + pageSize: 10, + }, +}; + +/** + * Mock AssetService methods for distributions + */ +export const mockAssetDistributionService = { + getAssetDistributions: jest + .fn() + .mockResolvedValue(mockDistributionsPaginatedResponse), +}; + +/** + * Mock DistributionService methods + */ +export const mockDistributionService = { + getDistributions: jest + .fn() + .mockResolvedValue(mockDistributionsPaginatedResponse), + getDistribution: jest.fn().mockResolvedValue(mockDistributions[0]), +}; + +/** + * Utility function to create a custom mock distribution with overrides + */ +export const createMockDistribution = ( + overrides: Partial = {}, +): MockDistribution => ({ + ...mockDistributions[0], + ...overrides, +}); + +/** + * Utility function to create multiple mock distributions + */ +export const createMockDistributions = ( + count: number, + baseOverrides: Partial = {}, +): MockDistribution[] => { + return Array.from({ length: count }, (_, index) => + createMockDistribution({ + ...baseOverrides, + id: `650e8400-e29b-41d4-a716-44665544000${index + 1}`, + asset: { + ...mockDistributions[0].asset, + id: `0.0.${123456 + index}`, + name: `Test Distribution Asset ${index + 1}`, + }, + }), + ); +}; + +/** + * Reset all distribution mocks to their initial state + */ +export const resetDistributionMocks = (): void => { + Object.values(mockAssetDistributionService).forEach((mock) => { + if (jest.isMockFunction(mock)) { + mock.mockClear(); + } + }); + + Object.values(mockDistributionService).forEach((mock) => { + if (jest.isMockFunction(mock)) { + mock.mockClear(); + } + }); +}; diff --git a/apps/mass-payout/frontend/src/test-utils/mocks/PaymentMocks.ts b/apps/mass-payout/frontend/src/test-utils/mocks/PaymentMocks.ts new file mode 100644 index 000000000..dcd4f2db6 --- /dev/null +++ b/apps/mass-payout/frontend/src/test-utils/mocks/PaymentMocks.ts @@ -0,0 +1,249 @@ +/* + * 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 notice 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. When 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ProcessStatusType } from '../../types/status'; + +export interface PaymentData { + paymentId: string; + creationDate: string; + paidAmount: number; + batchCount: number; + holders: number; + status: ProcessStatusType; + paymentType: string; + progress: number; +} + +export const mockPayments: PaymentData[] = [ + { + paymentId: '0.0.123456', + creationDate: '09/10/2024', + paidAmount: 1500.5, + batchCount: 80, + holders: 90, + status: 'In Progress' as ProcessStatusType, + paymentType: 'Dividend', + progress: 75, + }, + { + paymentId: '0.0.234567', + creationDate: '08/10/2024', + paidAmount: 2300.75, + batchCount: 80, + holders: 90, + status: 'Failed' as ProcessStatusType, + paymentType: 'Coupon', + progress: 45, + }, + { + paymentId: '0.0.345678', + creationDate: '04/10/2024', + paidAmount: 5000.0, + batchCount: 80, + holders: 90, + status: 'Completed' as ProcessStatusType, + paymentType: 'Dividend', + progress: 100, + }, +]; diff --git a/apps/mass-payout/frontend/src/test-utils/mocks/index.ts b/apps/mass-payout/frontend/src/test-utils/mocks/index.ts new file mode 100644 index 000000000..0a53f3090 --- /dev/null +++ b/apps/mass-payout/frontend/src/test-utils/mocks/index.ts @@ -0,0 +1,228 @@ +/* + * 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 + * (which shall not include communications that are reasonably + * considered separate from, or merely link (or bind by name) to the + * interfaces of, the Work and related works). + * + * "Derivative Works" shall mean any work, whether in Source or Object + * form, that is based upon (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 any separate works contained therein. + * + * "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 use, reproduce, modify, distribute, and prepare + * Derivative Works of the Work, and to publicly perform and display the + * Work and such Derivative Works in any medium or format, whether now + * known or hereafter devised, provided that You properly attribute the + * work as specified by the author or licensor (but not in any way that + * suggests the author or licensor endorses You or Your use of the work). + * + * 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 notice 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 Support. When 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 support. + * + * 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. + */ + +/** + * Centralized exports for all test mocks + * This provides a single entry point for importing mock utilities + */ + +// Asset-related mocks +export { + type BackendMocks, + mockAsset, + mockAssets, + mockAssetService, + backendMocks, + createMockAsset, + createMockAssets, + resetAssetMocks, +} from './AssetMocks'; + +// Future mocks can be added here as the application grows +export * from './DistributionMocks'; +export * from './PaymentMocks'; diff --git a/apps/mass-payout/frontend/src/theme/colors/index.ts b/apps/mass-payout/frontend/src/theme/colors/index.ts new file mode 100644 index 000000000..897d180f1 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/colors/index.ts @@ -0,0 +1,221 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { mainColors } from './mainColors'; +import { neutralColors } from './neutralColors'; +import { statusColors } from './statusColors'; + +export * from './mainColors'; +export * from './neutralColors'; +export * from './statusColors'; + +export type MainColors = keyof typeof mainColors; +export type NeutralColors = keyof typeof neutralColors; +export type StatusColors = keyof typeof statusColors; + +export const colors = { + neutral: neutralColors, + status: statusColors, + ...mainColors, +}; diff --git a/apps/mass-payout/frontend/src/theme/colors/mainColors.ts b/apps/mass-payout/frontend/src/theme/colors/mainColors.ts new file mode 100644 index 000000000..efb2bb4f9 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/colors/mainColors.ts @@ -0,0 +1,231 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export const mainColors = { + primary: { + 50: '#EDEFFC', + 100: '#C8CDF7', + 200: '#AEB4F3', + 400: '#717DEA', + 500: '#4E5DE5', + 700: '#3742A3', + 800: '#2B337E', + }, + secondary: { + 50: '#F7F4FE', + 100: '#E7DEFC', + 400: '#C1A9F6', + 500: '#B293F4', + 600: '#7E68AD', + 800: '#625189', + }, + tertiary: { + 50: '#FEF6F3', + 100: '#FDE2D9', + 400: '#F9B49E', + 500: '#F8A186', + 600: '#B0725F', + 800: '#88594A', + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/colors/neutralColors.ts b/apps/mass-payout/frontend/src/theme/colors/neutralColors.ts new file mode 100644 index 000000000..d9b8cb5ad --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/colors/neutralColors.ts @@ -0,0 +1,217 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ +export const neutralColors = { + white: '#FDFDFD', + 50: '#F8F7FC', + 100: '#F1F2F7', + 200: '#E2E5E9', + 300: '#D6D3DE', + 400: '#C3BECF', + 500: '#A7A0B9', + 600: '#958DAB', + 700: '#677489', + 800: '#57506B', + 900: '#2F363F', + 1000: '#0D0F12', +}; diff --git a/apps/mass-payout/frontend/src/theme/colors/statusColors.ts b/apps/mass-payout/frontend/src/theme/colors/statusColors.ts new file mode 100644 index 000000000..645c3cd1a --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/colors/statusColors.ts @@ -0,0 +1,250 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export const statusColors = { + success: { + 50: '#F3F9ED', + 100: '#DBECC7', + 500: '#8BC34A', + 700: '#638A35', + 800: '#4C6B29', + 900: '#D1FAE0', + }, + error: { + 50: '#FAE9E6', + 100: '#EEBAB2', + 200: '#FCCFCF', + 500: '#C92008', + 700: '#8F1706', + 800: '#6F1204', + }, + warning: { + 50: '#FFF5E6', + 100: '#FFDFB0', + 500: '#FF9800', + 700: '#B56C00', + 800: '#8C5400', + }, + info: { + 50: '#F3F7FB', + 100: '#DAE7F2', + 200: '#CCE4FF', + 500: '#89B0D4', + 700: '#617D97', + 800: '#4B6175', + }, + inProgress: { + 50: '#FDDCC4', + }, + cancelled: { + 50: '#F1F2F7', + }, + paused: { + 50: '#FFEAB0', + 100: '#FFC933', + }, + active: { + 50: '#33BAA7', + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Breadcrumb.ts b/apps/mass-payout/frontend/src/theme/components/Breadcrumb.ts new file mode 100644 index 000000000..66fc717dc --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Breadcrumb.ts @@ -0,0 +1,239 @@ +/* + 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. + +*/ + +import type { BreadcrumbThemeConfiguration } from 'io-bricks-ui'; +import { breadcrumbPartsList } from 'io-bricks-ui'; + +export const Breadcrumb: BreadcrumbThemeConfiguration = { + parts: breadcrumbPartsList, + baseStyle: { + item: { + textStyle: 'ElementsSemiboldSM', + _last: { + span: { + color: 'neutral.700', + cursor: 'default', + textDecoration: 'none', + textStyle: 'ElementSMBold', + }, + }, + svg: { + color: 'neutral.500', + }, + }, + isDesktop: { + base: true, + md: true, + }, + link: { + textStyle: 'ElementsSemiboldSM', + color: 'neutral.500', + + '&:last-child': { + textStyle: 'ElementsBoldSM', + }, + }, + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Button.ts b/apps/mass-payout/frontend/src/theme/components/Button.ts new file mode 100644 index 000000000..d469fcf48 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Button.ts @@ -0,0 +1,394 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { ButtonProps, ButtonThemeConfiguration } from 'io-bricks-ui'; + +export const sizes: ButtonThemeConfiguration['sizes'] = { + sm: { + fontSize: 'sm', + h: 'unset', + minH: 8, + minW: 19, + }, + md: { + fontSize: 'sm', + h: 'unset', + minH: 10, + minW: 19, + }, + lg: { + fontSize: 'sm', + h: 'unset', + minH: 12, + minW: 19, + }, +}; + +interface Color { + enabled: string; + hover: string; + focused: string; + disabled: string; +} + +type ColorName = 'primary' | 'secondary' | 'tertiary'; + +export const colors: Record = { + primary: { + enabled: 'primary.500', + hover: 'primary.400', + focused: 'primary.500', + disabled: 'primary.800', + }, + secondary: { + enabled: 'primary.500', + hover: 'primary.400', + focused: 'primary.500', + disabled: 'primary.800', + }, + tertiary: { + enabled: 'secondary.500', + hover: 'secondary.500', + focused: 'secondary.500', + disabled: 'neutral.600', + }, +}; + +const getColor = (props: ButtonProps, defaultColor: ColorName) => { + if (props.status === 'danger') { + return { + enabled: 'status.error.500', + hover: 'status.error.400', + focused: 'status.error.500', + disabled: 'status.error.800', + }; + } + return colors[defaultColor]; +}; + +export const variants = { + primary: (props: ButtonProps) => { + const getKey = (key: keyof Color) => { + const color = getColor(props, 'primary')[key]; + return { + bg: color, + borderColor: color, + color: 'neutral.white', + }; + }; + return { + ...getKey('enabled'), + _hover: { + ...getKey('hover'), + _disabled: getKey('disabled'), + }, + _focus: getKey('focused'), + _disabled: getKey('disabled'), + _loading: { + ...getKey('enabled'), + _hover: getKey('enabled'), + }, + }; + }, + secondary: (props: ButtonProps) => { + const getKey = (key: keyof Color) => { + const color = getColor(props, 'secondary')[key]; + return { + color, + borderColor: color, + }; + }; + return { + ...getKey('enabled'), + _hover: getKey('hover'), + _focus: getKey('focused'), + _disabled: getKey('disabled'), + }; + }, + tertiary: (props: ButtonProps) => { + const getKey = (key: keyof Color) => { + const bgColor = { + enabled: 'transparent', + hover: 'neutral.150', + focused: 'neutral.100', + disabled: 'transparent', + }[key]; + const color = getColor(props, 'tertiary')[key]; + return { + color, + bgColor, + borderColor: bgColor, + }; + }; + return { + ...getKey('enabled'), + _hover: getKey('hover'), + _focus: getKey('focused'), + _active: getKey('focused'), + _disabled: getKey('disabled'), + }; + }, +}; + +export const Button: ButtonThemeConfiguration = { + baseStyle: { + py: 2, + px: 4, + fontWeight: '500', + lineHeight: 1, + border: '1px solid', + borderRadius: '8px', + display: 'inline-flex', + flexWrap: 'wrap', + justifyContent: 'center', + alignItems: 'center', + transition: 'all 0.2s', + color: 'neutral.650', + leftIcon: { + color: 'neutral.650', + }, + }, + sizes, + variants: { + ...variants, + table: { + color: 'neutral.700', + textDecoration: 'none', + border: 'none', + background: 'transparent', + padding: 0, + minHeight: 'auto', + height: 'auto', + width: '100%', + justifyContent: 'flex-start', + textAlign: 'left', + fontWeight: 'normal', + _hover: { + color: 'primary.600', + textDecoration: 'underline', + background: 'transparent', + }, + _active: { + color: 'primary.700', + background: 'transparent', + }, + _focus: { + boxShadow: 'none', + border: 'none', + color: 'primary.600', + background: 'transparent', + }, + }, + ghost: { + //@ts-ignore TODO: Review this + border: 0, + mr: -3, + minW: 0, + }, + }, + defaultProps: { + size: 'md', + variant: 'primary', + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Header.ts b/apps/mass-payout/frontend/src/theme/components/Header.ts new file mode 100644 index 000000000..e1dc09be9 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Header.ts @@ -0,0 +1,223 @@ +/* + 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. + +*/ + +import { HeaderThemeConfiguration, headerPartsList } from 'io-bricks-ui'; + +export const Header: HeaderThemeConfiguration = { + parts: headerPartsList, + baseStyle: { + container: { + bg: 'neutral.50', + h: 16, + pl: 6, + pr: 8, + py: 4, + }, + + contentContainer: { + maxW: 'full', + }, + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Input.ts b/apps/mass-payout/frontend/src/theme/components/Input.ts new file mode 100644 index 000000000..3b396e1be --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Input.ts @@ -0,0 +1,241 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export const Input = { + baseStyle: { + field: { + bg: 'white', + border: '1px solid', + borderColor: 'neutral.300', + borderRadius: 'md', + _hover: { + borderColor: 'neutral.400', + }, + _focus: { + borderColor: 'primary.500', + boxShadow: '0 0 0 1px var(--chakra-colors-primary-500)', + }, + }, + }, + variants: { + outline: { + field: { + bg: 'white', + border: '1px solid', + borderColor: 'neutral.300', + borderRadius: 'md', + _hover: { + borderColor: 'neutral.400', + }, + _focus: { + borderColor: 'primary.500', + boxShadow: '0 0 0 1px var(--chakra-colors-primary-500)', + }, + }, + }, + }, + defaultProps: { + variant: 'outline', + }, +}; diff --git a/packages/ats/contracts/scripts/commands/DeployProxyAdminCommand.ts b/apps/mass-payout/frontend/src/theme/components/Logo.ts similarity index 98% rename from packages/ats/contracts/scripts/commands/DeployProxyAdminCommand.ts rename to apps/mass-payout/frontend/src/theme/components/Logo.ts index 969446bc1..0021ee62d 100644 --- a/packages/ats/contracts/scripts/commands/DeployProxyAdminCommand.ts +++ b/apps/mass-payout/frontend/src/theme/components/Logo.ts @@ -203,6 +203,11 @@ */ -import { BaseBlockchainCommand } from '../index' - -export default class DeployProxyAdminCommand extends BaseBlockchainCommand {} +import logo from '../../assets/logo.svg'; + +export const Logo = { + baseStyle: { + isoImage: logo, + fullImage: logo, + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/PopUp.ts b/apps/mass-payout/frontend/src/theme/components/PopUp.ts new file mode 100644 index 000000000..033f1b422 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/PopUp.ts @@ -0,0 +1,249 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import type { PopUpThemeConfiguration } from 'io-bricks-ui'; +import { popUpPartsList } from 'io-bricks-ui'; + +export const PopUp: PopUpThemeConfiguration = { + parts: popUpPartsList, + baseStyle: { + container: { + w: '310px', + bg: 'neutral.50', + }, + closeButton: { + minW: 6, + minH: 6, + }, + body: { + textAlign: 'center', + textColor: 'neutral.900', + whiteSpace: 'pre-line', + }, + title: { + textStyle: 'ElementsMediumMD', + mb: 3, + }, + footer: { + pb: 6, + }, + }, + variants: { + warning: { + icon: { + color: 'status.warning.500', + }, + }, + info: { + icon: { + color: 'primary.500', + }, + }, + error: { + icon: { + color: 'status.error.500', + }, + }, + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Progress.ts b/apps/mass-payout/frontend/src/theme/components/Progress.ts new file mode 100644 index 000000000..dc9a847b6 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Progress.ts @@ -0,0 +1,250 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export const Progress = { + baseStyle: { + track: { + bg: 'neutral.100', + borderRadius: 'full', + height: 2, + }, + filledTrack: { + borderRadius: 'full', + transition: 'all 0.3s ease', + }, + }, + sizes: { + lg: { + track: { + height: '8px', + }, + }, + }, + variants: { + inProgress: { + filledTrack: { + bg: 'primary.700', + }, + }, + success: { + filledTrack: { + bg: 'status.success.700', + }, + }, + error: { + filledTrack: { + bg: 'status.error.700', + }, + }, + scheduled: { + filledTrack: { + bg: 'primary.400', + }, + }, + }, + defaultProps: { + size: 'lg', + colorScheme: 'inProgress', + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Select.ts b/apps/mass-payout/frontend/src/theme/components/Select.ts new file mode 100644 index 000000000..f73565d7c --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Select.ts @@ -0,0 +1,241 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export const Select = { + baseStyle: { + field: { + bg: 'white', + border: '1px solid', + borderColor: 'neutral.300', + borderRadius: 'md', + _hover: { + borderColor: 'neutral.400', + }, + _focus: { + borderColor: 'primary.500', + boxShadow: '0 0 0 1px var(--chakra-colors-primary-500)', + }, + }, + }, + variants: { + outline: { + field: { + bg: 'white', + border: '1px solid', + borderColor: 'neutral.300', + borderRadius: 'md', + _hover: { + borderColor: 'neutral.400', + }, + _focus: { + borderColor: 'primary.500', + boxShadow: '0 0 0 1px var(--chakra-colors-primary-500)', + }, + }, + }, + }, + defaultProps: { + variant: 'outline', + }, +}; diff --git a/packages/ats/contracts/scripts/commands/DeployAtsFullInfrastructureCommand.ts b/apps/mass-payout/frontend/src/theme/components/Sidebar.ts similarity index 98% rename from packages/ats/contracts/scripts/commands/DeployAtsFullInfrastructureCommand.ts rename to apps/mass-payout/frontend/src/theme/components/Sidebar.ts index 918f6be3d..6b436558a 100644 --- a/packages/ats/contracts/scripts/commands/DeployAtsFullInfrastructureCommand.ts +++ b/apps/mass-payout/frontend/src/theme/components/Sidebar.ts @@ -203,6 +203,10 @@ */ -import { DeployAtsContractsCommand } from '../' - -export default class DeployAtsFullInfrastructureCommand extends DeployAtsContractsCommand {} +export const Sidebar = { + baseStyle: { + bg: 'neutral.50', + position: 'relative', + apply: 'textStyles.ElementsRegularXS', + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Sidebaritem.ts b/apps/mass-payout/frontend/src/theme/components/Sidebaritem.ts new file mode 100644 index 000000000..731b51934 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Sidebaritem.ts @@ -0,0 +1,260 @@ +/* + 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. + +*/ + +import { + SidebarItemConfigProps, + SidebarItemThemeConfiguration, + sidebarPartsList, +} from 'io-bricks-ui'; + +const iconStyles = { + hover: { + bgColor: 'neutral.150', + }, + + selected: { + bgColor: 'main.primary.100', + color: 'neutral.650', + }, + + disabled: { + bgColor: 'neutral.200', + color: 'neutral.600', + }, +}; + +const labelStyles = { + selected: { + textStyle: 'ElementsSemiboldXS', + }, + + disabled: { + color: 'neutral.600', + textStyle: 'ElementsMediumXS', + }, +}; + +export const SidebarItem: SidebarItemThemeConfiguration = { + parts: sidebarPartsList, + baseStyle: ({ isHovered, isActive, isDisabled }: SidebarItemConfigProps) => { + const isSelected = isActive && !isDisabled; + + return { + icon: { + color: 'neutral.800', + ...(isSelected && iconStyles.selected), + ...(isHovered && !isSelected && iconStyles.hover), + ...(isDisabled && iconStyles.disabled), + }, + + label: { + textStyle: 'ElementsMediumXS', + color: 'neutral.800', + ...(isSelected && labelStyles.selected), + ...(isDisabled && labelStyles.disabled), + }, + }; + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Table.ts b/apps/mass-payout/frontend/src/theme/components/Table.ts new file mode 100644 index 000000000..c4c73aadf --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Table.ts @@ -0,0 +1,297 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { tablePartsList, TableThemeConfiguration } from 'io-bricks-ui'; +import { BasePlatformTheme } from 'io-bricks-ui/Theme'; + +const row = { + bg: 'neutral.400', + boxShadow: '0px 4px 14px rgba(0, 0, 0, 0.05)', +}; + +const disabledColor = 'grey.500'; +const enabledColor = 'grey.900'; + +const baseStyle: TableThemeConfiguration['baseStyle'] = ({ + isSorted, + typeOfSort, +}) => ({ + headerContainer: { + ...row, + bg: 'white', + }, + header: { + // @ts-ignore + ...BasePlatformTheme.textStyles.ElementsMediumSM, + color: 'neutral.900', + px: 3, + py: 4, + }, + cell: { + apply: 'textStyles.ElementsRegularSM', + color: 'neutral.700', + _focusVisible: { + outline: 'var(--chakra-colors-primary-100) auto 1px', + }, + bg: 'white', + "a, button[role='link']": { + color: 'neutral.700', + textDecoration: 'underline', + fontWeight: 'medium', + _hover: { + color: 'primary.600', + textDecoration: 'underline', + }, + _active: { + color: 'primary.700', + }, + _focus: { + boxShadow: 'none', + color: 'primary.600', + }, + }, + }, + rowContainer: { + ...row, + _hover: { + bg: 'neutral.150', + }, + }, + footerText: { + apply: 'textStyles.ElementsRegularXS', + color: 'neutral.900', + mx: 2, + }, + subtext: { + apply: 'textStyles.ElementsLightXS', + color: 'neutral.500', + }, + title: { + ...BasePlatformTheme.textStyles.ElementsSemiboldLG, + }, + sortIcon: { + '& polyline:first-of-type, & line:first-of-type': { + stroke: isSorted + ? typeOfSort === 'desc' + ? enabledColor + : disabledColor + : 'grey.800', + }, + '& polyline:last-of-type, & line:last-of-type': { + stroke: isSorted + ? typeOfSort === 'asc' + ? enabledColor + : disabledColor + : 'grey.800', + }, + }, +}); + +export const Table: TableThemeConfiguration = { + parts: tablePartsList, + baseStyle, + defaultProps: { + size: 'lg', + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Tabs.ts b/apps/mass-payout/frontend/src/theme/components/Tabs.ts new file mode 100644 index 000000000..651e872c8 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Tabs.ts @@ -0,0 +1,34 @@ +/* + Copyright 2024 Pepe Sainz + + 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. +*/ + +export const Tabs = { + baseStyle: { + tab: { + _focus: { + boxShadow: 'none', + outline: 'none', + }, + _focusVisible: { + boxShadow: 'none', + outline: 'none', + }, + }, + tablist: { + borderBottom: '1px solid', + borderBottomColor: 'neutral.400', + }, + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/Tag.ts b/apps/mass-payout/frontend/src/theme/components/Tag.ts new file mode 100644 index 000000000..513d92547 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Tag.ts @@ -0,0 +1,280 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export const Tag = { + baseStyle: { + label: { + apply: 'textStyles.BodyTextMediumSM', + color: 'neutral.1000', + fontWeight: 500, + }, + container: { + color: `neutral.800`, + bg: `neutral.50`, + borderRadius: '19px', + px: 3, + py: 1, + cursor: 'inherit', + pointerEvents: 'none', + height: '18px', + }, + }, + variants: { + active: { + container: { + bg: 'status.active.50', + }, + }, + success: { + container: { + bg: 'status.success.900', + }, + }, + paused: { + container: { + bg: 'status.paused.100', + }, + }, + info: { + container: { + bg: 'status.info.500', + }, + }, + error: { + container: { + bg: 'status.error.500', + }, + }, + failed: { + container: { + bg: 'status.error.200', + }, + }, + warning: { + container: { + bg: 'status.warning.500', + }, + }, + scheduled: { + container: { + bg: 'status.info.200', + }, + }, + inProgress: { + container: { + bg: 'status.inProgress.50', + }, + }, + cancelled: { + container: { + bg: 'status.cancelled.50', + }, + }, + retrying: { + container: { + bg: 'status.paused.50', + }, + }, + }, +}; diff --git a/apps/mass-payout/frontend/src/theme/components/index.ts b/apps/mass-payout/frontend/src/theme/components/index.ts new file mode 100644 index 000000000..3fbbc3a0f --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/index.ts @@ -0,0 +1,242 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Tag } from './Tag'; +import { Table } from './Table'; +import { Button } from './Button'; +import { Header } from './Header'; +import { Sidebar } from './Sidebar'; +import { SidebarItem } from './Sidebaritem'; +import { Breadcrumb } from './Breadcrumb'; +import { Progress } from './Progress'; +import { PopUp } from './PopUp'; +import { Logo } from './Logo'; +import { Select } from './Select'; +import { Input } from './Input'; +import { Tabs } from './Tabs'; + +export const components = { + Tag, + Table, + Button, + Header, + Sidebar, + SidebarItem, + Breadcrumb, + Progress, + PopUp, + Logo, + Select, + Input, + Tabs, +}; + +export { Input } from './Input'; +export { Progress } from './Progress'; +export { Select } from './Select'; +export { Sidebar } from './Sidebar'; +export { SidebarItem } from './Sidebaritem'; +export { Table } from './Table'; +export { Tag } from './Tag'; +export { Tabs } from './Tabs'; diff --git a/apps/mass-payout/frontend/src/theme/index.ts b/apps/mass-payout/frontend/src/theme/index.ts new file mode 100644 index 000000000..cf5dfa256 --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/index.ts @@ -0,0 +1,311 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { extendTheme, type ThemeConfig } from '@chakra-ui/react'; +import _omit from 'lodash/omit'; +import { BasePlatformTheme } from 'io-bricks-ui/Theme'; +import { colors } from './colors'; +import { components } from './components'; + +const config: ThemeConfig = { + initialColorMode: 'light', + useSystemColorMode: false, +}; +const iobricksTheme = _omit(BasePlatformTheme, 'colors'); +const commonContainerLayout = { + w: 'full', + p: 4, + pt: 6, + borderRadius: 1, + '&::-webkit-scrollbar': { + w: 2, + h: '213px', + }, + '&::-webkit-scrollbar-track': { + w: 2, + h: '213px', + }, + '&::-webkit-scrollbar-thumb': { + background: 'primary.100', + borderRadius: '20px', + }, +}; +const theme = extendTheme(iobricksTheme, { + breakpoints: { + sm: '20em', + md: '48em', + lg: '60em', + xl: '75em', + }, + config, + colors, + components, + radii: { + 2: '8px', + normal: '5px', + }, + styles: { + global: { + '*': { + fontWeight: 'unset', + }, + body: { + margin: 0, + padding: 0, + bg: 'white', + color: 'black', + height: '100vh', + fontFamily: 'inter', + WebkitFontSmoothing: 'antialiased', + MozOsxFontSmoothing: 'grayscale', + display: 'flex', + '::-webkit-scrollbar': { + width: '12px', + }, + '::-webkit-scrollbar-track': { + backgroundColor: 'gray.100', + boxShadow: 'inset 0 0 6px rgba(0, 0, 0, .3)', + }, + '::-webkit-scrollbar-thumb': { + backgroundColor: 'gray.400', + borderRadius: '8px', + }, + }, + '#root': { + display: 'flex', + width: '100%', + maxWidth: 'auto', + p: 0, + main: { + flex: 1, + overflow: 'auto', + marginTop: 0, + }, + }, + //For chakra calendar + ".chakra-button[data-testid*='day-']": { + border: 'none ', + outline: 'none ', + boxShadow: 'none ', + }, + }, + }, + layerStyles: { + container: { + ...commonContainerLayout, + bgColor: 'white', + }, + lightContainer: { + flex: 1, + bg: 'neutral.50', + borderRadius: 'lg', + boxShadow: 'sm', + pt: 4, + px: 6, + pb: 6, + }, + }, +}); + +export default theme; diff --git a/apps/mass-payout/frontend/src/types/status.ts b/apps/mass-payout/frontend/src/types/status.ts new file mode 100644 index 000000000..261447d3d --- /dev/null +++ b/apps/mass-payout/frontend/src/types/status.ts @@ -0,0 +1,228 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +export enum ProcessStatus { + COMPLETED = 'Completed', + FAILED = 'Failed', + IN_PROGRESS = 'In Progress', + SCHEDULED = 'Scheduled', + CANCELLED = 'Cancelled', +} + +export enum DistributionsDetailsStatus { + PENDING = 'Pending', + RETRYING = 'Retrying', + SUCCESS = 'Success', + FAILED = 'Failed', +} + +export enum HolderStatus { + FAILED = 'FAILED', + PENDING = 'PENDING', + RETRYING = 'RETRYING', +} + +export type ProcessStatusType = ProcessStatus; +export type DistributionsDetailsStatusType = DistributionsDetailsStatus; +export type HolderStatusType = HolderStatus; diff --git a/apps/mass-payout/frontend/src/utils/assetTransforms.ts b/apps/mass-payout/frontend/src/utils/assetTransforms.ts new file mode 100644 index 000000000..a1d05093f --- /dev/null +++ b/apps/mass-payout/frontend/src/utils/assetTransforms.ts @@ -0,0 +1,237 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { Asset } from '../services/AssetService'; + +export enum AssetStatus { + ACTIVE = 'detail.status.active', + PAUSED = 'detail.status.paused', + COMPLETED = 'detail.status.completed', + SCHEDULED = 'detail.status.scheduled', + IN_PROGRESS = 'detail.status.inProgress', + FAILED = 'detail.status.failed', +} + +export interface AssetData { + assetType: string; + name: string; + assetId: string; + lifecycleCashFlowId: string; + maturityDate?: string; + symbol: string; + status: AssetStatus; +} + +export const transformAssetToAssetData = (asset: Asset): AssetData => ({ + assetType: asset.type, + name: asset.name, + assetId: asset.id, + lifecycleCashFlowId: + asset.lifeCycleCashFlowHederaAddress || + asset.lifeCycleCashFlowEvmAddress || + '', + maturityDate: asset.maturityDate, + symbol: asset.symbol, + status: asset.isPaused ? AssetStatus.PAUSED : AssetStatus.ACTIVE, +}); diff --git a/apps/mass-payout/frontend/src/utils/number-fs.ts b/apps/mass-payout/frontend/src/utils/number-fs.ts new file mode 100644 index 000000000..67c435ffa --- /dev/null +++ b/apps/mass-payout/frontend/src/utils/number-fs.ts @@ -0,0 +1,6 @@ +export function formatNumber(input: string, decimals: number = 2) { + const power = 10 ** decimals; + return (Math.floor(Number.parseFloat(input) * power) / power).toFixed( + decimals, + ); +} diff --git a/apps/mass-payout/frontend/src/views/Assets/AssetDetail/AssetDetail.tsx b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/AssetDetail.tsx new file mode 100644 index 000000000..490bfbcd7 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/AssetDetail.tsx @@ -0,0 +1,368 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { useState, useEffect } from 'react'; +import { useParams, useNavigate, useSearchParams } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import { Text, Spinner } from 'io-bricks-ui'; +import { useDisclosure, Box, Flex } from '@chakra-ui/react'; +import { + useDisableAssetSync, + useEnableAssetSync, + useGetAsset, + usePauseAsset, + useUnpauseAsset, +} from '../hooks/queries/AssetQueries'; +import { useBreadcrumbs } from '@/hooks/useBreadcrumbs'; +import { RoutePath } from '@/router/RoutePath'; +import { AssetHeader } from './components/AssetHeader'; +import { TabsConfiguration } from './components/TabsConfiguration'; +import { PopupConfigurations } from './components/PopupConfigurations'; + +const tabMap = { + details: 0, + distributions: 1, + payments: 2, +}; + +export const AssetDetail = () => { + const { id = '' } = useParams(); + const { t } = useTranslation('assets'); + const { isOpen, onOpen, onClose } = useDisclosure(); + const { + isOpen: isImportOpen, + onOpen: onImportOpen, + onClose: onImportClose, + } = useDisclosure(); + + const navigate = useNavigate(); + const [searchParams, setSearchParams] = useSearchParams(); + + const { data: asset, isLoading: isLoadingAsset, error } = useGetAsset(id); + + const [isPaused, setIsPaused] = useState(false); + const [activeTabIndex, setActiveTabIndex] = useState(0); + const [isImportingCorporateActions, setIsImportingCorporateActions] = + useState(asset?.syncEnabled ?? true); + + const pauseAssetMutation = usePauseAsset(); + const unpauseAssetMutation = useUnpauseAsset(); + const enableSyncMutation = useEnableAssetSync(); + const disableSyncMutation = useDisableAssetSync(); + + const routes = useBreadcrumbs({}); + + useEffect(() => { + if (asset) { + setIsPaused(asset.isPaused); + setIsImportingCorporateActions(asset.syncEnabled); + } + }, [asset]); + + useEffect(() => { + const tabParam = searchParams.get('tab'); + if (tabParam && tabMap[tabParam as keyof typeof tabMap] !== undefined) { + setActiveTabIndex(tabMap[tabParam as keyof typeof tabMap]); + } + }, [searchParams]); + + const handleNewDistribution = () => { + navigate(RoutePath.NEW_DISTRIBUTION.replace(':id', id)); + }; + + const handleImportCorporateActions = () => { + onImportOpen(); + }; + + const handleImportConfirm = () => { + const newSyncState = !isImportingCorporateActions; + if (newSyncState) { + enableSyncMutation.mutate(id); + } else { + disableSyncMutation.mutate(id); + } + setIsImportingCorporateActions(newSyncState); + onImportClose(); + }; + + const handleImportCancel = () => { + onImportClose(); + }; + + if (isLoadingAsset) { + return ( + + + {t('loading', 'Loading asset...')} + + ); + } + + if (error || !asset) { + return ( + + + {t('error', 'Error loading asset or asset not found')} + + + ); + } + + const handlePauseUnpause = async () => { + if (!asset.id) return; + + try { + if (isPaused) { + await unpauseAssetMutation.mutateAsync(asset.id); + } else { + await pauseAssetMutation.mutateAsync(asset.id); + } + setIsPaused(!isPaused); + onClose(); + } catch (error) { + console.error('Error pausing asset:', error); + } + }; + + const isMutationLoading = + pauseAssetMutation.isPending || unpauseAssetMutation.isPending; + + const handleTabChange = (index: number) => { + setActiveTabIndex(index); + const tabNames = ['details', 'distributions', 'payments']; + const newSearchParams = new URLSearchParams(searchParams); + newSearchParams.set('tab', tabNames[index]); + setSearchParams(newSearchParams); + }; + + return ( + <> + + + + + ); +}; diff --git a/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/AssetDetail.test.tsx b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/AssetDetail.test.tsx new file mode 100644 index 000000000..61204a427 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/AssetDetail.test.tsx @@ -0,0 +1,528 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { render } from '@/test-utils'; +import { screen } from '@testing-library/react'; +import { createMemoryHistory } from 'history'; +import { AssetType } from '@/services/AssetService'; +import { + mockAsset, + resetAssetMocks, + createMockAsset, +} from '@/test-utils/mocks/AssetMocks'; +import { AssetDetail } from '../AssetDetail'; + +const mockNavigate = jest.fn(); +const mockPauseMutateAsync = jest.fn(); +const mockUnpauseMutateAsync = jest.fn(); +const mockEnableSyncMutate = jest.fn(); +const mockDisableSyncMutate = jest.fn(); +const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useParams: () => ({ id: '0.0.890123' }), + useNavigate: () => mockNavigate, + useSearchParams: () => [new URLSearchParams(), jest.fn()], +})); + +jest.mock('../../hooks/queries/AssetQueries', () => ({ + useGetAsset: jest.fn(), + usePauseAsset: jest.fn(), + useUnpauseAsset: jest.fn(), + useEnableAssetSync: jest.fn(), + useDisableAssetSync: jest.fn(), +})); + +jest.mock('@/hooks/useBreadcrumbs', () => ({ + useBreadcrumbs: () => [ + { label: 'Asset list', href: '/assets' }, + { label: 'Asset Detail' }, + ], +})); + +// Mock child components +jest.mock('../components/AssetHeader', () => ({ + AssetHeader: jest.fn(({ asset }) => ( +
+
+ {asset?.isPaused ? 'Paused' : 'Active'} +
+ {asset && ( +
+ {asset.name} - {asset.hederaTokenAddress} +
+ )} +
+ )), +})); + +jest.mock('../components/TabsConfiguration', () => ({ + TabsConfiguration: jest.fn(({ asset }) => ( +
+ + + +
+ )), +})); + +jest.mock('../components/PopupConfigurations', () => ({ + PopupConfigurations: jest.fn(() => ( +
Mock Popup
+ )), +})); + +describe('AssetDetail Component', () => { + let history: ReturnType; + const mockUseGetAsset = require('../../hooks/queries/AssetQueries') + .useGetAsset as jest.MockedFunction; + const mockUsePauseAsset = require('../../hooks/queries/AssetQueries') + .usePauseAsset as jest.MockedFunction; + const mockUseUnpauseAsset = require('../../hooks/queries/AssetQueries') + .useUnpauseAsset as jest.MockedFunction; + const mockUseEnableAssetSync = require('../../hooks/queries/AssetQueries') + .useEnableAssetSync as jest.MockedFunction; + const mockUseDisableAssetSync = require('../../hooks/queries/AssetQueries') + .useDisableAssetSync as jest.MockedFunction; + + beforeEach(() => { + history = createMemoryHistory({ + initialEntries: [`/assets/${mockAsset.id}`], + }); + + jest.clearAllMocks(); + resetAssetMocks(); + consoleSpy.mockClear(); + + // Default mock implementations + mockUseGetAsset.mockReturnValue({ + data: mockAsset, + isLoading: false, + error: null, + }); + + mockUsePauseAsset.mockReturnValue({ + mutateAsync: mockPauseMutateAsync, + isPending: false, + }); + + mockUseUnpauseAsset.mockReturnValue({ + mutateAsync: mockUnpauseMutateAsync, + isPending: false, + }); + + mockUseEnableAssetSync.mockReturnValue({ + mutate: mockEnableSyncMutate, + }); + + mockUseDisableAssetSync.mockReturnValue({ + mutate: mockDisableSyncMutate, + }); + }); + + afterAll(() => { + consoleSpy.mockRestore(); + }); + + describe('Basic rendering', () => { + test('should render correctly', () => { + const component = render(, { history }); + expect(component.asFragment()).toMatchSnapshot(); + }); + + test('should display tabs configuration', () => { + render(, { history }); + expect(screen.getByTestId('tabs-configuration')).toBeInTheDocument(); + expect(screen.getByTestId('pause-unpause-button')).toBeInTheDocument(); + expect( + screen.getByTestId('import-corporate-actions-button'), + ).toBeInTheDocument(); + expect(screen.getByTestId('new-distribution-button')).toBeInTheDocument(); + }); + + test('should display popup configurations', () => { + render(, { history }); + expect(screen.getByTestId('popup-configurations')).toBeInTheDocument(); + }); + }); + + describe('Loading states', () => { + test('should show loading spinner when asset is loading', () => { + mockUseGetAsset.mockReturnValue({ + data: null, + isLoading: true, + error: null, + }); + + render(, { history }); + expect(screen.getByText('Loading asset...')).toBeInTheDocument(); + }); + + test('should show error message when asset loading fails', () => { + mockUseGetAsset.mockReturnValue({ + data: null, + isLoading: false, + error: new Error('Failed to load asset'), + }); + + render(, { history }); + expect( + screen.getByText('Error loading asset or asset not found'), + ).toBeInTheDocument(); + }); + + test('should show error message when asset is not found', () => { + mockUseGetAsset.mockReturnValue({ + data: null, + isLoading: false, + error: null, + }); + + render(, { history }); + expect( + screen.getByText('Error loading asset or asset not found'), + ).toBeInTheDocument(); + }); + }); + + describe('Asset status management', () => { + test('should display active status for unpaused asset', () => { + const activeAsset = createMockAsset({ isPaused: false }); + mockUseGetAsset.mockReturnValue({ + data: activeAsset, + isLoading: false, + error: null, + }); + + render(, { history }); + expect(screen.getByTestId('asset-status')).toHaveTextContent('Active'); + expect(screen.getByTestId('pause-unpause-button')).toHaveTextContent( + 'Pause Asset', + ); + }); + + test('should display paused status for paused asset', () => { + const pausedAsset = createMockAsset({ isPaused: true }); + mockUseGetAsset.mockReturnValue({ + data: pausedAsset, + isLoading: false, + error: null, + }); + + render(, { history }); + expect(screen.getByTestId('asset-status')).toHaveTextContent('Paused'); + expect(screen.getByTestId('pause-unpause-button')).toHaveTextContent( + 'Unpause Asset', + ); + }); + + test('should render pause/unpause button', () => { + render(, { history }); + expect(screen.getByTestId('pause-unpause-button')).toBeInTheDocument(); + }); + }); + + describe('Sync management', () => { + test('should display correct sync button text for enabled sync', () => { + const syncEnabledAsset = createMockAsset({ syncEnabled: true }); + mockUseGetAsset.mockReturnValue({ + data: syncEnabledAsset, + isLoading: false, + error: null, + }); + + render(, { history }); + expect( + screen.getByTestId('import-corporate-actions-button'), + ).toHaveTextContent('Disable Sync'); + }); + + test('should display correct sync button text for disabled sync', () => { + const syncDisabledAsset = createMockAsset({ syncEnabled: false }); + mockUseGetAsset.mockReturnValue({ + data: syncDisabledAsset, + isLoading: false, + error: null, + }); + + render(, { history }); + expect( + screen.getByTestId('import-corporate-actions-button'), + ).toHaveTextContent('Enable Sync'); + }); + + test('should render import corporate actions button', () => { + render(, { history }); + expect( + screen.getByTestId('import-corporate-actions-button'), + ).toBeInTheDocument(); + }); + }); + + describe('Navigation and tabs', () => { + test('should render new distribution button', () => { + render(, { history }); + expect(screen.getByTestId('new-distribution-button')).toBeInTheDocument(); + }); + }); + + describe('Asset data integration', () => { + test('should handle different asset types', () => { + const bondAsset = createMockAsset({ + type: AssetType.BOND, + name: 'Bond Asset', + symbol: 'BOND', + }); + + mockUseGetAsset.mockReturnValue({ + data: bondAsset, + isLoading: false, + error: null, + }); + + render(, { history }); + + expect( + screen.getByText(`${bondAsset.name} - ${bondAsset.hederaTokenAddress}`), + ).toBeInTheDocument(); + }); + + test('should handle asset without ID correctly', () => { + const assetWithoutId = createMockAsset({ id: '' }); + mockUseGetAsset.mockReturnValue({ + data: assetWithoutId, + isLoading: false, + error: null, + }); + + render(, { history }); + + expect(screen.getByTestId('asset-header')).toBeInTheDocument(); + }); + + test('should update state when asset data changes', () => { + const { rerender } = render(, { history }); + + // Initially active + expect(screen.getByTestId('asset-status')).toHaveTextContent('Active'); + + // Update to paused asset + const pausedAsset = createMockAsset({ isPaused: true }); + mockUseGetAsset.mockReturnValue({ + data: pausedAsset, + isLoading: false, + error: null, + }); + + rerender(); + + expect(screen.getByTestId('asset-status')).toHaveTextContent('Paused'); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/AssetHeader.test.tsx b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/AssetHeader.test.tsx new file mode 100644 index 000000000..7d44e3e46 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/AssetHeader.test.tsx @@ -0,0 +1,272 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { screen } from '@testing-library/react'; +import { AssetHeader } from '../components/AssetHeader'; +import type { Asset } from '@/services/AssetService'; +import { AssetType } from '@/services/AssetService'; +import type { BreadcrumbItem } from '@/hooks/useBreadcrumbs'; +import { Link as RouterLink } from 'react-router-dom'; +import { render } from '@/test-utils'; + +describe('AssetHeader', () => { + const mockAsset: Asset = { + id: '1', + name: 'Test Asset', + hederaTokenAddress: '0x123456789', + type: AssetType.EQUITY, + symbol: 'TST', + evmTokenAddress: '0x123456789', + lifeCycleCashFlowEvmAddress: '0x123456789', + isPaused: false, + syncEnabled: true, + createdAt: '2023-01-01T00:00:00Z', + updatedAt: '2023-01-01T00:00:00Z', + }; + + const mockRoutes: BreadcrumbItem[] = [ + { + label: 'Home', + link: { as: RouterLink, to: '/' }, + isActive: false, + }, + { + label: 'Assets', + link: { as: RouterLink, to: '/assets' }, + isActive: false, + }, + { + label: 'Asset Detail', + link: { as: RouterLink, to: '/assets/1' }, + isActive: true, + }, + ]; + + const defaultProps = { + asset: mockAsset, + routes: mockRoutes, + isPaused: false, + }; + + it('should match snapshot', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + + it('should render go back button with correct label', () => { + render(); + + const goBackButton = screen.getByTestId('go-back-button'); + expect(goBackButton).toBeInTheDocument(); + expect(goBackButton).toHaveTextContent( + `${mockAsset.name} - ${mockAsset.hederaTokenAddress}`, + ); + }); + + it('should render distributions status label', () => { + render(); + + expect(screen.getByText('Distributions status:')).toBeInTheDocument(); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/Details.test.tsx b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/Details.test.tsx new file mode 100644 index 000000000..9ea8e2bfb --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/Details.test.tsx @@ -0,0 +1,346 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { render } from '../../../../test-utils'; +import { Asset, AssetType } from '@/services/AssetService'; +import { format } from 'date-fns'; +import { Details } from '../components/Details'; + +// Mock dependencies +jest.mock('date-fns', () => ({ + format: jest.fn((date: Date, formatStr: string) => { + if (formatStr === 'dd/MM/yyyy') { + return '15/12/2025'; + } + return date.toISOString(); + }), +})); + +const mockAsset: Asset = { + id: '1', + name: 'Test Asset', + symbol: 'TEST', + type: AssetType.BOND, + hederaTokenAddress: '0.0.123456', + evmTokenAddress: '0x1234567890abcdef', + lifeCycleCashFlowHederaAddress: '0.0.789012', + lifeCycleCashFlowEvmAddress: '0xabcdef1234567890', + maturityDate: '2025-12-15T00:00:00Z', + isPaused: false, + syncEnabled: true, + createdAt: '2024-01-01T00:00:00Z', + updatedAt: '2024-01-01T00:00:00Z', +}; + +const mockAssetWithoutOptionalFields: Asset = { + id: '2', + name: 'Simple Asset', + symbol: 'SIMPLE', + type: AssetType.EQUITY, + hederaTokenAddress: '', + evmTokenAddress: '', + lifeCycleCashFlowHederaAddress: '', + lifeCycleCashFlowEvmAddress: '', + maturityDate: undefined, + isPaused: false, + syncEnabled: false, + createdAt: '2024-01-01T00:00:00Z', + updatedAt: '2024-01-01T00:00:00Z', +}; + +describe('Details Component', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Basic Rendering', () => { + it('should match snapshot', () => { + const component = render( +
, + ); + expect(component.asFragment()).toMatchSnapshot(); + }); + + it('should render the component with asset data', () => { + const component = render( +
, + ); + + expect(component.getByText('Asset details')).toBeInTheDocument(); + expect( + component.getByTestId('definition-list-item-Name'), + ).toBeInTheDocument(); + expect( + component.getByTestId('definition-list-item-Symbol'), + ).toBeInTheDocument(); + expect(component.getByText('Test Asset')).toBeInTheDocument(); + expect(component.getByText('TEST')).toBeInTheDocument(); + }); + + it('should render with loading state', () => { + const component = render(
); + expect(component.getByText('Asset details')).toBeInTheDocument(); + }); + + it('should render without asset data', () => { + const component = render(
); + + expect(component.getByText('Asset details')).toBeInTheDocument(); + + expect( + component.getByTestId('definition-list-item-Name'), + ).toBeInTheDocument(); + expect( + component.getByTestId('definition-list-item-Symbol'), + ).toBeInTheDocument(); + }); + }); + + describe('Asset Data Display', () => { + it('should display asset name and symbol', () => { + const component = render( +
, + ); + + expect(component.getByText('Test Asset')).toBeInTheDocument(); + expect(component.getByText('TEST')).toBeInTheDocument(); + }); + + it('should display formatted maturity date when available', () => { + const component = render( +
, + ); + + expect(format).toHaveBeenCalledWith( + new Date('2025-12-15T00:00:00Z'), + 'dd/MM/yyyy', + ); + expect(component.getByText('15/12/2025')).toBeInTheDocument(); + }); + + it('should not display maturity date when not available', () => { + const component = render( +
, + ); + + expect(component.queryByText('Maturity Date')).not.toBeInTheDocument(); + }); + + it('should display empty strings for missing addresses', () => { + const component = render( +
, + ); + + expect( + component.queryByTestId('clipboard-button'), + ).not.toBeInTheDocument(); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/PopupConfigurations.test.tsx b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/PopupConfigurations.test.tsx new file mode 100644 index 000000000..8305616da --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/PopupConfigurations.test.tsx @@ -0,0 +1,444 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { screen, fireEvent } from '@testing-library/react'; +import type { Asset } from '@/services/AssetService'; +import { AssetType } from '@/services/AssetService'; +import { render } from '@/test-utils'; +import { PopupConfigurations } from '../components/PopupConfigurations'; + +// Mock io-bricks-ui components +jest.mock('io-bricks-ui', () => ({ + PopUp: jest.fn( + ({ + id, + isOpen, + onClose, + onConfirm, + onCancel, + icon, + title, + description, + confirmText, + cancelText, + variant, + confirmButtonProps, + }) => + isOpen ? ( +
+
{icon}
+
{title}
+
{description}
+ + + +
+
+ ) : null, + ), + PhosphorIcon: jest.fn(({ as: IconComponent, size, weight, ...props }) => ( +
+ {IconComponent?.name || 'Icon'} +
+ )), + Weight: { + Light: 'light', + }, +})); + +// Mock phosphor icons +jest.mock('@phosphor-icons/react', () => ({ + Warning: { name: 'Warning' }, + Info: { name: 'Info' }, +})); + +const mockAsset: Asset = { + id: 'asset-123', + name: 'Test Asset', + symbol: 'TEST', + type: AssetType.BOND, + hederaTokenAddress: '0.0.123456', + evmTokenAddress: '0x1234567890abcdef', + lifeCycleCashFlowEvmAddress: '0xabcdef1234567890', + maturityDate: '2025-12-31', + isPaused: false, + syncEnabled: true, + createdAt: '2023-01-01T00:00:00Z', + updatedAt: '2023-01-01T00:00:00Z', +}; + +const defaultProps = { + asset: mockAsset, + isPaused: false, + isImportingCorporateActions: false, + isOpen: false, + isImportOpen: false, + isMutationLoading: false, + onClose: jest.fn(), + onImportClose: jest.fn(), + onConfirmPauseUnpause: jest.fn(), + onConfirmImport: jest.fn(), +}; + +const renderPopupConfigurations = (props = {}) => { + return render(); +}; + +describe('PopupConfigurations', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Basic Rendering', () => { + it('should match snapshot', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + + it('should not render popups when both are closed', () => { + renderPopupConfigurations(); + + expect( + screen.queryByTestId('popup-pauseUnpauseDistributions'), + ).not.toBeInTheDocument(); + expect( + screen.queryByTestId('popup-importCorporateActions'), + ).not.toBeInTheDocument(); + }); + + it('should render pause popup when isOpen is true and isPaused is false', () => { + renderPopupConfigurations({ isOpen: true, isPaused: false }); + + const popup = screen.getByTestId('popup-pauseUnpauseDistributions'); + expect(popup).toBeInTheDocument(); + expect(screen.getByTestId('popup-title')).toHaveTextContent( + 'Pause Asset', + ); + expect(screen.getByTestId('popup-description')).toHaveTextContent( + 'Are you sure you want to pause this asset?', + ); + expect(screen.getByTestId('popup-confirm')).toHaveTextContent('Pause'); + expect(screen.getByTestId('popup-cancel')).toHaveTextContent('Cancel'); + }); + + it('should render unpause popup when isOpen is true and isPaused is true', () => { + renderPopupConfigurations({ isOpen: true, isPaused: true }); + + const popup = screen.getByTestId('popup-pauseUnpauseDistributions'); + expect(popup).toBeInTheDocument(); + expect(screen.getByTestId('popup-title')).toHaveTextContent( + 'Unpause Asset', + ); + expect(screen.getByTestId('popup-description')).toHaveTextContent( + 'Are you sure you want to unpause this asset?', + ); + expect(screen.getByTestId('popup-confirm')).toHaveTextContent('Unpause'); + expect(screen.getByTestId('popup-cancel')).toHaveTextContent('Cancel'); + }); + }); + + describe('Icons and Variants', () => { + it('should use Warning icon and warning variant for pause popup', () => { + renderPopupConfigurations({ isOpen: true, isPaused: false }); + + const icon = screen.getByTestId('popup-icon'); + const variant = screen.getByTestId('popup-variant'); + + expect(icon).toHaveTextContent('Warning'); + expect(variant).toHaveAttribute('data-variant', 'warning'); + }); + + it('should use Info icon and info variant for unpause popup', () => { + renderPopupConfigurations({ isOpen: true, isPaused: true }); + + const icon = screen.getByTestId('popup-icon'); + const variant = screen.getByTestId('popup-variant'); + + expect(icon).toHaveTextContent('Info'); + expect(variant).toHaveAttribute('data-variant', 'info'); + }); + + it('should use Info icon and info variant for import corporate actions popup', () => { + renderPopupConfigurations({ isImportOpen: true }); + + const icon = screen.getByTestId('popup-icon'); + const variant = screen.getByTestId('popup-variant'); + + expect(icon).toHaveTextContent('Info'); + expect(variant).toHaveAttribute('data-variant', 'info'); + }); + }); + + describe('User Interactions', () => { + it('should call onConfirmPauseUnpause when pause popup confirm is clicked', () => { + const onConfirmPauseUnpause = jest.fn(); + renderPopupConfigurations({ isOpen: true, onConfirmPauseUnpause }); + + fireEvent.click(screen.getByTestId('popup-confirm')); + + expect(onConfirmPauseUnpause).toHaveBeenCalledTimes(1); + }); + + it('should call onClose when pause popup cancel is clicked', () => { + const onClose = jest.fn(); + renderPopupConfigurations({ isOpen: true, onClose }); + + fireEvent.click(screen.getByTestId('popup-cancel')); + + expect(onClose).toHaveBeenCalledTimes(1); + }); + + it('should call onClose when pause popup close is clicked', () => { + const onClose = jest.fn(); + renderPopupConfigurations({ isOpen: true, onClose }); + + fireEvent.click(screen.getByTestId('popup-close')); + + expect(onClose).toHaveBeenCalledTimes(1); + }); + + it('should call onConfirmImport when import popup confirm is clicked', () => { + const onConfirmImport = jest.fn(); + renderPopupConfigurations({ isImportOpen: true, onConfirmImport }); + + fireEvent.click(screen.getByTestId('popup-confirm')); + + expect(onConfirmImport).toHaveBeenCalledTimes(1); + }); + + it('should call onImportClose when import popup cancel is clicked', () => { + const onImportClose = jest.fn(); + renderPopupConfigurations({ isImportOpen: true, onImportClose }); + + fireEvent.click(screen.getByTestId('popup-cancel')); + + expect(onImportClose).toHaveBeenCalledTimes(1); + }); + + it('should call onImportClose when import popup close is clicked', () => { + const onImportClose = jest.fn(); + renderPopupConfigurations({ isImportOpen: true, onImportClose }); + + fireEvent.click(screen.getByTestId('popup-close')); + + expect(onImportClose).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/TabsConfiguration.test.tsx b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/TabsConfiguration.test.tsx new file mode 100644 index 000000000..0184a998f --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/TabsConfiguration.test.tsx @@ -0,0 +1,350 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { screen } from '@testing-library/react'; +import type { Asset } from '@/services/AssetService'; +import { AssetType } from '@/services/AssetService'; +import { render } from '@/test-utils'; +import { TabsConfiguration } from '../components/TabsConfiguration'; + +// Mock dependencies + +jest.mock('io-bricks-ui', () => ({ + Tabs: ({ tabs, variant, index, onChange, ...props }: any) => ( +
+ {tabs?.map((tab: any, i: number) => ( +
+
{tab.header}
+
{tab.content}
+ +
+ ))} +
+ ), +})); + +jest.mock('../../AssetDistributions/AssetDistributions', () => ({ + AssetDistributions: ({ + assetId, + isPaused, + onPauseUnpause, + onImportCorporateActions, + isImportingCorporateActions, + handleNewDistribution, + ...props + }: any) => ( +
+ + + +
+ ), +})); + +jest.mock('../components/Details', () => ({ + Details: ({ assetData, isLoading, ...props }: any) => ( +
+ {assetData ? ( +
+ {assetData.name} + {assetData.symbol} +
+ ) : ( +
No asset data
+ )} +
+ ), +})); + +const mockAsset: Asset = { + id: 'asset-123', + name: 'Test Asset', + symbol: 'TST', + type: AssetType.BOND, + hederaTokenAddress: '0x123', + evmTokenAddress: '0x456', + lifeCycleCashFlowEvmAddress: '0x789', + maturityDate: '2024-12-31', + isPaused: false, + syncEnabled: true, + createdAt: '2024-01-01T00:00:00Z', + updatedAt: '2024-01-01T00:00:00Z', +}; + +const defaultProps = { + asset: mockAsset, + isLoadingAsset: false, + id: 'asset-123', + isPaused: false, + isImportingCorporateActions: false, + activeTabIndex: 0, + onPauseUnpause: jest.fn(), + onImportCorporateActions: jest.fn(), + onNewDistribution: jest.fn(), + onTabChange: jest.fn(), +}; + +describe('TabsConfiguration Component', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Basic Rendering', () => { + it('should match snapshot', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + + it('should render both tabs', () => { + render(); + + expect(screen.getByTestId('tab-0')).toBeInTheDocument(); + expect(screen.getByTestId('tab-1')).toBeInTheDocument(); + expect(screen.getByTestId('tabs')).toHaveAttribute( + 'data-tabs-count', + '2', + ); + }); + + it('should render tab headers with correct translations', () => { + render(); + + expect(screen.getByTestId('tab-header-0')).toHaveTextContent('Details'); + expect(screen.getByTestId('tab-header-1')).toHaveTextContent( + 'Distributions', + ); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/__snapshots__/AssetDetail.test.tsx.snap b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/__snapshots__/AssetDetail.test.tsx.snap new file mode 100644 index 000000000..80f2a1d60 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/__snapshots__/AssetDetail.test.tsx.snap @@ -0,0 +1,46 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AssetDetail Component Basic rendering should render correctly 1`] = ` + +
+
+ Active +
+
+ Test Asset - 0.0.123456 +
+
+
+ + + +
+
+ Mock Popup +
+
+`; diff --git a/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/__snapshots__/AssetHeader.test.tsx.snap b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/__snapshots__/AssetHeader.test.tsx.snap new file mode 100644 index 000000000..97616df34 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/AssetDetail/__tests__/__snapshots__/AssetHeader.test.tsx.snap @@ -0,0 +1,152 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AssetHeader should match snapshot 1`] = ` + +
+ +
+
+
+ +

+ Test Asset - 0x123456789 +

+
+
+

+ Distributions status: +

+ +
+
+
+
+
+
+ )} + + + ); +}; diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/Assets.tsx b/apps/mass-payout/frontend/src/views/Assets/Assets/Assets.tsx new file mode 100644 index 000000000..07fd4fced --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/Assets.tsx @@ -0,0 +1,277 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { useTranslation } from 'react-i18next'; +import { useForm, useWatch } from 'react-hook-form'; +import { useTable } from '@/hooks/useTable'; +import { useAssetsColumns } from '../hooks/useAssetsColumns'; +import { useGetAssets } from '../hooks/queries/AssetQueries'; +import { AssetHeader } from './components/AssetHeader'; +import { AssetFilters } from './components/AssetFilters'; +import { AssetTable } from './components/AssetTable'; + +export const Assets = () => { + const { t } = useTranslation('assets'); + const table = useTable(); + const { columns } = useAssetsColumns(); + const { pagination, sorting } = table; + + const { data, isLoading } = useGetAssets({ + page: pagination.pageIndex, + sort: sorting, + size: pagination.pageSize, + }); + + const { control } = useForm({ + mode: 'onChange', + defaultValues: { + assetType: '', + search: '', + }, + }); + + const assetTypeOptions = [ + { value: 'all', label: t('filters.options.allTypes') }, + { value: 'Bond', label: t('filters.options.bond') }, + { value: 'Equity', label: t('filters.options.equity') }, + ]; + + const selectedAssetType = useWatch({ control, name: 'assetType' }); + const searchTerm = useWatch({ control, name: 'search' }); + + const filteredAssets = (data?.queryData || []).filter((asset) => { + if ( + selectedAssetType && + selectedAssetType !== 'all' && + selectedAssetType !== '' + ) { + if (asset.type !== selectedAssetType) return false; + } + + if (searchTerm) { + const searchLower = searchTerm.toLowerCase(); + return ( + asset.name.toLowerCase().includes(searchLower) || + asset.hederaTokenAddress?.toLowerCase().includes(searchLower) || + asset.evmTokenAddress?.toLowerCase().includes(searchLower) + ); + } + + return true; + }); + + return ( + <> + + + + + ); +}; diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/AssetHeader.test.tsx b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/AssetHeader.test.tsx new file mode 100644 index 000000000..cbc49c29a --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/AssetHeader.test.tsx @@ -0,0 +1,270 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import userEvent from '@testing-library/user-event'; +import { AssetHeader } from '../components/AssetHeader'; +import { RouterManager } from '@/router/RouterManager'; +import { RouteName } from '@/router/RouteName'; +import { render } from '@/test-utils'; + +describe('AssetHeader', () => { + const mockRouterTo = RouterManager.to as jest.MockedFunction< + typeof RouterManager.to + >; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Basic Rendering', () => { + it('should render correctly', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + + it('should render the header with title', () => { + const component = render(); + + expect(component.getAllByText('Import Asset')[0]).toBeInTheDocument(); + }); + + it('should render the import asset button', () => { + const component = render(); + + expect( + component.getAllByRole('button', { name: 'Import Asset' })[0], + ).toBeInTheDocument(); + }); + }); + + describe('Interactions', () => { + it('should navigate to ImportAsset when button is clicked', async () => { + const user = userEvent.setup(); + const component = render(); + + const importButton = component.getByRole('button', { + name: 'Import Asset', + }); + await user.click(importButton); + + expect(mockRouterTo).toHaveBeenCalledWith(RouteName.ImportAsset); + }); + + it('should handle multiple button clicks', async () => { + const user = userEvent.setup(); + const component = render(); + + const importButton = component.getByRole('button', { + name: 'Import Asset', + }); + + await user.click(importButton); + await user.click(importButton); + + expect(mockRouterTo).toHaveBeenCalledTimes(2); + expect(mockRouterTo).toHaveBeenNthCalledWith(1, RouteName.ImportAsset); + expect(mockRouterTo).toHaveBeenNthCalledWith(2, RouteName.ImportAsset); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/AssetTable.test.tsx b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/AssetTable.test.tsx new file mode 100644 index 000000000..8453cf2d1 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/AssetTable.test.tsx @@ -0,0 +1,382 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { AssetTable } from '../components/AssetTable'; +import { RouterManager } from '@/router/RouterManager'; +import { RouteName } from '@/router/RouteName'; +import type { Asset } from '@/services/AssetService'; +import { AssetType } from '@/services/AssetService'; +import type { UseTableReturn } from '@/hooks/useTable'; +import { render } from '@/test-utils'; + +const mockAssets: Asset[] = [ + { + id: '1', + name: 'Test Asset 1', + type: AssetType.EQUITY, + symbol: 'TST1', + hederaTokenAddress: '0.0.123456', + evmTokenAddress: '0x123456', + lifeCycleCashFlowEvmAddress: '0x789012', + isPaused: false, + syncEnabled: true, + createdAt: '2024-01-01T00:00:00Z', + updatedAt: '2024-01-01T00:00:00Z', + }, + { + id: '2', + name: 'Test Asset 2', + type: AssetType.BOND, + symbol: 'TST2', + hederaTokenAddress: '0.0.654321', + evmTokenAddress: '0x654321', + lifeCycleCashFlowEvmAddress: '0x210987', + isPaused: true, + syncEnabled: false, + createdAt: '2024-01-02T00:00:00Z', + updatedAt: '2024-01-02T00:00:00Z', + }, +]; + +const mockColumns = [ + { id: 'name', header: 'Name' }, + { id: 'type', header: 'Type' }, + { id: 'status', header: 'Status' }, +]; + +const mockTable: UseTableReturn = { + pagination: { pageIndex: 0, pageSize: 10 }, + setPagination: jest.fn(), + sorting: [], + setSorting: jest.fn(), +}; + +const defaultProps = { + isLoading: false, + columns: mockColumns, + filteredAssets: mockAssets, + totalPages: 1, + table: mockTable, +}; + +describe('AssetTable', () => { + const mockRouterTo = RouterManager.to as jest.MockedFunction< + typeof RouterManager.to + >; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Basic Rendering', () => { + it('should match snapshot', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + + it('should render with empty data', () => { + render(); + + expect(screen.getByTestId('table-assets')).toBeInTheDocument(); + expect(screen.queryByTestId('row-0')).not.toBeInTheDocument(); + }); + }); + + describe('Props Integration', () => { + it('should pass correct props to Table component', () => { + render(); + + const table = screen.getByTestId('table-assets'); + expect(table).toBeInTheDocument(); + }); + + it('should handle different totalPages values', () => { + render(); + + const table = screen.getByTestId('table-assets'); + expect(table).toBeInTheDocument(); + }); + + it('should pass table props correctly', () => { + const customTable = { + ...mockTable, + pagination: { pageIndex: 2, pageSize: 20 }, + }; + + render(); + + const table = screen.getByTestId('table-assets'); + expect(table).toBeInTheDocument(); + }); + }); + + describe('Row Click Interactions', () => { + it('should navigate to asset detail when row is clicked', async () => { + const user = userEvent.setup(); + render(); + + const firstRow = screen.getByTestId('row-0'); + await user.click(firstRow); + + expect(mockRouterTo).toHaveBeenCalledWith(RouteName.AssetDetail, { + params: { id: '1' }, + }); + }); + + it('should navigate with correct asset id for different rows', async () => { + const user = userEvent.setup(); + render(); + + const secondRow = screen.getByTestId('row-1'); + await user.click(secondRow); + + expect(mockRouterTo).toHaveBeenCalledWith(RouteName.AssetDetail, { + params: { id: '2' }, + }); + }); + + it('should handle multiple row clicks', async () => { + const user = userEvent.setup(); + render(); + + const firstRow = screen.getByTestId('row-0'); + const secondRow = screen.getByTestId('row-1'); + + await user.click(firstRow); + await user.click(secondRow); + + expect(mockRouterTo).toHaveBeenCalledTimes(2); + expect(mockRouterTo).toHaveBeenNthCalledWith(1, RouteName.AssetDetail, { + params: { id: '1' }, + }); + expect(mockRouterTo).toHaveBeenNthCalledWith(2, RouteName.AssetDetail, { + params: { id: '2' }, + }); + }); + }); + + describe('Data Handling', () => { + it('should handle large datasets', () => { + const largeDataset = Array.from({ length: 100 }, (_, index) => ({ + id: `asset-${index}`, + name: `Asset ${index}`, + type: index % 2 === 0 ? AssetType.EQUITY : AssetType.BOND, + symbol: `SYM${index}`, + hederaTokenAddress: `0.0.${index}`, + evmTokenAddress: `0x${index}`, + lifeCycleCashFlowEvmAddress: `0x${index + 1000}`, + isPaused: false, + syncEnabled: true, + createdAt: '2024-01-01T00:00:00Z', + updatedAt: '2024-01-01T00:00:00Z', + })); + + render(); + + expect(screen.getByTestId('table-assets')).toBeInTheDocument(); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/Assets.test.tsx b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/Assets.test.tsx new file mode 100644 index 000000000..0bd9745d5 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/Assets.test.tsx @@ -0,0 +1,611 @@ +/* + * 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 2025 Hedera Hashgraph LLC + * + * 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. + */ + +import { render } from '@/test-utils'; +import { screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { mockAssets, resetAssetMocks } from '@/test-utils/mocks/AssetMocks'; +import { AssetService } from '@/services/AssetService'; +import { useGetAssets } from '../../hooks/queries/AssetQueries'; +import { Assets } from '../Assets'; + +jest.mock('@/services/AssetService', () => ({ + AssetService: { + getAssets: jest.fn(), + getAsset: jest.fn(), + pauseAsset: jest.fn(), + unpauseAsset: jest.fn(), + }, + AssetType: { + EQUITY: 'EQUITY', + BOND: 'BOND', + }, +})); + +jest.mock('../../hooks/queries/AssetQueries', () => ({ + useGetAssets: jest.fn(), + useGetAsset: jest.fn(), + usePauseAsset: jest.fn(), + useUnpauseAsset: jest.fn(), +})); + +jest.mock('@/router/RouterManager', () => ({ + RouterManager: { + to: jest.fn(), + }, +})); + +describe('Assets Component', () => { + let user: ReturnType; + const assetService = AssetService as jest.Mocked; + const mockUseGetAssets = useGetAssets as jest.MockedFunction< + typeof useGetAssets + >; + + beforeEach(() => { + user = userEvent.setup(); + resetAssetMocks(); + assetService.getAssets.mockClear(); + assetService.getAsset.mockClear(); + assetService.pauseAsset.mockClear(); + assetService.unpauseAsset.mockClear(); + + const mockPaginatedAssets = { + queryData: mockAssets, + page: { + totalElements: mockAssets.length, + totalPages: 1, + pageIndex: 0, + pageSize: 10, + }, + }; + + assetService.getAssets.mockResolvedValue(mockPaginatedAssets); + + mockUseGetAssets.mockReturnValue({ + data: mockPaginatedAssets, + isLoading: false, + error: null, + isError: false, + refetch: jest.fn(), + } as any); + }); + + describe('Basic rendering', () => { + test('should render correctly', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + + test('should display assets title', () => { + render(); + expect(screen.getAllByText('Import Asset')[0]).toBeInTheDocument(); + }); + + test('should show filter and search controls', async () => { + render(); + await waitFor(() => { + expect(screen.getByRole('combobox')).toBeInTheDocument(); + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + }); + + test('should display table with data', async () => { + render(); + await waitFor(() => { + expect(screen.getByRole('table')).toBeInTheDocument(); + expect(screen.getAllByRole('row').length).toBeGreaterThan(0); + }); + }); + + test('should show import asset button', async () => { + render(); + await waitFor(() => { + expect( + screen.getByRole('button', { name: /import/i }), + ).toBeInTheDocument(); + }); + }); + }); + + describe('Asset type filtering', () => { + test('should filter by Bond type', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('combobox')).toBeInTheDocument(); + }); + + const selector = screen.getByRole('combobox'); + await user.click(selector); + + const bondOptions = await screen.findAllByText('filters.options.bond'); + await user.click(bondOptions[0]); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBeGreaterThanOrEqual(1); + }); + }); + + test('should filter by Equity type', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('combobox')).toBeInTheDocument(); + }); + + const selector = screen.getByRole('combobox'); + await user.click(selector); + + const equityOptions = await screen.findAllByText( + 'filters.options.equity', + ); + await user.click(equityOptions[0]); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBeGreaterThanOrEqual(1); + }); + }); + + test('should show all assets when selecting all types', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('combobox')).toBeInTheDocument(); + }); + + const selector = screen.getByRole('combobox'); + await user.click(selector); + + const allOptions = await screen.findAllByText('filters.options.allTypes'); + await user.click(allOptions[0]); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBeGreaterThanOrEqual(1); + }); + }); + }); + + describe('Search functionality', () => { + test('should filter assets by name', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + + const searchInput = screen.getByRole('textbox'); + await user.type(searchInput, 'Hedera'); + + expect(searchInput).toHaveValue('Hedera'); + }); + + test('should filter assets by asset ID', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + + const searchInput = screen.getByRole('textbox'); + await user.type(searchInput, '0.0.123456'); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBeGreaterThan(0); + }); + }); + + test('should filter assets by lifecycle cash flow ID', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + + const searchInput = screen.getByRole('textbox'); + await user.type(searchInput, '0.0.789012'); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBeGreaterThan(0); + }); + }); + + test('should show no results for non-existent search', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + + const searchInput = screen.getByRole('textbox'); + await user.type(searchInput, 'NonExistentAsset123'); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBe(1); + }); + }); + + test('should clear search results when input is cleared', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + + const searchInput = screen.getByRole('textbox'); + + await user.type(searchInput, 'Hedera'); + await waitFor(() => { + const filteredRows = screen.getAllByRole('row'); + expect(filteredRows.length).toBeGreaterThan(0); + }); + + await user.clear(searchInput); + + await waitFor(() => { + const allRows = screen.getAllByRole('row'); + expect(allRows.length).toBeGreaterThan(1); + }); + }); + }); + + describe('Table interactions', () => { + test('should handle row clicks', async () => { + const { RouterManager } = require('@/router/RouterManager'); + const routerSpy = jest.spyOn(RouterManager, 'to'); + + render(); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBeGreaterThan(1); + }); + + const rows = screen.getAllByRole('row'); + if (rows.length > 1) { + await user.click(rows[1]); + expect(routerSpy).toHaveBeenCalledWith('ASSET_DETAIL', { + params: { id: expect.any(String) }, + }); + } + + routerSpy.mockRestore(); + }); + + test('should display asset status tags', async () => { + render(); + + await waitFor(() => { + const activeElements = screen.getAllByText('Active'); + expect(activeElements.length).toBeGreaterThan(0); + expect(activeElements[0]).toBeInTheDocument(); + }); + }); + + test('should display asset links', async () => { + render(); + + await waitFor(() => { + const links = screen.getAllByRole('link'); + expect(links.length).toBeGreaterThan(0); + + links.forEach((link) => { + expect(link).toHaveAttribute('href'); + expect(link).toHaveAttribute('target', '_blank'); + }); + }); + }); + }); + + describe('Combined filtering', () => { + test('should apply asset type and search filters simultaneously', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('combobox')).toBeInTheDocument(); + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + + const selector = screen.getByRole('combobox'); + await user.click(selector); + + const bondOptions = await screen.findAllByText('filters.options.bond'); + await user.click(bondOptions[0]); + + const searchInput = screen.getByRole('textbox'); + await user.type(searchInput, 'Hedera'); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBeGreaterThan(0); + }); + }); + }); + + describe('Pagination', () => { + test('should limit displayed rows per page', async () => { + render(); + + await waitFor(() => { + const rows = screen.getAllByRole('row'); + expect(rows.length).toBeLessThanOrEqual(11); + }); + }); + }); + + describe('Button interactions', () => { + test('should handle import asset button click', async () => { + const { RouterManager } = require('@/router/RouterManager'); + const routerSpy = jest.spyOn(RouterManager, 'to'); + + render(); + + await waitFor(() => { + expect( + screen.getByRole('button', { name: /import/i }), + ).toBeInTheDocument(); + }); + + const addButton = screen.getByRole('button', { name: /import/i }); + await user.click(addButton); + + expect(routerSpy).toHaveBeenCalledWith('IMPORT_ASSET'); + routerSpy.mockRestore(); + }); + }); + + describe('Edge cases', () => { + test('should handle special characters in search', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + + const searchInput = screen.getByRole('textbox'); + await user.type(searchInput, '@#$%'); + + expect(searchInput).toHaveValue('@#$%'); + }); + + test('should handle very long search terms', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('textbox')).toBeInTheDocument(); + }); + + const searchInput = screen.getByRole('textbox'); + const longSearch = 'a'.repeat(100); + await user.type(searchInput, longSearch); + + expect(searchInput).toHaveValue(longSearch); + }); + + test('should maintain filter state during interactions', async () => { + render(); + + await waitFor(() => { + expect(screen.getByRole('textbox')).toBeInTheDocument(); + expect(screen.getByRole('combobox')).toBeInTheDocument(); + }); + + const searchInput = screen.getByRole('textbox'); + await user.type(searchInput, 'Hedera'); + + expect(searchInput).toHaveValue('Hedera'); + + const selector = screen.getByRole('combobox'); + await user.click(selector); + + expect(searchInput).toHaveValue('Hedera'); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/__snapshots__/AssetHeader.test.tsx.snap b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/__snapshots__/AssetHeader.test.tsx.snap new file mode 100644 index 000000000..746852397 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/__snapshots__/AssetHeader.test.tsx.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AssetHeader Basic Rendering should render correctly 1`] = ` + +
+

+ Import Asset +

+
+ +
+
+
+`; diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/__snapshots__/AssetTable.test.tsx.snap b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/__snapshots__/AssetTable.test.tsx.snap new file mode 100644 index 000000000..0db98ad4a --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/__snapshots__/AssetTable.test.tsx.snap @@ -0,0 +1,237 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AssetTable Basic Rendering should match snapshot 1`] = ` + +
+

+ Import Asset +

+
+
+
+
+ + + + + + + + + + + + + + + + + +
+
+
+ Name +
+
+
+
+
+ Type +
+
+
+
+
+ Status +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ + +

+ Page 1/1 +

+ + +
+

+ 2 records found +

+
+ + + +