Skip to content

Application Services

This document describes the main application services in the wallets package, organized by domain area.

Overview

The application layer contains the business logic and orchestrates domain entities to fulfill specific operations. Application services are organized into:

  • Domain-specific services: Simple services focused on a single operation (e.g., WalletBalanceUpdater)
  • Complex application services: Services that orchestrate multiple operations (e.g., WalletAddressBalanceSupervisor)
  • Blockchain-specific services: Services with blockchain-specific logic (UTXO, Tron, Solana)

Wallet Application Services

WalletDepositAddressFinder

Purpose: Finds or creates a deposit address for a specific coin/token on a blockchain.

Key Logic:

  1. Validates wallet exists and deposits are enabled
  2. For tokens, validates token is supported and enabled
  3. Finds highest used address index
  4. Creates new address if under limit (1000), otherwise reuses oldest
  5. Publishes domain event for address creation

Dependencies:

  • HDWalletAddressDerivator - Generates blockchain addresses
  • WalletFinder - Locates wallets
  • WalletTokenFinder - Locates wallet tokens
  • WalletAddressRepository - Persists addresses
  • EventPublisher - Publishes domain events
typescript
async run(coinId: CoinId, blockchain: Blockchain): Promise<WalletAddress | undefined>

WalletBalanceRetriever

Purpose: Retrieves current balance for a wallet from blockchain.

Key Logic:

  1. Finds wallet by blockchain
  2. Queries blockchain adapter for current balance
  3. Returns balance information

WalletBalanceUpdater

Purpose: Updates wallet balance from blockchain and persists changes.

Key Logic:

  1. Retrieves current balance from blockchain
  2. Updates wallet entity
  3. Persists changes to repository

WalletBalanceScanner

Purpose: Scans entire wallet for balance updates across all addresses.

Key Logic:

  1. Finds all addresses for wallet
  2. Updates balance for each address
  3. Consolidates total wallet balance

WalletWithdrawer

Purpose: Initiates withdrawal transaction from wallet.

Key Logic:

  1. Validates withdrawal is allowed
  2. Checks sufficient balance
  3. Creates withdrawal transaction
  4. Queues transaction for processing

WalletFinder

Purpose: Locates wallet by blockchain.

typescript
async run(blockchain: Blockchain): Promise<Wallet | undefined>

WalletTokenFinder

Purpose: Locates specific token within a wallet.

typescript
async run(walletId: WalletId, tokenId: TokenId): Promise<WalletToken | undefined>

Address Application Services

WalletAddressFundsDetector

Purpose: Detects when funds arrive at a wallet address.

Key Logic:

  1. Queries blockchain for address transactions
  2. Identifies new deposits
  3. Updates address balance
  4. Triggers sweep if needed

WalletAddressSweeper

Purpose: Sweeps funds from deposit addresses to main wallet.

Key Logic:

  1. Validates address has sufficient funds
  2. Calculates optimal sweep amount (considering fees)
  3. Creates sweep transaction
  4. Queues transaction for processing

Flow Diagram:

WalletTokenAddressFundsChecker

Purpose: Checks if token address has sufficient native funds for operations.

Key Logic:

  1. Checks native token balance (for gas/fees)
  2. Compares against minimum required
  3. Returns funding status

WalletTokenAddressNativeFundsSender

Purpose: Sends native funds to token addresses for gas/fees.

Key Logic:

  1. Calculates required native funds
  2. Creates funding transaction
  3. Sends from main wallet to token address

WalletAddressBalanceUpdater

Purpose: Updates balance for a specific address.

WalletAddressUnlocker

Purpose: Unlocks a deposit address for reuse.

Key Logic:

  1. Marks address as available
  2. Resets usage timestamps
  3. Persists changes

Transaction Application Services

TransactionSender

Purpose: Sends pending transactions to blockchain.

Key Logic:

  1. Validates transaction is ready to send
  2. Signs transaction with wallet keys
  3. Broadcasts to blockchain
  4. Updates transaction status

TransactionUpdater

Purpose: Updates transaction status from blockchain.

Key Logic:

  1. Queries blockchain for transaction status
  2. Updates local transaction record
  3. Triggers balance updates if confirmed

TransactionCanceller

Purpose: Cancels pending transactions.

Key Logic:

  1. Validates transaction can be cancelled
  2. Updates status to cancelled
  3. Releases any locked funds

TransactionRetriever

Purpose: Retrieves transaction information.

Blockchain-Specific Application Services

Tron Application Services

TronWalletAddressActivator

Activates Tron addresses by sending initial TRX.

TronWalletAddressDelegator

Delegates Tron energy/bandwidth resources.

TronWalletAddressUnDelegator

Undelegates Tron resources.

UTXO Application Services

UTXOTransactionCPFP

Implements Child-Pays-For-Parent for Bitcoin transactions.

Key Logic:

  1. Creates child transaction with higher fee
  2. References parent transaction
  3. Incentivizes miners to confirm both

Complex Application Services

WalletAddressBalanceSupervisor

Purpose: Orchestrates balance updates and sweep operations for multiple wallet addresses.

Key Logic:

  1. Finds addresses with oldest lastUsedAt timestamps
  2. Updates balances for each address (batch processing for UTXO)
  3. Triggers sweep events for addresses with sufficient balance
  4. Handles blockchain-specific logic (different limits for UTXO vs account-based)

Dependencies:

  • WalletAddressBalanceUpdater - Updates individual address balances
  • UtxoWalletAddressesBalanceUpdater - Batch updates for UTXO addresses
  • WalletAddressRepository - Address persistence
  • EventPublisher - Publishes sweep events

This is an example of a complex application service that orchestrates multiple simpler services.

Application Service Dependencies

Error Handling

Application services implement consistent error handling patterns:

  1. Validation Errors: Return undefined or throw domain exceptions
  2. Infrastructure Errors: Propagate with context
  3. Business Rule Violations: Return specific error types

Event Publishing

Many application services publish domain events:

  • WalletAddressCreatedDomainEvent - When new address is created
  • TransactionCreatedDomainEvent - When transaction is created
  • BalanceUpdatedDomainEvent - When balance changes

Testing Strategy

Application services are tested with:

  1. Unit Tests: Mock all dependencies
  2. Integration Tests: Use in-memory repositories
  3. Contract Tests: Verify repository interfaces

Performance Considerations

  • Address Generation: Cached derivation paths
  • Balance Queries: Batched blockchain calls
  • Transaction Processing: Queued for async processing
  • Event Publishing: Async to avoid blocking