Skip to content

Conversation

@NeOMakinG
Copy link
Collaborator

No description provided.

Minimoi and others added 28 commits January 18, 2026 02:37
…re and package.json

- Added package.json with @shapeshift/send-swap-service name
- Added tsconfig.json extending root config
- Added nest-cli.json with NestJS configuration
- Added prisma.config.ts for database setup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…enums

- Added prisma/schema.prisma with Quote model following existing patterns
- Defined QuoteStatus enum (ACTIVE, EXPIRED, DEPOSIT_RECEIVED, EXECUTING, COMPLETED, FAILED)
- Defined SwapperType enum (DIRECT, SERVICE_WALLET)
- Added indexes on depositAddress, quoteId, and status for query performance

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…nd NativeHDWallet

- Add WalletManagerService with Keyring and NativeHDWallet initialization
- Implement loadDevice for mnemonic loading from environment variables
- Create WalletModule for NestJS integration
- Add hdwallet-core and hdwallet-native dependencies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…TH, AVAX, BSC, Polygon)

- Add bip32ToAddressNList, slip44ByCoin, ETHGetAddress imports from hdwallet-core
- Add EvmChain type for supported EVM chains
- Add EvmAddressResult interface for address metadata
- Add getEvmDerivationPath() for BIP44 path generation
- Add getEvmAddress() for single chain address generation
- Add getAllEvmAddresses() for batch address generation
- Add getEvmDepositAddress() for quote-specific deposit addresses
- All EVM chains use same SLIP44 coin type (60) for address derivation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…BTC, LTC, DOGE, BCH)

- Add BTCGetAddress and BTCInputScriptType imports from hdwallet-core
- Define UtxoChain type for supported UTXO chains (BTC, LTC, DOGE, BCH)
- Add UtxoAddressResult interface with address metadata including scriptType
- Create UTXO_CHAIN_CONFIG with coin names, script types, and derivation purposes
  - BTC/LTC: Use SegWit (P2WPKH) with BIP84 derivation for native bech32 addresses
  - DOGE/BCH: Use Legacy (P2PKH) with BIP44 derivation
- Implement getUtxoDerivationPath() for chain-specific BIP32 paths
- Implement getUtxoAddress() for single UTXO chain address generation
- Add getAllUtxoAddresses() for batch address generation
- Add getUtxoDepositAddress() convenience method for quote addresses

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…tion (ATOM, OSMO)

- Import CosmosGetAddress from @shapeshiftoss/hdwallet-core
- Add CosmosChain type for ATOM and OSMO chains
- Add CosmosAddressResult interface with address metadata
- Add COSMOS_CHAIN_CONFIG with proper SLIP44 coin type 118 mappings
- Implement getCosmosDerivationPath() for BIP44 path generation
- Implement getCosmosAddress() for single address generation
- Implement getAllCosmosAddresses() for batch address generation
- Implement getCosmosDepositAddress() for quote-specific addresses

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added Solana wallet address generation to WalletManagerService:
- Import SolanaGetAddress from @shapeshiftoss/hdwallet-core
- Add SolanaAddressResult interface for type safety
- Add SOLANA_COIN_NAME constant (SLIP44 coin type 501)
- Implement getSolanaDerivationPath() using m/44'/501'/account'/0'
- Implement getSolanaAddress() using wallet.solanaGetAddress()
- Add getSolanaDepositAddressInfo() for startup initialization
- Add getSolanaDepositAddress() for quote-specific addresses

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add WalletInitService that handles explicit wallet initialization at startup
- Service is called from main.ts before HTTP listener starts
- Verifies wallet can generate addresses for all chain types (EVM, UTXO, Cosmos, Solana)
- Logs primary deposit addresses during startup for verification
- Follows ChainAdapterInitService pattern from swap-service

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…classification

- Created SwapperType enum (DIRECT, SERVICE_WALLET) in swapper.types.ts
- Implemented SwapperManagerService with classification logic:
  - Direct swappers: Chainflip, NEAR Intents
  - Service-wallet swappers: THORChain, Jupiter, Relay, Mayachain, ButterSwap, Bebop
  - Excluded swappers (no destination address support): Zrx, CowSwap, etc.
- Added filtering methods to exclude swappers without destination address support
- Created SwappersModule for NestJS integration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…-destination-address swappers

Created swapper-config.ts with:
- EXCLUDED_SWAPPERS constant array (Zrx, CowSwap, ArbitrumBridge, Portals, Cetus, Sunio, Avnu, Stonfi)
- DIRECT_SWAPPERS constant array (Chainflip, NearIntents)
- SERVICE_WALLET_SWAPPERS constant array (THORChain, Jupiter, Relay, Mayachain, ButterSwap, Bebop)
- filterValidSwappers() function to filter out excluded swappers
- SWAPPER_CONFIGS map with full configuration for all swappers
- Helper functions: isExcludedSwapper, isValidSwapper, getSwapperConfig

Updated swapper-manager.service.ts to use externalized configuration from swapper-config.ts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ific gas

- Add GasCalculatorService with chain-specific gas overhead estimation
- Define ChainId enum with CAIP-2 chain identifiers for EVM, UTXO, Cosmos, and Solana
- Create GAS_OVERHEAD_BY_CHAIN mapping with conservative overhead estimates
- Include volatility buffers for networks with variable gas prices (ETH 20%, BTC 30%)
- Add methods for calculating overhead from asset IDs (CAIP-19 format)
- Export GasCalculatorService from SwappersModule

Gas overhead values cover typical swap transaction costs:
- EVM: Approve + swap (~0.003 ETH for mainnet, lower for L2s)
- UTXO: Transaction size-based fees (10k sats for BTC)
- Cosmos: Fixed gas costs (~0.005 ATOM)
- Solana: Base + priority fees (~0.01 SOL)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ackage

Added comprehensive Quote types for send-swap-service:
- QuoteStatus type: ACTIVE, EXPIRED, DEPOSIT_RECEIVED, EXECUTING, COMPLETED, FAILED
- SwapperType type: DIRECT, SERVICE_WALLET
- Quote interface: Full quote model with assets, addresses, timing, and execution fields
- CreateQuoteDto: Input for creating a quote (sellAssetId, buyAssetId, amount, receiveAddress)
- QuoteResponse: API response with quote details, QR data, and swapper info
- QuoteStatusResponse: Execution status response
- UpdateQuoteStatusDto: For updating quote status during execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… logic

- Create QuotesService with quote lifecycle management:
  - createQuote: Generate quotes with 30-min expiration
  - getQuote: Retrieve quote by ID with expiration check
  - getQuoteByDepositAddress: Find active quote by deposit address
  - getActiveQuotes/getQuotesToMonitor: Query methods for cron jobs
  - markDepositReceived/markExecuting/markCompleted/markFailed: Status transitions
  - expireStaleQuotes: Batch expire old quotes

- Generate deposit addresses based on chain family (EVM, UTXO, Cosmos, Solana)
- Calculate gas overhead for SERVICE_WALLET swappers
- Generate QR-friendly deposit URIs for all supported chains
- Extract chain info from CAIP-19 asset IDs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…and GET /quotes/:id

Add QuotesController to handle HTTP endpoints for quote operations:
- POST /quotes: Creates a new quote for send-swap operations
- GET /quotes/:id: Retrieves a quote by its unique identifier

Updated QuotesModule to register the controller.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…e TTL)

- Add QUOTE_EXPIRATION_MS constant (1800000ms) for millisecond-based operations
- Add isQuoteExpired() helper method to check quote expiration status
- Add getRemainingTimeMs() to get remaining time before quote expires
- Add canAcceptDeposit() to verify quote can still accept deposits
- Add getExpirationDurationMs() to expose TTL duration to clients
- Enhanced documentation for expiration constants and methods
- Updated checkAndUpdateExpiration() to use helper method and add logging

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… (every 30 seconds)

- Add DepositMonitorService with @Cron(EVERY_30_SECONDS) for deposit monitoring
- Create MonitoringModule that imports QuotesModule
- Register MonitoringModule in AppModule
- Monitor job fetches active quotes and checks deposit addresses
- Error handling follows swap-polling.service.ts pattern

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…y address + amount)

- Add chain-aware deposit detection with support for EVM, UTXO, Cosmos, and Solana
- Implement checkDepositReceived() method for blockchain queries via Unchained APIs
- Add amount matching logic with 0.1% tolerance for minor variations
- Handle edge cases: partial deposits, over-deposits
- Add per-chain confirmation requirements (EVM: 12, UTXO: 3, Cosmos: 1, Solana: 32)
- Implement getChainFamily() for address format detection
- Add transaction query methods for each chain family
- Update MonitoringModule with HttpModule and ConfigModule dependencies

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…nt race conditions

Add optimistic locking to prevent race conditions when multiple deposit
monitor iterations might process the same quote simultaneously:

- Add lockQuote() method to QuotesService that atomically transitions
  quotes from ACTIVE to EXECUTING status using database-level guards
- Update markDepositReceived() to accept both ACTIVE and EXECUTING status
  for backwards compatibility with direct calls
- Integrate locking into deposit-monitor.service.ts before processing
  confirmed deposits
- If lock acquisition fails, skip processing (quote already being handled)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ervice-wallet)

Created SwapExecutorService that handles swap execution with different flows:
- DIRECT swappers (Chainflip, NEAR Intents): Monitor external execution, check status
- SERVICE_WALLET swappers (THORChain, Jupiter, etc.): Placeholder for self-execution

Key changes:
- Created apps/send-swap-service/src/execution/swap-executor.service.ts
- Created apps/send-swap-service/src/execution/execution.module.ts
- Updated deposit-monitor.service.ts to integrate swap execution after deposit
- Added checkPendingSwapExecution for monitoring DEPOSIT_RECEIVED quotes
- Added updateQuoteAfterExecution for status updates based on execution result

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…d execution

Add explicit updateQuoteStatus method to deposit monitor for handling
status transitions after swap execution:
- COMPLETED: Set when swap executes successfully with tx hash
- FAILED: Set when swap execution encounters an error

Enhanced updateQuoteAfterExecution with:
- Detailed JSDoc documenting status transition flows
- Centralized status update logic with consistent logging
- Error handling with re-throw for caller awareness

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix default port to 3004 (was incorrectly set to 3002)
- Add startup verification script with expected log messages checklist
- Documents wallet initialization flow: EVM, UTXO (BTC), Cosmos (ATOM), Solana
- Verification script checks for MNEMONIC in root .env

Verification shows wallet init service properly:
1. Initializes HD wallet from mnemonic
2. Verifies address generation for all chain types
3. Logs deposit addresses for debugging
4. Fails fast on initialization errors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added test infrastructure for the quotes API:
- Added quotes.controller.spec.ts with unit tests for POST /quotes and GET /quotes/:id
- Created test-quotes-api.sh for API endpoint testing with proper request bodies
- Added jest.config.js for running unit tests
- Updated package.json with test scripts and jest dependencies

Tests verify:
- Quote creation returns 201 with proper response structure
- Quote response includes qrData for QR code generation
- Quote has 30-minute expiration
- Quote retrieval by ID works correctly
- Invalid swappers (e.g., Zrx) are rejected with 400

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ng activity

- Updated verify-startup.sh with expected cron job log messages
- Added cron verification to startup checklist
- Documented expected logs: "Starting deposit check...", quote monitoring status
- Cron runs every 30 seconds via @nestjs/schedule

Verification: Code inspection confirms ScheduleModule configured correctly,
DepositMonitorService has @Cron decorator, and proper logging statements present.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants