# Transaction Manager Service

The transaction manager coordinates queued blockchain submissions with retry and
confirmation handling. It is designed to sit between upstream product flows and
low-level RPC providers, ensuring that intermittent failures, nonce management,
and confirmation polling are centrally managed.

## Features

- In-memory FIFO queue with single-flight processing
- Exponential backoff retry scheduling plus attempt tracking
- Confirmation polling via pluggable provider interface
- EventEmitter hooks for observability (`transactionQueued`,
  `transactionSubmitted`, `transactionRetryScheduled`, `transactionConfirmed`,
  `transactionFailed`)
- Metrics snapshot (`getMetrics`) for queue depth and success ratios
- Promise-based `waitForCompletion` helper suitable for API responders

## Provider Interface

```ts
type TransactionProvider = {
  sendTransaction(request: TransactionRequest): Promise<{ hash: string }>;
  waitForConfirmation(hash: string): Promise<TransactionReceipt>;
};
```

Implementations can wrap ethers.js, viem, or custom RPC clients. The manager
remains agnostic to the underlying network.

## Usage

```ts
import { TransactionManager } from './transaction-manager';

const provider = {
  sendTransaction: async (request) => rpcClient.sendTransaction(request),
  waitForConfirmation: async (hash) => rpcClient.waitForReceipt(hash),
};

const manager = new TransactionManager({
  provider,
  baseRetryDelayMs: 500,
  maxRetries: 5,
});

const { transactionId } = await manager.queueTransaction({
  chainId: 137,
  from: ACCOUNT_ADDRESS,
  to: CONTRACT_ADDRESS,
  data: encodedCalldata,
});

const result = await manager.waitForCompletion(transactionId);
if (result.status === 'confirmed') {
  console.log('🎉 confirmed at', result.receipt?.blockNumber);
} else {
  console.error('❌ failed:', result.error);
}
```

## Tests

```bash
npx jest --config apps/lilith/svc-transaction-manager/jest.config.cjs --runInBand
```
