diff --git a/.github/workflows/mp.test.yml b/.github/workflows/mp.test.yml index 97c0cb3f4..751be7f20 100644 --- a/.github/workflows/mp.test.yml +++ b/.github/workflows/mp.test.yml @@ -64,8 +64,8 @@ jobs: - name: Install dependencies run: npm ci - # - name: Build mass-payout - # run: npm run mp:build + - name: Build mass-payout + run: npm run mass-payout:build - # - name: Test mass-payout - # run: npm run mp:test + - name: Test mass-payout + run: npm run mass-payout:test diff --git a/README.md b/README.md index 54a3f33ff..9a20b3eee 100644 --- a/README.md +++ b/README.md @@ -6,337 +6,208 @@ -### 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 + +![Architecture Overview](./docs/images/architecture.png) + +```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 all code using centralized configuration -npm run format # Format all code using centralized Prettier config +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.6797832` -- **`REACT_APP_RPC_FACTORY`**: The Hedera testnet account ID for the factory. Example: `0.0.6797955` +## 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.6797832' - REACT_APP_RPC_FACTORY='0.0.6797955' - - 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 +219,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/package.json b/apps/ats/web/package.json index ec958444d..e96498733 100644 --- a/apps/ats/web/package.json +++ b/apps/ats/web/package.json @@ -49,7 +49,7 @@ "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", @@ -64,22 +64,18 @@ "@hashgraph/asset-tokenization-sdk": "file:../../../packages/ats/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/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/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..c4f99d5e3 --- /dev/null +++ b/apps/mass-payout/backend/package.json @@ -0,0 +1,87 @@ +{ + "name": "@mass-payout/backend", + "version": "1.9.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..d0cce5fdd --- /dev/null +++ b/apps/mass-payout/backend/test/integration/adapters/repositories/typeorm-holder.repository.spec.ts @@ -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 { 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) + expect(savedHolders).toContainEqual(holder1) + expect(savedHolders).toContainEqual(holder2) + }) + + 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/.gitignore b/apps/mass-payout/frontend/.gitignore new file mode 100644 index 000000000..c1e66e955 --- /dev/null +++ b/apps/mass-payout/frontend/.gitignore @@ -0,0 +1,27 @@ +# 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/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..7f8d804e3 --- /dev/null +++ b/apps/mass-payout/frontend/package.json @@ -0,0 +1,78 @@ +{ + "name": "@mass-payout/frontend", + "version": "0.1.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/apps/mass-payout/frontend/src/components/History.tsx b/apps/mass-payout/frontend/src/components/History.tsx new file mode 100644 index 000000000..404fe3846 --- /dev/null +++ b/apps/mass-payout/frontend/src/components/History.tsx @@ -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 [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 { 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/apps/mass-payout/frontend/src/components/__tests__/History.test.tsx b/apps/mass-payout/frontend/src/components/__tests__/History.test.tsx new file mode 100644 index 000000000..93ebe0665 --- /dev/null +++ b/apps/mass-payout/frontend/src/components/__tests__/History.test.tsx @@ -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 [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 { 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/apps/mass-payout/frontend/src/hooks/useBreadcrumbs.tsx b/apps/mass-payout/frontend/src/hooks/useBreadcrumbs.tsx new file mode 100644 index 000000000..7894a3038 --- /dev/null +++ b/apps/mass-payout/frontend/src/hooks/useBreadcrumbs.tsx @@ -0,0 +1,283 @@ +/* + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the 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 { 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; + } + + 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/apps/mass-payout/frontend/src/store/locationStore.tsx b/apps/mass-payout/frontend/src/store/locationStore.tsx new file mode 100644 index 000000000..43897d6cf --- /dev/null +++ b/apps/mass-payout/frontend/src/store/locationStore.tsx @@ -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 { 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'; +} + +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/apps/mass-payout/frontend/src/theme/components/Logo.ts b/apps/mass-payout/frontend/src/theme/components/Logo.ts new file mode 100644 index 000000000..0021ee62d --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Logo.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 [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 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/apps/mass-payout/frontend/src/theme/components/Sidebar.ts b/apps/mass-payout/frontend/src/theme/components/Sidebar.ts new file mode 100644 index 000000000..6b436558a --- /dev/null +++ b/apps/mass-payout/frontend/src/theme/components/Sidebar.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 [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 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/__tests__/__snapshots__/Assets.test.tsx.snap b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/__snapshots__/Assets.test.tsx.snap new file mode 100644 index 000000000..5ea66c2d6 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/__tests__/__snapshots__/Assets.test.tsx.snap @@ -0,0 +1,879 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Assets Component Basic rendering should render correctly 1`] = ` + +
+

+ Import Asset +

+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+

+ Import Asset +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ table.headers.name +
+
+
+
+
+ table.headers.symbol +
+
+
+
+
+

+ table.headers.assetType +

+
+
+
+
+
+

+ table.headers.hederaAdress +

+
+
+
+
+
+

+ table.headers.evmTokenAddress +

+
+
+
+
+
+

+ table.headers.distributionsHedera +

+
+
+
+
+
+

+ table.headers.distributionsEVM +

+
+
+
+
+
+ table.headers.status +
+
+
+
+ Test Asset +
+
+
+ TEST +
+
+
+ EQUITY +
+
+
+
+ + 0.0.123456 + + +
+
+
+
+ +
+
+
+
+ + 0.0.654321 + + +
+
+
+
+ +
+
+
+ +
+
+
+ Bond Asset +
+
+
+ BOND +
+
+
+ BOND +
+
+
+
+ + 0.0.789012 + + +
+
+
+
+ +
+
+
+
+ + 0.0.210987 + + +
+
+
+
+ +
+
+
+ +
+
+
+
+
+ + +

+ Page 1/1 +

+ + +
+

+ 2 records found +

+
+
+
+
+
+`; diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetFilters.tsx b/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetFilters.tsx new file mode 100644 index 000000000..340f64c57 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetFilters.tsx @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024 IOB - Todos los derechos reservados. + * Este archivo es parte del software propietario de IOB. + * Queda prohibida su distribución, copia o uso no autorizado. + */ + +import { Box, Stack } from '@chakra-ui/react'; +import { SearchInputController, SelectController } from 'io-bricks-ui'; +import { useTranslation } from 'react-i18next'; +import { Control } from 'react-hook-form'; +import { PlaceholderWithIcon } from '../../Components/PlaceholderWithIcon'; + +interface AssetFiltersFormValues { + assetType: string; + search: string; +} + +interface AssetFiltersProps { + control: Control; + assetTypeOptions: { value: string; label: string }[]; +} + +export const AssetFilters = ({ + control, + assetTypeOptions, +}: AssetFiltersProps) => { + const { t } = useTranslation('assets'); + + return ( + + + } + options={assetTypeOptions} + isSearchable={false} + /> + + + {}} + /> + + + ); +}; diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetHeader.tsx b/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetHeader.tsx new file mode 100644 index 000000000..167229b8b --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetHeader.tsx @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 IOB - Todos los derechos reservados. + * Este archivo es parte del software propietario de IOB. + * Queda prohibida su distribución, copia o uso no autorizado. + */ + +import { Stack } from '@chakra-ui/react'; +import { Button, Text, Tooltip } from 'io-bricks-ui'; +import { useTranslation } from 'react-i18next'; +import { RouteName } from '@/router/RouteName'; +import { RouterManager } from '@/router/RouterManager'; + +export const AssetHeader = () => { + const { t } = useTranslation('assets'); + + const handleNewAsset = () => { + RouterManager.to(RouteName.ImportAsset); + }; + + return ( + + + {t('title')} + + + + + + ); +}; diff --git a/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetTable.tsx b/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetTable.tsx new file mode 100644 index 000000000..9af36d7ac --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Assets/components/AssetTable.tsx @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 IOB - Todos los derechos reservados. + * Este archivo es parte del software propietario de IOB. + * Queda prohibida su distribución, copia o uso no autorizado. + */ + +import { Box, Text } from '@chakra-ui/react'; +import { Table } from 'io-bricks-ui'; +import { useTranslation } from 'react-i18next'; +import { ColumnDef } from '@tanstack/react-table'; +import { UseTableReturn } from '@/hooks/useTable'; +import { RouteName } from '@/router/RouteName'; +import { RouterManager } from '@/router/RouterManager'; +import type { Asset } from '@/services/AssetService'; + +interface AssetTableProps { + isLoading: boolean; + columns: ColumnDef[]; + filteredAssets: Asset[]; + totalPages: number; + table: UseTableReturn; +} + +export const AssetTable = ({ + isLoading, + columns, + filteredAssets, + totalPages, + table, +}: AssetTableProps) => { + const { t } = useTranslation('assets'); + + const onClickRow = (asset: Asset) => { + RouterManager.to(RouteName.AssetDetail, { + params: { id: asset.id }, + }); + }; + + return ( + + + {t('title')} + + + + + + + ); +}; diff --git a/apps/mass-payout/frontend/src/views/Assets/Components/PlaceholderWithIcon.tsx b/apps/mass-payout/frontend/src/views/Assets/Components/PlaceholderWithIcon.tsx new file mode 100644 index 000000000..d9f146907 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Components/PlaceholderWithIcon.tsx @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2024 IOB - Todos los derechos reservados. + * Este archivo es parte del software propietario de IOB. + * Queda prohibida su distribución, copia o uso no autorizado. + */ + +import { HStack } from '@chakra-ui/react'; +import { PhosphorIcon, Weight, Text } from 'io-bricks-ui'; +import { CalendarBlank } from '@phosphor-icons/react'; +import { useTranslation } from 'react-i18next'; + +export const PlaceholderWithIcon = () => { + const { t } = useTranslation('assets'); + + return ( + + + {t('filters.selectByType')} + + ); +}; diff --git a/apps/mass-payout/frontend/src/views/Assets/Components/PreviousStepButton.tsx b/apps/mass-payout/frontend/src/views/Assets/Components/PreviousStepButton.tsx new file mode 100644 index 000000000..f91b98a2e --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Components/PreviousStepButton.tsx @@ -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 { Button, useStepContext } from 'io-bricks-ui'; +import type { ButtonProps } from 'io-bricks-ui'; +import { useTranslation } from 'react-i18next'; + +export const PreviousStepButton = (props: ButtonProps) => { + const { t } = useTranslation('importAsset', { keyPrefix: 'buttons' }); + + const { goToPrevious } = useStepContext(); + + return ( + + ); +}; diff --git a/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/PlaceholderWithIcon.test.tsx b/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/PlaceholderWithIcon.test.tsx new file mode 100644 index 000000000..8e56d347b --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/PlaceholderWithIcon.test.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 { render } from '../../../../test-utils'; +import { PlaceholderWithIcon } from '../PlaceholderWithIcon'; + +describe('PlaceholderWithIcon', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Rendering', () => { + it('should render correctly', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/PreviousStepButton.test.tsx b/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/PreviousStepButton.test.tsx new file mode 100644 index 000000000..c6d8cca0f --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/PreviousStepButton.test.tsx @@ -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 { screen } from '@testing-library/react'; +import { render } from '../../../../test-utils'; +import userEvent from '@testing-library/user-event'; +import { PreviousStepButton } from '../PreviousStepButton'; + +const mockGoToPrevious = jest.fn(); + +jest.mock('io-bricks-ui', () => ({ + Button: jest.fn(({ children, onClick, ...props }) => ( + + )), + useStepContext: () => ({ + goToPrevious: mockGoToPrevious, + }), +})); + +describe('PreviousStepButton', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Basic Rendering', () => { + it('should render correctly', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + }); + + describe('Interactions', () => { + it('should call goToPrevious when clicked', async () => { + const user = userEvent.setup(); + render(); + + const button = screen.getByRole('button'); + await user.click(button); + + expect(mockGoToPrevious).toHaveBeenCalledTimes(1); + }); + + it('should handle multiple clicks', async () => { + const user = userEvent.setup(); + render(); + + const button = screen.getByRole('button'); + await user.click(button); + await user.click(button); + await user.click(button); + + expect(mockGoToPrevious).toHaveBeenCalledTimes(3); + }); + + it('should not call goToPrevious when disabled', async () => { + const user = userEvent.setup(); + render(); + + const button = screen.getByRole('button'); + await user.click(button); + + expect(mockGoToPrevious).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/__snapshots__/PlaceholderWithIcon.test.tsx.snap b/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/__snapshots__/PlaceholderWithIcon.test.tsx.snap new file mode 100644 index 000000000..aa3f6f8e7 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/__snapshots__/PlaceholderWithIcon.test.tsx.snap @@ -0,0 +1,32 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PlaceholderWithIcon Rendering should render correctly 1`] = ` + +
+ + + +

+ filters.selectByType +

+
+
+`; diff --git a/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/__snapshots__/PreviousStepButton.test.tsx.snap b/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/__snapshots__/PreviousStepButton.test.tsx.snap new file mode 100644 index 000000000..52404f961 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/Components/__tests__/__snapshots__/PreviousStepButton.test.tsx.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PreviousStepButton Basic Rendering should render correctly 1`] = ` + + + +`; diff --git a/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/DistributionsDetails.tsx b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/DistributionsDetails.tsx new file mode 100644 index 000000000..82cbf6652 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/DistributionsDetails.tsx @@ -0,0 +1,322 @@ +/* + * Apache License + * Version 2.0, January 2004 + * http://www.apache.org/licenses/ + * + * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + * + * 1. Definitions. + * + * "License" shall mean the terms and conditions for use, reproduction, + * and distribution as defined by Sections 1 through 9 of this document. + * + * "Licensor" shall mean the copyright owner or entity authorized by + * the copyright owner that is granting the License. + * + * "Legal Entity" shall mean the union of the acting entity and all + * other entities that control, are controlled by, or are under common + * control with that entity. For the purposes of this definition, + * "control" means (i) the power, direct or indirect, to cause the + * direction or management of such entity, whether by contract or + * otherwise, or (ii) ownership of fifty percent (50%) or more of the + * outstanding shares, or (iii) beneficial ownership of such entity. + * + * "You" (or "Your") shall mean an individual or Legal Entity + * exercising permissions granted by this License. + * + * "Source" form shall mean the preferred form for making modifications, + * including but not limited to software source code, documentation + * source, and configuration files. + * + * "Object" form shall mean any form resulting from mechanical + * transformation or translation of a Source form, including but + * not limited to compiled object code, generated documentation, + * and conversions to other media types. + * + * "Work" shall mean the work of authorship, whether in Source or + * Object form, made available under the License, as indicated by a + * copyright notice that is included in or attached to the work + * (an example is provided in the Appendix below). + * + * "Derivative Works" shall mean any work, whether in Source or Object + * form, that is based on (or derived from) the Work and for which the + * editorial revisions, annotations, elaborations, or other modifications + * represent, as a whole, an original work of authorship. For the purposes + * of this License, Derivative Works shall not include works that remain + * separable from, or merely link (or bind by name) to the interfaces of, + * the Work and Derivative Works thereof. + * + * "Contribution" shall mean any work of authorship, including + * the original version of the Work and any modifications or additions + * to that Work or Derivative Works thereof, that is intentionally + * submitted to Licensor for inclusion in the Work by the copyright owner + * or by an individual or Legal Entity authorized to submit on behalf of + * the copyright owner. For the purposes of this definition, "submitted" + * means any form of electronic, verbal, or written communication sent + * to the Licensor or its representatives, including but not limited to + * communication on electronic mailing lists, source code control systems, + * and issue tracking systems that are managed by, or on behalf of, the + * Licensor for the purpose of discussing and improving the Work, but + * excluding communication that is conspicuously marked or otherwise + * designated in writing by the copyright owner as "Not a Contribution." + * + * "Contributor" shall mean Licensor and any individual or Legal Entity + * on behalf of whom a Contribution has been received by Licensor and + * subsequently incorporated within the Work. + * + * 2. Grant of Copyright License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * copyright license to reproduce, prepare Derivative Works of, + * publicly display, publicly perform, sublicense, and distribute the + * Work and such Derivative Works in Source or Object form. + * + * 3. Grant of Patent License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * (except as stated in this section) patent license to make, have made, + * use, offer to sell, sell, import, and otherwise transfer the Work, + * where such license applies only to those patent claims licensable + * by such Contributor that are necessarily infringed by their + * Contribution(s) alone or by combination of their Contribution(s) + * with the Work to which such Contribution(s) was submitted. If You + * institute patent litigation against any entity (including a + * cross-claim or counterclaim in a lawsuit) alleging that the Work + * or a Contribution incorporated within the Work constitutes direct + * or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate + * as of the date such litigation is filed. + * + * 4. Redistribution. You may reproduce and distribute copies of the + * Work or Derivative Works thereof in any medium, with or without + * modifications, and in Source or Object form, provided that You + * meet the following conditions: + * + * (a) You must give any other recipients of the Work or + * Derivative Works a copy of this License; and + * + * (b) You must cause any modified files to carry prominent notices + * stating that You changed the files; and + * + * (c) You must retain, in the Source form of any Derivative Works + * that You distribute, all copyright, patent, trademark, and + * attribution notices from the Source form of the Work, + * excluding those notices that do not pertain to any part of + * the Derivative Works; and + * + * (d) If the Work includes a "NOTICE" text file as part of its + * distribution, then any Derivative Works that You distribute must + * include a readable copy of the attribution notices contained + * within such NOTICE file, excluding those notices that do not + * pertain to any part of the Derivative Works, in at least one + * of the following places: within a NOTICE text file distributed + * as part of the Derivative Works; within the Source form or + * documentation, if provided along with the Derivative Works; or, + * within a display generated by the Derivative Works, if and + * wherever such third-party notices normally appear. The contents + * of the NOTICE file are for informational purposes only and + * do not modify the License. You may add Your own attribution + * notices within Derivative Works that You distribute, alongside + * or as an addendum to the 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 { useMemo } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { Holder } from '@/services/DistributionService'; +import { DistributionsDetailsStatus } from '@/types/status'; +import { format } from 'date-fns'; +import { + DistributionsDetailsData, + useDistributionsDetailsColumns, +} from '../hooks/useDistributionsDetailsColumns'; +import { formatNumber } from '@/utils/number-fs'; +import { useTable } from '@/hooks/useTable'; +import { useTranslation } from 'react-i18next'; +import { + useGetDistribution, + useGetDistributionHolders, + useRetryDistribution, +} from '../hooks/queries/DistributionQueries'; +import { DistributionHeader } from './components/DistributionHeader'; +import { DistributionTable } from './components/DistributionTable'; + +const mapHolderToDetailsData = (holder: Holder): DistributionsDetailsData => { + const statusMap: Record = { + PENDING: DistributionsDetailsStatus.PENDING, + RETRYING: DistributionsDetailsStatus.RETRYING, + SUCCESS: DistributionsDetailsStatus.SUCCESS, + FAILED: DistributionsDetailsStatus.FAILED, + }; + return { + paymentId: holder.batchPayout.id, + receieverAddressHedera: holder.holderHederaAddress, + receieverAddressEvm: holder.holderEvmAddress, + amount: holder.amount ? `$ ${formatNumber(holder.amount)}` : '-', + executionDate: format(new Date(holder.updatedAt || 0), 'dd/MM/yyyy'), + txHash: holder.batchPayout.hederaTransactionId, + status: statusMap[holder.status] || DistributionsDetailsStatus.PENDING, + }; +}; + +export const DistributionsDetails = () => { + const navigate = useNavigate(); + const { itemId: distributionId, id: assetId } = useParams<{ + type: string; + itemId: string; + id: string; + }>(); + + const table = useTable(); + const columns = useDistributionsDetailsColumns(); + const { t } = useTranslation('distributionsDetails'); + + const { data: distribution } = useGetDistribution(distributionId || ''); + + const breadcrumbItems = [ + { label: 'Asset list', link: '/assets' }, + { label: 'Assets details', link: `/assets/${assetId}` }, + { + label: 'Distribution details', + link: '#', + }, + ]; + + const { data: holdersData } = useGetDistributionHolders({ + distributionId: distributionId || '', + page: table.pagination.pageIndex, + size: table.pagination.pageSize, + }); + + const distributionDetails = useMemo(() => { + if (!holdersData?.queryData) return []; + return holdersData.queryData.map(mapHolderToDetailsData); + }, [holdersData]); + + const handleGoBack = () => { + navigate(-1); + }; + + const retryDistributionMutation = useRetryDistribution(); + + const retryAll = () => { + if (!distributionId) { + console.error('Distribution ID not available'); + return; + } + + retryDistributionMutation.mutate(distributionId, { + onSuccess: () => { + console.log('Retry all successful'); + }, + onError: (error) => { + console.error('Error retrying distribution:', error); + }, + }); + }; + + return ( + <> + + + + ); +}; + +export default DistributionsDetails; diff --git a/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionHeader.test.tsx b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionHeader.test.tsx new file mode 100644 index 000000000..26ee38558 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionHeader.test.tsx @@ -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 { screen, fireEvent } from '@testing-library/react'; +import { DistributionHeader } from '../components/DistributionHeader'; +import { ProcessStatus } from '@/types/status'; +import { render } from '@/test-utils'; + +describe('DistributionHeader', () => { + const mockT = jest.fn((key: string) => { + const translations: Record = { + failedMessage: 'This distribution has failed', + retryButton: 'Retry all', + }; + return translations[key] || key; + }); + + const mockOnGoBack = jest.fn(); + const mockOnRetryAll = jest.fn(); + + const defaultProps = { + breadcrumbItems: [ + { label: 'Assets', link: '/assets' }, + { label: 'Distribution Details', link: '/distributions/123' }, + ], + title: 'Distribution #123', + onGoBack: mockOnGoBack, + onRetryAll: mockOnRetryAll, + t: mockT, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Basic Rendering', () => { + test('should render correctly', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + + test('should render breadcrumb with correct items', () => { + render(); + + const breadcrumb = screen.getByTestId('breadcrumb-desktop'); + expect(breadcrumb).toBeInTheDocument(); + + expect(screen.getByText('Assets')).toBeInTheDocument(); + expect(screen.getByText('Distribution Details')).toBeInTheDocument(); + }); + }); + + describe('Distribution Status', () => { + test('should render completed status tag', () => { + const propsWithCompletedStatus = { + ...defaultProps, + distribution: { status: 'COMPLETED' }, + }; + + render(); + + // Check that the status tag is rendered with the correct text + expect(screen.getByText(ProcessStatus.COMPLETED)).toBeInTheDocument(); + }); + + test('should render failed status tag', () => { + const propsWithFailedStatus = { + ...defaultProps, + distribution: { status: 'FAILED' }, + }; + + render(); + + // Check that the status tag is rendered with the correct text + expect(screen.getByText(ProcessStatus.FAILED)).toBeInTheDocument(); + }); + + test('should not render status tag when no distribution provided', () => { + render(); + + // Check that no status tag is rendered + expect( + screen.queryByText(ProcessStatus.COMPLETED), + ).not.toBeInTheDocument(); + expect(screen.queryByText(ProcessStatus.FAILED)).not.toBeInTheDocument(); + }); + }); + + describe('Interactions', () => { + test('should call onGoBack when go back button is clicked', () => { + render(); + + const gobackButton = screen.getByTestId('go-back-button-button'); + fireEvent.click(gobackButton); + + expect(mockOnGoBack).toHaveBeenCalledTimes(1); + }); + + test('should call onRetryAll when retry button is clicked', () => { + const propsWithFailedStatus = { + ...defaultProps, + distribution: { status: 'FAILED' }, + }; + + render(); + + const retryButton = screen.getByText('Retry all'); + fireEvent.click(retryButton); + + expect(mockOnRetryAll).toHaveBeenCalledTimes(1); + }); + + test('should not render retry button when distribution is not failed', () => { + const propsWithCompletedStatus = { + ...defaultProps, + distribution: { status: 'COMPLETED' }, + }; + + render(); + + expect(screen.queryByText('Retry all')).not.toBeInTheDocument(); + }); + + test('should not render retry button when no distribution provided', () => { + render(); + + expect(screen.queryByText('Retry all')).not.toBeInTheDocument(); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionTable.test.tsx b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionTable.test.tsx new file mode 100644 index 000000000..b24e85e6d --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionTable.test.tsx @@ -0,0 +1,364 @@ +/* + * Apache License + * Version 2.0, January 2004 + * http://www.apache.org/licenses/ + * + * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + * + * 1. Definitions. + * + * "License" shall mean the terms and conditions for use, reproduction, + * and distribution as defined by Sections 1 through 9 of this document. + * + * "Licensor" shall mean the copyright owner or entity authorized by + * the copyright owner that is granting the License. + * + * "Legal Entity" shall mean the union of the acting entity and all + * other entities that control, are controlled by, or are under common + * control with that entity. For the purposes of this definition, + * "control" means (i) the power, direct or indirect, to cause the + * direction or management of such entity, whether by contract or + * otherwise, or (ii) ownership of fifty percent (50%) or more of the + * outstanding shares, or (iii) beneficial ownership of such entity. + * + * "You" (or "Your") shall mean an individual or Legal Entity + * exercising permissions granted by this License. + * + * "Source" form shall mean the preferred form for making modifications, + * including but not limited to software source code, documentation + * source, and configuration files. + * + * "Object" form shall mean any form resulting from mechanical + * transformation or translation of a Source form, including but + * not limited to compiled object code, generated documentation, + * and conversions to other media types. + * + * "Work" shall mean the work of authorship, whether in Source or + * Object form, made available under the License, as indicated by a + * copyright notice that is included in or attached to the work + * (an example is provided in the Appendix below). + * + * "Derivative Works" shall mean any work, whether in Source or Object + * form, that is based on (or derived from) the Work and for which the + * editorial revisions, annotations, elaborations, or other modifications + * represent, as a whole, an original work of authorship. For the purposes + * of this License, Derivative Works shall not include works that remain + * separable from, or merely link (or bind by name) to the interfaces of, + * the Work and Derivative Works thereof. + * + * "Contribution" shall mean any work of authorship, including + * the original version of the Work and any modifications or additions + * to that Work or Derivative Works thereof, that is intentionally + * submitted to Licensor for inclusion in the Work by the copyright owner + * or by an individual or Legal Entity authorized to submit on behalf of + * the copyright owner. For the purposes of this definition, "submitted" + * means any form of electronic, verbal, or written communication sent + * to the Licensor or its representatives, including but not limited to + * communication on electronic mailing lists, source code control systems, + * and issue tracking systems that are managed by, or on behalf of, the + * Licensor for the purpose of discussing and improving the Work, but + * excluding communication that is conspicuously marked or otherwise + * designated in writing by the copyright owner as "Not a Contribution." + * + * "Contributor" shall mean Licensor and any individual or Legal Entity + * on behalf of whom a Contribution has been received by Licensor and + * subsequently incorporated within the Work. + * + * 2. Grant of Copyright License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * copyright license to reproduce, prepare Derivative Works of, + * publicly display, publicly perform, sublicense, and distribute the + * Work and such Derivative Works in Source or Object form. + * + * 3. Grant of Patent License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * (except as stated in this section) patent license to make, have made, + * use, offer to sell, sell, import, and otherwise transfer the Work, + * where such license applies only to those patent claims licensable + * by such Contributor that are necessarily infringed by their + * Contribution(s) alone or by combination of their Contribution(s) + * with the Work to which such Contribution(s) was submitted. If You + * institute patent litigation against any entity (including a + * cross-claim or counterclaim in a lawsuit) alleging that the Work + * or a Contribution incorporated within the Work constitutes direct + * or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate + * as of the date such litigation is filed. + * + * 4. Redistribution. You may reproduce and distribute copies of the + * Work or Derivative Works thereof in any medium, with or without + * modifications, and in Source or Object form, provided that You + * meet the following conditions: + * + * (a) You must give any other recipients of the Work or + * Derivative Works a copy of this License; and + * + * (b) You must cause any modified files to carry prominent notices + * stating that You changed the files; and + * + * (c) You must retain, in the Source form of any Derivative Works + * that You distribute, all copyright, patent, trademark, and + * attribution notices from the Source form of the Work, + * excluding those notices that do not pertain to any part of + * the Derivative Works; and + * + * (d) If the Work includes a "NOTICE" text file as part of its + * distribution, then any Derivative Works that You distribute must + * include a readable copy of the attribution notices contained + * within such NOTICE file, excluding those notices that do not + * pertain to any part of the Derivative Works, in at least one + * of the following places: within a NOTICE text file distributed + * as part of the Derivative Works; within the Source form or + * documentation, if provided along with the Derivative Works; or, + * within a display generated by the Derivative Works, if and + * wherever such third-party notices normally appear. The contents + * of the NOTICE file are for informational purposes only and + * do not modify the License. You may add Your own attribution + * notices within Derivative Works that You distribute, alongside + * or as an addendum to the 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 { DistributionTable } from '../components/DistributionTable'; +import { DistributionsDetailsData } from '../../hooks/useDistributionsDetailsColumns'; +import { UseTableReturn } from '@/hooks/useTable'; +import { DistributionsDetailsStatus } from '@/types/status'; +import { render } from '@/test-utils'; + +const mockColumns = [ + { + id: 'address', + header: 'Address', + accessorKey: 'address', + }, + { + id: 'amount', + header: 'Amount', + accessorKey: 'amount', + }, +]; + +const mockData: DistributionsDetailsData[] = [ + { + paymentId: '1', + receieverAddressHedera: '0.0.123', + receieverAddressEvm: '0x123...abc', + amount: '100.00', + executionDate: '2024-01-15', + txHash: '0xabc123...', + status: DistributionsDetailsStatus.SUCCESS, + }, + { + paymentId: '2', + receieverAddressHedera: '0.0.456', + receieverAddressEvm: '0x456...def', + amount: '200.00', + executionDate: '2024-01-16', + txHash: '0xdef456...', + status: DistributionsDetailsStatus.PENDING, + }, +]; + +const mockTable: UseTableReturn = { + pagination: { + pageIndex: 0, + pageSize: 10, + }, + setPagination: jest.fn(), + sorting: [], + setSorting: jest.fn(), +}; + +describe('DistributionTable', () => { + const defaultProps = { + title: 'Distribution Details', + columns: mockColumns, + data: mockData, + totalElements: 2, + totalPages: 1, + table: mockTable, + }; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('Basic Rendering', () => { + test('should match snapshot', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + }); + + describe('Props Integration', () => { + test('should pass title prop correctly', () => { + const customTitle = 'Custom Distribution Title'; + render(); + + expect(screen.getByText(customTitle)).toBeInTheDocument(); + }); + + test('should pass columns to Table component', () => { + render(); + + const table = screen.getByTestId('table-ca-distributions-details'); + expect(table).toBeInTheDocument(); + }); + + test('should pass data to Table component', () => { + render(); + + const table = screen.getByTestId('table-ca-distributions-details'); + expect(table).toBeInTheDocument(); + expect(screen.getByTestId('row-0')).toBeInTheDocument(); + expect(screen.getByTestId('row-1')).toBeInTheDocument(); + }); + + test('should pass totalElements to Table component', () => { + render(); + + const table = screen.getByTestId('table-ca-distributions-details'); + expect(table).toBeInTheDocument(); + }); + + test('should pass totalPages to Table component', () => { + render(); + + const table = screen.getByTestId('table-ca-distributions-details'); + expect(table).toBeInTheDocument(); + }); + + test('should spread table props to Table component', () => { + const customTable = { + ...mockTable, + pagination: { + pageIndex: 1, + pageSize: 20, + }, + }; + + render(); + + const table = screen.getByTestId('table-ca-distributions-details'); + expect(table).toBeInTheDocument(); + }); + }); + + describe('Data Handling', () => { + test('should handle empty data array', () => { + render(); + + const table = screen.getByTestId('table-ca-distributions-details'); + expect(table).toBeInTheDocument(); + expect(screen.queryByTestId('row-0')).not.toBeInTheDocument(); + }); + + test('should handle large data sets', () => { + const largeData = Array.from({ length: 100 }, (_, index) => ({ + paymentId: `${index + 1}`, + receieverAddressHedera: `0.0.${index}`, + receieverAddressEvm: `0x${index}...abc`, + amount: `${(index + 1) * 10}.00`, + executionDate: '2024-01-15', + txHash: `0xabc${index}...`, + status: DistributionsDetailsStatus.SUCCESS, + })); + + render( + , + ); + + const table = screen.getByTestId('table-ca-distributions-details'); + expect(table).toBeInTheDocument(); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionsDetails.test.tsx b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionsDetails.test.tsx new file mode 100644 index 000000000..57c6dd327 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/DistributionsDetails.test.tsx @@ -0,0 +1,363 @@ +/* + * Apache License + * Version 2.0, January 2004 + * http://www.apache.org/licenses/ + * + * TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + * + * 1. Definitions. + * + * "License" shall mean the terms and conditions for use, reproduction, + * and distribution as defined by Sections 1 through 9 of this document. + * + * "Licensor" shall mean the copyright owner or entity authorized by + * the copyright owner that is granting the License. + * + * "Legal Entity" shall mean the union of the acting entity and all + * other entities that control, are controlled by, or are under common + * control with that entity. For the purposes of this definition, + * "control" means (i) the power, direct or indirect, to cause the + * direction or management of such entity, whether by contract or + * otherwise, or (ii) ownership of fifty percent (50%) or more of the + * outstanding shares, or (iii) beneficial ownership of such entity. + * + * "You" (or "Your") shall mean an individual or Legal Entity + * exercising permissions granted by this License. + * + * "Source" form shall mean the preferred form for making modifications, + * including but not limited to software source code, documentation + * source, and configuration files. + * + * "Object" form shall mean any form resulting from mechanical + * transformation or translation of a Source form, including but + * not limited to compiled object code, generated documentation, + * and conversions to other media types. + * + * "Work" shall mean the work of authorship, whether in Source or + * Object form, made available under the License, as indicated by a + * copyright notice that is included in or attached to the work + * (an example is provided in the Appendix below). + * + * "Derivative Works" shall mean any work, whether in Source or Object + * form, that is based on (or derived from) the Work and for which the + * editorial revisions, annotations, elaborations, or other modifications + * represent, as a whole, an original work of authorship. For the purposes + * of this License, Derivative Works shall not include works that remain + * separable from, or merely link (or bind by name) to the interfaces of, + * the Work and Derivative Works thereof. + * + * "Contribution" shall mean any work of authorship, including + * the original version of the Work and any modifications or additions + * to that Work or Derivative Works thereof, that is intentionally + * submitted to Licensor for inclusion in the Work by the copyright owner + * or by an individual or Legal Entity authorized to submit on behalf of + * the copyright owner. For the purposes of this definition, "submitted" + * means any form of electronic, verbal, or written communication sent + * to the Licensor or its representatives, including but not limited to + * communication on electronic mailing lists, source code control systems, + * and issue tracking systems that are managed by, or on behalf of, the + * Licensor for the purpose of discussing and improving the Work, but + * excluding communication that is conspicuously marked or otherwise + * designated in writing by the copyright owner as "Not a Contribution." + * + * "Contributor" shall mean Licensor and any individual or Legal Entity + * on behalf of whom a Contribution has been received by Licensor and + * subsequently incorporated within the Work. + * + * 2. Grant of Copyright License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * copyright license to reproduce, prepare Derivative Works of, + * publicly display, publicly perform, sublicense, and distribute the + * Work and such Derivative Works in Source or Object form. + * + * 3. Grant of Patent License. Subject to the terms and conditions of + * this License, each Contributor hereby grants to You a perpetual, + * worldwide, non-exclusive, no-charge, royalty-free, irrevocable + * (except as stated in this section) patent license to make, have made, + * use, offer to sell, sell, import, and otherwise transfer the Work, + * where such license applies only to those patent claims licensable + * by such Contributor that are necessarily infringed by their + * Contribution(s) alone or by combination of their Contribution(s) + * with the Work to which such Contribution(s) was submitted. If You + * institute patent litigation against any entity (including a + * cross-claim or counterclaim in a lawsuit) alleging that the Work + * or a Contribution incorporated within the Work constitutes direct + * or contributory patent infringement, then any patent licenses + * granted to You under this License for that Work shall terminate + * as of the date such litigation is filed. + * + * 4. Redistribution. You may reproduce and distribute copies of the + * Work or Derivative Works thereof in any medium, with or without + * modifications, and in Source or Object form, provided that You + * meet the following conditions: + * + * (a) You must give any other recipients of the Work or + * Derivative Works a copy of this License; and + * + * (b) You must cause any modified files to carry prominent notices + * stating that You changed the files; and + * + * (c) You must retain, in the Source form of any Derivative Works + * that You distribute, all copyright, patent, trademark, and + * attribution notices from the Source form of the Work, + * excluding those notices that do not pertain to any part of + * the Derivative Works; and + * + * (d) If the Work includes a "NOTICE" text file as part of its + * distribution, then any Derivative Works that You distribute must + * include a readable copy of the attribution notices contained + * within such NOTICE file, excluding those notices that do not + * pertain to any part of the Derivative Works, in at least one + * of the following places: within a NOTICE text file distributed + * as part of the Derivative Works; within the Source form or + * documentation, if provided along with the Derivative Works; or, + * within a display generated by the Derivative Works, if and + * wherever such third-party notices normally appear. The contents + * of the NOTICE file are for informational purposes only and + * do not modify the License. You may add Your own attribution + * notices within Derivative Works that You distribute, alongside + * or as an addendum to the 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 { DistributionsDetails } from '../DistributionsDetails'; +import * as DistributionQueries from '../../hooks/queries/DistributionQueries'; +import * as useDistributionsDetailsColumns from '../../hooks/useDistributionsDetailsColumns'; +import { useNavigate } from 'react-router-dom'; + +// Mock react-router-dom +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: jest.fn(), + useParams: jest.fn(() => ({ + itemId: 'test-distribution-id', + id: 'test-asset-id', + })), +})); + +// Mock DistributionQueries +const mockUseGetDistribution = jest.spyOn( + DistributionQueries, + 'useGetDistribution', +); +const mockUseGetDistributionHolders = jest.spyOn( + DistributionQueries, + 'useGetDistributionHolders', +); + +// Mock useDistributionsDetailsColumns +const mockUseDistributionsDetailsColumns = jest.spyOn( + useDistributionsDetailsColumns, + 'useDistributionsDetailsColumns', +); + +// Mock navigate function +const mockNavigate = jest.fn(); + +const mockDistribution = { + id: 'test-distribution-id', + name: 'Test Distribution', + status: 'PENDING', + totalAmount: 1000, + executionDate: '2024-01-15T10:00:00Z', +}; + +const mockHoldersData = { + queryData: [ + { + id: 'holder-1', + batchPayout: { + id: 'payment-1', + hederaTransactionId: '0x123456789abcdef', + }, + holderHederaAddress: '0.0.123456', + holderEvmAddress: '0x123456789abcdef', + amount: 100, + status: 'PENDING', + updatedAt: '2024-01-15T10:00:00Z', + }, + { + id: 'holder-2', + batchPayout: { + id: 'payment-2', + hederaTransactionId: '0xabcdef123456789', + }, + holderHederaAddress: '0.0.234567', + holderEvmAddress: '0xabcdef123456789', + amount: 200, + status: 'SUCCESS', + updatedAt: '2024-01-15T10:05:00Z', + }, + ], + page: { + totalPages: 1, + totalElements: 2, + }, +}; + +const mockColumns = [ + { + id: 'paymentId', + header: 'Payment ID', + accessorKey: 'paymentId', + }, + { + id: 'receieverAddressHedera', + header: 'Receiver Address (Hedera)', + accessorKey: 'receieverAddressHedera', + }, + { + id: 'amount', + header: 'Amount', + accessorKey: 'amount', + }, + { + id: 'status', + header: 'Status', + accessorKey: 'status', + }, +]; + +beforeEach(() => { + jest.clearAllMocks(); + (useNavigate as jest.Mock).mockReturnValue(mockNavigate); + + mockUseGetDistribution.mockReturnValue({ + data: mockDistribution, + isLoading: false, + error: null, + isError: false, + } as any); + + mockUseGetDistributionHolders.mockReturnValue({ + data: mockHoldersData, + isLoading: false, + error: null, + isError: false, + } as any); + + mockUseDistributionsDetailsColumns.mockReturnValue(mockColumns); +}); + +describe('DistributionsDetails', () => { + describe('Basic rendering', () => { + it('should render correctly', () => { + const component = render(); + expect(component.asFragment()).toMatchSnapshot(); + }); + + it('should render breadcrumb navigation', async () => { + render(); + + await waitFor(() => { + expect(screen.getByText('Asset list')).toBeInTheDocument(); + expect(screen.getByText('Assets details')).toBeInTheDocument(); + expect(screen.getByText('Distribution details')).toBeInTheDocument(); + }); + }); + }); + + describe('Data fetching', () => { + it('should fetch distribution data with correct parameters', () => { + render(); + + expect(mockUseGetDistribution).toHaveBeenCalledWith( + 'test-distribution-id', + ); + }); + + it('should fetch distribution holders with pagination parameters', () => { + render(); + + expect(mockUseGetDistributionHolders).toHaveBeenCalledWith({ + distributionId: 'test-distribution-id', + page: 0, + size: 8, + }); + }); + }); +}); diff --git a/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/__snapshots__/DistributionHeader.test.tsx.snap b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/__snapshots__/DistributionHeader.test.tsx.snap new file mode 100644 index 000000000..e9f1e9883 --- /dev/null +++ b/apps/mass-payout/frontend/src/views/Assets/DistributionsDetails/__tests__/__snapshots__/DistributionHeader.test.tsx.snap @@ -0,0 +1,105 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DistributionHeader Basic Rendering should render correctly 1`] = ` + +
+ +
+
+
+ +

+ Distribution #123 +

+
+
+
+
+
+
+ + + + + + + + + + + + + + +
+
+
+ Address +
+ +
+
+
+
+ Amount +
+ +
+
+
+
+
+ 100.00 +
+
+
+
+
+ 200.00 +
+
+ +
+
+ + +

+ Page 1/1 +

+ + +
+

+ 2 records found +

+
+ + + +