From 6afb13535ad74282121620a03e9756e89064f760 Mon Sep 17 00:00:00 2001 From: "prd-carapulse[bot]" <264278285+prd-carapulse[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 07:33:13 +0000 Subject: [PATCH 1/4] refactor: align bot naming with quoter terminology Rebase the package rename onto the latest main branch; align code, documentation, tests, configuration, workflows, and generated references with the repository's quoter terminology; preserve externally bound compatibility identifiers; and carry forward the Railway volume-permission hardening from main. --- .agents/skills/build-jsdoc/SKILL.md | 28 ++--- .github/workflows/checks.yml | 2 +- .github/workflows/deploy-production.yml | 18 +-- ...d.yml => deploy-quoter-bot-playground.yml} | 12 +- ...n.yml => deploy-quoter-bot-production.yml} | 10 +- .gitignore | 10 +- CLAUDE.md | 6 +- bots/blue-liquidation/test/fork/harness.ts | 2 +- .../market-making-monitor-halted.error.ts | 16 --- .../midnight-liquidation/test/fork/harness.ts | 2 +- .../.env.example | 2 +- bots/{market-making => quoter-bot}/Dockerfile | 4 +- bots/{market-making => quoter-bot}/README.md | 108 +++++++++--------- .../docker-compose.yml | 6 +- .../docs/architecture.md | 26 ++--- .../package.json | 4 +- .../playground/app.tsx | 0 .../playground/collection-import.error.ts | 0 .../playground/collection-validation.error.ts | 0 .../playground/field-visibility.utils.ts | 0 .../playground/fragment-codec.error.ts | 0 .../playground/index.html | 0 .../playground/model.ts | 0 .../playground/playground-error.utils.ts | 0 .../playground-initialization.error.ts | 0 .../playground/preview-generation.error.ts | 0 .../playground/strict-json.error.ts | 0 .../playground/styles.css | 0 .../quoter-bot.example.yaml} | 2 +- .../scripts/build.ts | 0 .../scripts/bundle-failed.error.ts | 0 .../scripts/check-jsdoc.test.ts | 0 .../scripts/check-jsdoc.ts | 4 +- .../scripts/deploy-railway.ts | 8 +- .../scripts/js-doc-validation.error.ts | 0 .../scripts/playground-atomic-publish.mjs | 0 .../playground-atomic-publish.test.mjs | 0 .../scripts/playground-build-arguments.d.mts | 0 .../scripts/playground-build-arguments.mjs | 0 .../scripts/playground-build.mjs | 6 +- .../scripts/playground-build.test.mjs | 28 ++--- .../scripts/playground-path-safety.mjs | 0 .../scripts/playground-process.mjs | 0 .../scripts/playground-process.test.mjs | 0 .../scripts/playground-serve-support.mjs | 0 .../scripts/playground-serve.mjs | 0 .../scripts/playground-serve.test.mjs | 30 ++--- .../scripts/playground-smoke-output-probe.mjs | 0 .../playground-smoke-persistence.error.mjs | 0 .../scripts/playground-smoke-suite.test.mjs | 16 +-- .../scripts/playground-smoke-support.mjs | 4 +- .../scripts/playground-smoke.browser.mjs | 18 ++- .../scripts/playground-smoke.mjs | 4 +- .../scripts/playground-smoke.oxlintrc.json | 0 .../scripts/playground-smoke.test.mjs | 16 ++- .../scripts/railway-deployment.error.ts | 0 .../scripts/railway-entrypoint.mjs | 0 .../scripts/railway.utils.ts | 0 .../bootstrap-ownership-cleanup.error.ts | 0 .../position-bootstrap-halted.error.ts | 0 ...position-bootstrap-monitor-halted.error.ts | 0 .../bootstrap/position-bootstrap-verbose.ts | 0 .../bootstrap/position-bootstrap.service.ts | 0 .../offer-invalidation-failed.error.ts | 0 .../offer-invalidation.service.ts | 0 .../ladder/ladder-cycle-halted.error.ts | 0 .../ladder/ladder-monitor-halted.error.ts | 2 +- .../ladder/ladder-ownership-cleanup.error.ts | 0 .../ladder/ladder-quoter.service.ts} | 4 +- .../ladder/ladder-quoter.utils.ts} | 0 .../src/application/ladder/ladder-verbose.ts | 0 .../application/operator-error-name.utils.ts | 2 +- .../quoter-bot-monitor-halted.error.ts | 16 +++ .../quoter-bot/quoter-bot-mutation.utils.ts} | 10 +- .../quoter-bot/quoter-bot.service.ts} | 54 ++++----- .../application/setup/safe-provider.error.ts | 0 .../application/setup/setup-check.service.ts | 4 +- .../application/setup/setup-check.utils.ts | 0 .../application/setup/setup-failed.error.ts | 0 .../setup-monitor-configuration.error.ts | 0 .../setup/setup-monitor-halted.error.ts | 0 .../src/application/version.service.ts | 0 .../src/bootstrap.ts | 16 +-- .../src/config/config-file.error.ts | 0 .../src/config/config-source.utils.ts | 2 +- .../src/config/config-validation.error.ts | 0 .../src/config/config.service.ts | 6 +- .../src/config/config.utils.ts | 2 +- .../src/config/market-collections.ts | 0 .../src/config/signer-identity.utils.ts | 0 .../bootstrap-configuration.error.ts | 0 .../domain/bootstrap/position-bootstrap.ts | 0 .../src/domain/bytes32.ts | 0 .../ladder/ladder-configuration.error.ts | 0 .../src/domain/ladder/ladder.ts | 0 .../src/domain/setup/.gitkeep | 0 .../src/domain/target-rate.ts | 0 .../src/index.ts | 12 +- .../bootstrap/bootstrap-adapter.error.ts | 0 .../bootstrap/bootstrap-exposure.utils.ts | 0 .../bootstrap-group-ownership.utils.ts | 2 +- .../bootstrap/bootstrap-groups.utils.ts | 0 .../bootstrap/bootstrap-hard-halt.error.ts | 0 .../bootstrap/bootstrap-make.service.ts | 0 .../bootstrap-mempool-validation.error.ts | 0 .../bootstrap-mempool-validation.utils.ts | 0 .../bootstrap/bootstrap-offer.utils.ts | 0 .../bootstrap-pending-offer.utils.ts | 0 .../bootstrap/bootstrap-position.service.ts | 0 .../bootstrap-reference-rate.service.ts | 0 .../bootstrap-requirement-client.utils.ts | 0 .../bootstrap/bootstrap-requirements.utils.ts | 0 .../bootstrap/bootstrap-spread.utils.ts | 0 .../bootstrap/bootstrap-transaction.utils.ts | 0 .../bootstrap/production-bootstrap.ts | 0 .../src/infrastructure/cli/cli-usage.error.ts | 0 .../src/infrastructure/cli/cli.ts | 42 +++---- .../cli/offer-invalidation-argument.utils.ts | 0 .../cli/password-prompt.utils.ts | 0 .../cli/quoter-bot-entrypoint.ts} | 16 +-- .../batch-offer-invalidation.utils.ts | 0 .../offer-invalidation-adapter.error.ts | 0 .../offer-invalidation-group.utils.ts | 0 .../offer-invalidation-transaction.utils.ts | 0 .../production-offer-invalidation.ts | 0 .../ladder/ladder-active-publication.utils.ts | 0 .../ladder/ladder-adapter.error.ts | 0 .../ladder/ladder-cash-reservation.utils.ts | 0 .../ladder/ladder-group-ownership.utils.ts | 2 +- .../ladder/ladder-hard-halt.error.ts | 0 .../ladder/ladder-make.service.ts | 2 +- .../ladder/ladder-offer.utils.ts | 0 .../ladder/ladder-ratification.utils.ts | 0 .../ladder/ladder-signature.utils.ts | 0 .../ladder/ladder-spread.utils.ts | 0 .../ladder/ladder-transaction.utils.ts | 0 .../ladder/production-ladder.ts | 2 +- .../make/maker-account.error.ts | 0 .../make/maker-account.utils.ts | 0 .../make/managed-maker-account.utils.ts | 0 .../make/read-only-bootstrap-make.service.ts | 0 .../make/read-only-ladder-make.service.ts | 2 +- .../make/read-only-make.utils.ts | 0 .../reference/blue-reference-reader.utils.ts | 0 .../reference/reference-adapter.error.ts | 0 .../setup-state/chain-reader.utils.ts | 0 .../setup-state/http-json.utils.ts | 0 .../setup-state/provider-pagination.error.ts | 0 .../setup-state/provider-read.error.ts | 0 .../setup-state/provider-read.utils.ts | 0 .../setup-state/provider-response.error.ts | 0 .../setup-state/viem-setup-state.service.ts | 0 .../setup-state/viem-setup-state.utils.ts | 0 .../position-bootstrap.service.test.ts | 0 .../offer-invalidation.service.test.ts | 0 .../ladder/ladder-quoter.service.test.ts} | 23 ++-- .../operator-error-name.utils.test.ts | 8 +- .../quoter-bot-mutation.utils.test.ts} | 12 +- .../quoter-bot/quoter-bot.service.test.ts} | 72 ++++++------ .../setup/setup-check.service.test.ts | 0 .../test/application/version.service.test.ts | 0 .../test/bootstrap.test.ts | 10 +- .../test/config/config-loading.test.ts | 28 ++--- .../test/config/config-private-key.test.ts | 0 .../test/config/config.service.test.ts | 0 .../test/config/config.utils.test.ts | 0 .../test/config/key-storage.test.ts | 12 +- .../test/config/ladder-config.test.ts | 2 +- .../bootstrap/position-bootstrap.test.ts | 0 .../test/domain/ladder/ladder.test.ts | 0 .../test/e2e/anvil-startup.error.ts | 0 .../test/e2e/anvil.ts | 2 +- .../test/e2e/constants.ts | 0 .../test/e2e/setup-api.ts | 0 .../test/e2e/setup-check.e2e.test.ts | 2 +- .../test/e2e/setup-maker.ts | 2 +- .../test/error-convention.test.ts | 2 +- .../test/fixtures/ecrecover-ratifier-base.hex | 0 .../test/fixtures/setter-ratifier-base.hex | 0 .../bootstrap/bootstrap-make.service.test.ts | 0 ...bootstrap-mempool-validation.utils.test.ts | 0 .../bootstrap-pending-offer.utils.test.ts | 0 .../bootstrap-position.service.test.ts | 0 .../bootstrap-reference-rate.service.test.ts | 0 ...bootstrap-requirement-client.utils.test.ts | 0 .../bootstrap/bootstrap-spread.utils.test.ts | 0 .../bootstrap/production-bootstrap.test.ts | 10 +- .../test/infrastructure/cli/cli.test.ts | 74 ++++++------ .../cli/key-storage-cli.test.ts | 2 +- .../cli/password-prompt.test.ts | 0 ...oter-bot-entrypoint-observability.test.ts} | 30 ++--- ...fer-invalidation-transaction.utils.test.ts | 0 .../batch-offer-invalidation.utils.test.ts | 0 .../offer-invalidation-group.utils.test.ts | 0 ...fer-invalidation-transaction.utils.test.ts | 0 .../production-offer-invalidation.test.ts | 0 .../ladder-active-publication.utils.test.ts | 0 .../ladder-cash-reservation.utils.test.ts | 0 .../ladder-group-ownership.utils.test.ts | 0 .../ladder/ladder-make.service.test.ts | 0 .../ladder/ladder-offer.utils.test.ts | 0 .../ladder/ladder-ratification.utils.test.ts | 0 .../ladder/ladder-signature.utils.test.ts | 0 .../ladder/ladder-spread.utils.test.ts | 0 .../ladder/ladder-transaction.utils.test.ts | 0 .../ladder/production-ladder.test.ts | 0 .../infrastructure/make/maker-account.test.ts | 8 +- .../make/managed-maker-account.utils.test.ts | 0 .../make/read-only-make.service.test.ts | 0 .../viem-setup-state.service.test.ts | 0 .../test/playground/artifact.test.ts | 2 +- .../playground/field-visibility.utils.test.ts | 0 .../test/playground/model.test.ts | 0 .../test/playground/module-graph.test.ts | 0 .../test/playground/pages-workflow.test.ts | 14 +-- .../playground/playground-error.utils.test.ts | 0 .../test/playground/react-contract.test.ts | 0 .../shared-market-collections.test.ts | 0 .../test/playground/tsconfig-coverage.test.ts | 2 +- .../test/scripts/railway.utils.test.ts | 18 +-- .../tsconfig.json | 0 .../typedoc.json | 14 +-- .../vitest.config.ts | 2 +- docs/CONVENTIONS.md | 2 +- docs/INDEX.md | 2 +- .../TIB-2026-07-20-migrate-to-pnpm.md | 2 +- ... => TIB-2026-07-27-midnight-quoter-bot.md} | 52 ++++----- ...-04-extract-quoter-bot-shared-packages.md} | 24 ++-- knip.json | 2 +- package.json | 6 +- .../logging/test/cli-logger.utils.test.ts | 6 +- .../test/bot-observability.utils.test.ts | 6 +- .../test/verbose-argv.utils.test.ts | 4 +- pnpm-lock.yaml | 2 +- vitest.config.ts | 2 +- 235 files changed, 522 insertions(+), 529 deletions(-) rename .github/workflows/{deploy-market-making-playground.yml => deploy-quoter-bot-playground.yml} (85%) rename .github/workflows/{deploy-market-making-production.yml => deploy-quoter-bot-production.yml} (72%) delete mode 100644 bots/market-making/src/application/market-making/market-making-monitor-halted.error.ts rename bots/{market-making => quoter-bot}/.env.example (99%) rename bots/{market-making => quoter-bot}/Dockerfile (89%) rename bots/{market-making => quoter-bot}/README.md (93%) rename bots/{market-making => quoter-bot}/docker-compose.yml (93%) rename bots/{market-making => quoter-bot}/docs/architecture.md (90%) rename bots/{market-making => quoter-bot}/package.json (96%) rename bots/{market-making => quoter-bot}/playground/app.tsx (100%) rename bots/{market-making => quoter-bot}/playground/collection-import.error.ts (100%) rename bots/{market-making => quoter-bot}/playground/collection-validation.error.ts (100%) rename bots/{market-making => quoter-bot}/playground/field-visibility.utils.ts (100%) rename bots/{market-making => quoter-bot}/playground/fragment-codec.error.ts (100%) rename bots/{market-making => quoter-bot}/playground/index.html (100%) rename bots/{market-making => quoter-bot}/playground/model.ts (100%) rename bots/{market-making => quoter-bot}/playground/playground-error.utils.ts (100%) rename bots/{market-making => quoter-bot}/playground/playground-initialization.error.ts (100%) rename bots/{market-making => quoter-bot}/playground/preview-generation.error.ts (100%) rename bots/{market-making => quoter-bot}/playground/strict-json.error.ts (100%) rename bots/{market-making => quoter-bot}/playground/styles.css (100%) rename bots/{market-making/market-making.example.yaml => quoter-bot/quoter-bot.example.yaml} (98%) rename bots/{market-making => quoter-bot}/scripts/build.ts (100%) rename bots/{market-making => quoter-bot}/scripts/bundle-failed.error.ts (100%) rename bots/{market-making => quoter-bot}/scripts/check-jsdoc.test.ts (100%) rename bots/{market-making => quoter-bot}/scripts/check-jsdoc.ts (98%) rename bots/{market-making => quoter-bot}/scripts/deploy-railway.ts (97%) rename bots/{market-making => quoter-bot}/scripts/js-doc-validation.error.ts (100%) rename bots/{market-making => quoter-bot}/scripts/playground-atomic-publish.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-atomic-publish.test.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-build-arguments.d.mts (100%) rename bots/{market-making => quoter-bot}/scripts/playground-build-arguments.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-build.mjs (96%) rename bots/{market-making => quoter-bot}/scripts/playground-build.test.mjs (89%) rename bots/{market-making => quoter-bot}/scripts/playground-path-safety.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-process.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-process.test.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-serve-support.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-serve.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-serve.test.mjs (96%) rename bots/{market-making => quoter-bot}/scripts/playground-smoke-output-probe.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-smoke-persistence.error.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/playground-smoke-suite.test.mjs (93%) rename bots/{market-making => quoter-bot}/scripts/playground-smoke-support.mjs (99%) rename bots/{market-making => quoter-bot}/scripts/playground-smoke.browser.mjs (98%) rename bots/{market-making => quoter-bot}/scripts/playground-smoke.mjs (99%) rename bots/{market-making => quoter-bot}/scripts/playground-smoke.oxlintrc.json (100%) rename bots/{market-making => quoter-bot}/scripts/playground-smoke.test.mjs (98%) rename bots/{market-making => quoter-bot}/scripts/railway-deployment.error.ts (100%) rename bots/{market-making => quoter-bot}/scripts/railway-entrypoint.mjs (100%) rename bots/{market-making => quoter-bot}/scripts/railway.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/application/bootstrap/bootstrap-ownership-cleanup.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/bootstrap/position-bootstrap-halted.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/bootstrap/position-bootstrap-monitor-halted.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/bootstrap/position-bootstrap-verbose.ts (100%) rename bots/{market-making => quoter-bot}/src/application/bootstrap/position-bootstrap.service.ts (100%) rename bots/{market-making => quoter-bot}/src/application/invalidation/offer-invalidation-failed.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/invalidation/offer-invalidation.service.ts (100%) rename bots/{market-making => quoter-bot}/src/application/ladder/ladder-cycle-halted.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/ladder/ladder-monitor-halted.error.ts (87%) rename bots/{market-making => quoter-bot}/src/application/ladder/ladder-ownership-cleanup.error.ts (100%) rename bots/{market-making/src/application/ladder/ladder-market-maker.service.ts => quoter-bot/src/application/ladder/ladder-quoter.service.ts} (99%) rename bots/{market-making/src/application/ladder/ladder-market-maker.utils.ts => quoter-bot/src/application/ladder/ladder-quoter.utils.ts} (100%) rename bots/{market-making => quoter-bot}/src/application/ladder/ladder-verbose.ts (100%) rename bots/{market-making => quoter-bot}/src/application/operator-error-name.utils.ts (98%) create mode 100644 bots/quoter-bot/src/application/quoter-bot/quoter-bot-monitor-halted.error.ts rename bots/{market-making/src/application/market-making/market-making-mutation.utils.ts => quoter-bot/src/application/quoter-bot/quoter-bot-mutation.utils.ts} (85%) rename bots/{market-making/src/application/market-making/market-making.service.ts => quoter-bot/src/application/quoter-bot/quoter-bot.service.ts} (84%) rename bots/{market-making => quoter-bot}/src/application/setup/safe-provider.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/setup/setup-check.service.ts (98%) rename bots/{market-making => quoter-bot}/src/application/setup/setup-check.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/application/setup/setup-failed.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/setup/setup-monitor-configuration.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/setup/setup-monitor-halted.error.ts (100%) rename bots/{market-making => quoter-bot}/src/application/version.service.ts (100%) rename bots/{market-making => quoter-bot}/src/bootstrap.ts (95%) rename bots/{market-making => quoter-bot}/src/config/config-file.error.ts (100%) rename bots/{market-making => quoter-bot}/src/config/config-source.utils.ts (99%) rename bots/{market-making => quoter-bot}/src/config/config-validation.error.ts (100%) rename bots/{market-making => quoter-bot}/src/config/config.service.ts (97%) rename bots/{market-making => quoter-bot}/src/config/config.utils.ts (99%) rename bots/{market-making => quoter-bot}/src/config/market-collections.ts (100%) rename bots/{market-making => quoter-bot}/src/config/signer-identity.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/domain/bootstrap/bootstrap-configuration.error.ts (100%) rename bots/{market-making => quoter-bot}/src/domain/bootstrap/position-bootstrap.ts (100%) rename bots/{market-making => quoter-bot}/src/domain/bytes32.ts (100%) rename bots/{market-making => quoter-bot}/src/domain/ladder/ladder-configuration.error.ts (100%) rename bots/{market-making => quoter-bot}/src/domain/ladder/ladder.ts (100%) rename bots/{market-making => quoter-bot}/src/domain/setup/.gitkeep (100%) rename bots/{market-making => quoter-bot}/src/domain/target-rate.ts (100%) rename bots/{market-making => quoter-bot}/src/index.ts (85%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-adapter.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-exposure.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-group-ownership.utils.ts (99%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-groups.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-hard-halt.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-make.service.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-mempool-validation.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-mempool-validation.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-offer.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-pending-offer.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-position.service.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-reference-rate.service.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-requirement-client.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-requirements.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-spread.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/bootstrap-transaction.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/bootstrap/production-bootstrap.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/cli/cli-usage.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/cli/cli.ts (92%) rename bots/{market-making => quoter-bot}/src/infrastructure/cli/offer-invalidation-argument.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/cli/password-prompt.utils.ts (100%) rename bots/{market-making/src/infrastructure/cli/market-making-entrypoint.ts => quoter-bot/src/infrastructure/cli/quoter-bot-entrypoint.ts} (88%) rename bots/{market-making => quoter-bot}/src/infrastructure/invalidation/batch-offer-invalidation.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/invalidation/offer-invalidation-adapter.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/invalidation/offer-invalidation-group.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/invalidation/offer-invalidation-transaction.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/invalidation/production-offer-invalidation.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-active-publication.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-adapter.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-cash-reservation.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-group-ownership.utils.ts (99%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-hard-halt.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-make.service.ts (99%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-offer.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-ratification.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-signature.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-spread.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/ladder-transaction.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/ladder/production-ladder.ts (99%) rename bots/{market-making => quoter-bot}/src/infrastructure/make/maker-account.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/make/maker-account.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/make/managed-maker-account.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/make/read-only-bootstrap-make.service.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/make/read-only-ladder-make.service.ts (99%) rename bots/{market-making => quoter-bot}/src/infrastructure/make/read-only-make.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/reference/blue-reference-reader.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/reference/reference-adapter.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/setup-state/chain-reader.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/setup-state/http-json.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/setup-state/provider-pagination.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/setup-state/provider-read.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/setup-state/provider-read.utils.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/setup-state/provider-response.error.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/setup-state/viem-setup-state.service.ts (100%) rename bots/{market-making => quoter-bot}/src/infrastructure/setup-state/viem-setup-state.utils.ts (100%) rename bots/{market-making => quoter-bot}/test/application/bootstrap/position-bootstrap.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/application/invalidation/offer-invalidation.service.test.ts (100%) rename bots/{market-making/test/application/ladder/ladder-market-maker.service.test.ts => quoter-bot/test/application/ladder/ladder-quoter.service.test.ts} (96%) rename bots/{market-making => quoter-bot}/test/application/operator-error-name.utils.test.ts (93%) rename bots/{market-making/test/application/market-making/market-making-mutation.utils.test.ts => quoter-bot/test/application/quoter-bot/quoter-bot-mutation.utils.test.ts} (88%) rename bots/{market-making/test/application/market-making/market-making.service.test.ts => quoter-bot/test/application/quoter-bot/quoter-bot.service.test.ts} (82%) rename bots/{market-making => quoter-bot}/test/application/setup/setup-check.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/application/version.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/bootstrap.test.ts (98%) rename bots/{market-making => quoter-bot}/test/config/config-loading.test.ts (97%) rename bots/{market-making => quoter-bot}/test/config/config-private-key.test.ts (100%) rename bots/{market-making => quoter-bot}/test/config/config.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/config/config.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/config/key-storage.test.ts (96%) rename bots/{market-making => quoter-bot}/test/config/ladder-config.test.ts (99%) rename bots/{market-making => quoter-bot}/test/domain/bootstrap/position-bootstrap.test.ts (100%) rename bots/{market-making => quoter-bot}/test/domain/ladder/ladder.test.ts (100%) rename bots/{market-making => quoter-bot}/test/e2e/anvil-startup.error.ts (100%) rename bots/{market-making => quoter-bot}/test/e2e/anvil.ts (99%) rename bots/{market-making => quoter-bot}/test/e2e/constants.ts (100%) rename bots/{market-making => quoter-bot}/test/e2e/setup-api.ts (100%) rename bots/{market-making => quoter-bot}/test/e2e/setup-check.e2e.test.ts (97%) rename bots/{market-making => quoter-bot}/test/e2e/setup-maker.ts (97%) rename bots/{market-making => quoter-bot}/test/error-convention.test.ts (98%) rename bots/{market-making => quoter-bot}/test/fixtures/ecrecover-ratifier-base.hex (100%) rename bots/{market-making => quoter-bot}/test/fixtures/setter-ratifier-base.hex (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/bootstrap/bootstrap-make.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/bootstrap/bootstrap-mempool-validation.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/bootstrap/bootstrap-pending-offer.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/bootstrap/bootstrap-position.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/bootstrap/bootstrap-reference-rate.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/bootstrap/bootstrap-requirement-client.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/bootstrap/bootstrap-spread.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/bootstrap/production-bootstrap.test.ts (99%) rename bots/{market-making => quoter-bot}/test/infrastructure/cli/cli.test.ts (92%) rename bots/{market-making => quoter-bot}/test/infrastructure/cli/key-storage-cli.test.ts (98%) rename bots/{market-making => quoter-bot}/test/infrastructure/cli/password-prompt.test.ts (100%) rename bots/{market-making/test/infrastructure/cli/market-making-entrypoint-observability.test.ts => quoter-bot/test/infrastructure/cli/quoter-bot-entrypoint-observability.test.ts} (84%) rename bots/{market-making => quoter-bot}/test/infrastructure/invalidation/batch-offer-invalidation-transaction.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/invalidation/batch-offer-invalidation.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/invalidation/offer-invalidation-group.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/invalidation/offer-invalidation-transaction.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/invalidation/production-offer-invalidation.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-active-publication.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-cash-reservation.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-group-ownership.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-make.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-offer.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-ratification.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-signature.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-spread.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/ladder-transaction.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/ladder/production-ladder.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/make/maker-account.test.ts (98%) rename bots/{market-making => quoter-bot}/test/infrastructure/make/managed-maker-account.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/make/read-only-make.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/infrastructure/setup-state/viem-setup-state.service.test.ts (100%) rename bots/{market-making => quoter-bot}/test/playground/artifact.test.ts (97%) rename bots/{market-making => quoter-bot}/test/playground/field-visibility.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/playground/model.test.ts (100%) rename bots/{market-making => quoter-bot}/test/playground/module-graph.test.ts (100%) rename bots/{market-making => quoter-bot}/test/playground/pages-workflow.test.ts (90%) rename bots/{market-making => quoter-bot}/test/playground/playground-error.utils.test.ts (100%) rename bots/{market-making => quoter-bot}/test/playground/react-contract.test.ts (100%) rename bots/{market-making => quoter-bot}/test/playground/shared-market-collections.test.ts (100%) rename bots/{market-making => quoter-bot}/test/playground/tsconfig-coverage.test.ts (96%) rename bots/{market-making => quoter-bot}/test/scripts/railway.utils.test.ts (94%) rename bots/{market-making => quoter-bot}/tsconfig.json (100%) rename bots/{market-making => quoter-bot}/typedoc.json (92%) rename bots/{market-making => quoter-bot}/vitest.config.ts (97%) rename docs/decisions/{TIB-2026-07-27-midnight-market-making-bot.md => TIB-2026-07-27-midnight-quoter-bot.md} (96%) rename docs/decisions/{TIB-2026-08-04-extract-market-making-shared-packages.md => TIB-2026-08-04-extract-quoter-bot-shared-packages.md} (90%) diff --git a/.agents/skills/build-jsdoc/SKILL.md b/.agents/skills/build-jsdoc/SKILL.md index 07f48b85..176867ce 100644 --- a/.agents/skills/build-jsdoc/SKILL.md +++ b/.agents/skills/build-jsdoc/SKILL.md @@ -1,29 +1,29 @@ --- name: build-jsdoc -description: Use when changing externally facing TypeScript in the market-making bot. Inventory public callables, enforce substantive JSDoc, and build browsable TypeDoc output before completion. +description: Use when changing externally facing TypeScript in the quoter-bot bot. Inventory public callables, enforce substantive JSDoc, and build browsable TypeDoc output before completion. version: 1.1.0 author: Morpho license: Apache-2.0 metadata: hermes: - tags: [typescript, jsdoc, typedoc, market-making, verification] + tags: [typescript, jsdoc, typedoc, quoter-bot, verification] related_skills: [] --- -# Build Market-Making JSDoc +# Build Quoter Bot JSDoc ## Overview -Use the package-owned TypeScript AST inventory and TypeDoc configuration to keep the market-making +Use the package-owned TypeScript AST inventory and TypeDoc configuration to keep the quoter-bot public surface documented. The build treats TypeDoc warnings as errors and writes ignored, browsable HTML; generated output is verification evidence, not a committed artifact. ## When to Use - Any change to an exported function, class, interface, or type under - `bots/market-making/src/**`. + `bots/quoter-bot/src/**`. - Any change to a public constructor, method, accessor, or exported callable signature. -- Before completing market-making work that could alter runtime/package boundaries. +- Before completing quoter-bot work that could alter runtime/package boundaries. Do not use this workflow to document private implementation helpers unless their safety behavior cannot be understood from the public contract. @@ -54,13 +54,13 @@ corepack: ```sh pnpm install --frozen-lockfile -pnpm --filter @morpho-org/market-making-bot run jsdoc:check -pnpm --filter @morpho-org/market-making-bot run jsdoc:build +pnpm --filter @morpho-org/quoter-bot run jsdoc:check +pnpm --filter @morpho-org/quoter-bot run jsdoc:build ``` - Coverage command: `jsdoc:check` -- TypeDoc config: `bots/market-making/typedoc.json` -- Output: `bots/market-making/build/jsdoc/index.html` +- TypeDoc config: `bots/quoter-bot/typedoc.json` +- Output: `bots/quoter-bot/build/jsdoc/index.html` - Output policy: `build/` is ignored; do not stage generated HTML. Completion criterion: the AST inventory exits zero, TypeDoc emits zero warnings/errors, and @@ -95,7 +95,7 @@ Completion criterion: no named utility function declaration remains in changed s shares a file with a class, and each protocol/viem reuse or local exception is evidenced in code or the change report. -For the current market-making implementation, preserve these verified package boundaries: +For the current quoter-bot implementation, preserve these verified package boundaries: - `@morpho-org/midnight-sdk@1.3.0/api` owns active-book URL construction and mapping through `MidnightApi.fetchBooks`; inject the package's sanitized timeout-aware fetch adapter. @@ -116,8 +116,8 @@ every added public callable exactly once. ## Inspect Generated Docs ```sh -test -s bots/market-making/build/jsdoc/index.html -python3 -m http.server 8000 --directory bots/market-making/build/jsdoc +test -s bots/quoter-bot/build/jsdoc/index.html +python3 -m http.server 8000 --directory bots/quoter-bot/build/jsdoc ``` Open `http://127.0.0.1:8000/` and inspect the setup-check service, state port, viem adapter, @@ -144,7 +144,7 @@ URL, default runtime environment, raw provider response, or generated source-map - [ ] Pinned pnpm install succeeds with the lockfile frozen. - [ ] AST coverage prints the exhaustive public declaration inventory and exits zero. - [ ] TypeDoc exits zero with warnings-as-errors enabled. -- [ ] `bots/market-making/build/jsdoc/index.html` exists and is non-empty. +- [ ] `bots/quoter-bot/build/jsdoc/index.html` exists and is non-empty. - [ ] Generated output is ignored and absent from `git status`. - [ ] Public docs explain failure, side-effect, timeout/deadline, and concurrency behavior where relevant. - [ ] Independent checks still run concurrently through `Promise.all` where possible. diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 80444f50..345f9b44 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -59,7 +59,7 @@ jobs: RPC_URL_8453: ${{ secrets.RPC_URL_8453 }} - name: Run browser smoke tests - run: pnpm --filter @morpho-org/market-making-bot run playground:smoke:test + run: pnpm --filter @morpho-org/quoter-bot run playground:smoke:test Dead-Code: runs-on: ubuntu-latest diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index 77140df3..dd265f45 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -20,7 +20,7 @@ on: - blue-liq - midnight-liq - crossed-books - - market-making + - quoter-bot permissions: contents: read @@ -41,7 +41,7 @@ jobs: blue_liq: ${{ steps.pick.outputs.blue_liq }} midnight_liq: ${{ steps.pick.outputs.midnight_liq }} crossed_books: ${{ steps.pick.outputs.crossed_books }} - market_making: ${{ steps.pick.outputs.market_making }} + quoter_bot: ${{ steps.pick.outputs.quoter_bot }} steps: - id: pick env: @@ -63,7 +63,7 @@ jobs: echo "blue_liq=$(has blue-liq)" echo "midnight_liq=$(has midnight-liq)" echo "crossed_books=$(has crossed-books)" - echo "market_making=$(has market-making)" + echo "quoter_bot=$(has quoter-bot)" } >> "$GITHUB_OUTPUT" Blue: @@ -101,10 +101,10 @@ jobs: github_environment: crossed-books-prod ref: ${{ github.sha }} - Market-making: + Quoter bot: needs: Select - if: ${{ needs.Select.outputs.market_making == 'true' }} - uses: ./.github/workflows/deploy-market-making-production.yml + if: ${{ needs.Select.outputs.quoter_bot == 'true' }} + uses: ./.github/workflows/deploy-quoter-bot-production.yml secrets: inherit with: ref: ${{ github.sha }} @@ -194,8 +194,8 @@ jobs: gh release create "$tag" --target "$SHA" --title "$tag" --generate-notes \ ${prev:+--notes-start-tag "$prev"} - Release-market-making: - needs: Market-making + Release-quoter-bot: + needs: Quoter bot runs-on: ubuntu-latest permissions: contents: write @@ -208,7 +208,7 @@ jobs: fetch-depth: 0 - name: Create release env: - BOT: market-making + BOT: quoter-bot SHA: ${{ github.sha }} run: | set -euo pipefail diff --git a/.github/workflows/deploy-market-making-playground.yml b/.github/workflows/deploy-quoter-bot-playground.yml similarity index 85% rename from .github/workflows/deploy-market-making-playground.yml rename to .github/workflows/deploy-quoter-bot-playground.yml index a900517e..013901fb 100644 --- a/.github/workflows/deploy-market-making-playground.yml +++ b/.github/workflows/deploy-quoter-bot-playground.yml @@ -1,10 +1,10 @@ -name: Deploy market-making playground to GitHub Pages +name: Deploy quoter-bot playground to GitHub Pages on: push: branches: [main] paths: - - bots/market-making/** + - bots/quoter-bot/** - packages/bot-kit/** - packages/logging/** - packages/monitoring/** @@ -18,7 +18,7 @@ on: - .npmrc - .nvmrc - .github/actions/setup/action.yml - - .github/workflows/deploy-market-making-playground.yml + - .github/workflows/deploy-quoter-bot-playground.yml workflow_dispatch: permissions: {} @@ -47,16 +47,16 @@ jobs: build-contracts: 'false' - name: Test playground at the GitHub Pages subpath - run: PLAYGROUND_SMOKE_BASE_PATH=/morpho-bots/ pnpm --filter @morpho-org/market-making-bot run playground:smoke:test + run: PLAYGROUND_SMOKE_BASE_PATH=/morpho-bots/ pnpm --filter @morpho-org/quoter-bot run playground:smoke:test - name: Build playground - run: pnpm --filter @morpho-org/market-making-bot run playground:build + run: pnpm --filter @morpho-org/quoter-bot run playground:build - name: Upload GitHub Pages artifact uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: name: github-pages - path: bots/market-making/playground/dist + path: bots/quoter-bot/playground/dist retention-days: 1 deploy: diff --git a/.github/workflows/deploy-market-making-production.yml b/.github/workflows/deploy-quoter-bot-production.yml similarity index 72% rename from .github/workflows/deploy-market-making-production.yml rename to .github/workflows/deploy-quoter-bot-production.yml index 61fe4438..06b4f220 100644 --- a/.github/workflows/deploy-market-making-production.yml +++ b/.github/workflows/deploy-quoter-bot-production.yml @@ -1,7 +1,7 @@ -name: Deploy market-making production +name: Deploy quoter-bot production -# Reusable deploy-only job for market-making's single Railway environment. Production's release -# selector calls this workflow after a `release-market-making` label lands on main. +# Reusable deploy-only job for quoter-bot's single Railway environment. Production's release +# selector calls this workflow after a `release-quoter-bot` label lands on main. on: workflow_call: @@ -15,7 +15,7 @@ permissions: contents: read concurrency: - group: deploy-market-making-production + group: deploy-quoter-bot-production cancel-in-progress: false jobs: @@ -42,4 +42,4 @@ jobs: RAILWAY_ENVIRONMENT: production RAILWAY_PROJECT_ID: ${{ vars.RAILWAY_PROJECT_ID }} RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }} - run: pnpm --filter @morpho-org/market-making-bot run deploy:railway + run: pnpm --filter @morpho-org/quoter-bot run deploy:railway diff --git a/.gitignore b/.gitignore index fa326487..750aba17 100644 --- a/.gitignore +++ b/.gitignore @@ -9,11 +9,11 @@ node_modules .env.* !.env.example -# Local market-making configuration (examples remain trackable) -**/market-making.yaml -**/market-making.yml -!**/market-making.example.yaml -!**/market-making.example.yml +# Local quoter-bot configuration (examples remain trackable) +**/quoter-bot.yaml +**/quoter-bot.yml +!**/quoter-bot.example.yaml +!**/quoter-bot.example.yml # Testing diff --git a/CLAUDE.md b/CLAUDE.md index 3826ff22..5de65d13 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -32,7 +32,7 @@ Agent conventions: - **JSDoc public surface**: Every externally facing function and public method changed in TypeScript requires substantive JSDoc covering its applicable parameters, return value, failures, and side effects. Before completion, follow `.agents/skills/build-jsdoc/SKILL.md` and run - `pnpm --filter @morpho-org/market-making-bot run jsdoc:build`; `.claude/skills` must be the real + `pnpm --filter @morpho-org/quoter-bot run jsdoc:build`; `.claude/skills` must be the real symlink `../.agents/skills`, and independent checks must continue to run concurrently through `Promise.all` where possible. - **Utility isolation**: Utility functions must live in a different file from every file containing @@ -157,7 +157,7 @@ This is a **pnpm workspaces monorepo** housing off-chain Morpho curator bots: Each bot owns its own operator surface — `README.md`, `Dockerfile`, `docker-compose.yml`, and `scripts/deploy-railway.ts` — so it ships as its own image and deploys independently. `bots/blue-liquidation` and `bots/midnight-liquidation` are the live - liquidators; `bots/market-making` is the Midnight maker bot (setup checks, position bootstrap, + liquidators; `bots/quoter-bot` is the Midnight maker bot (setup checks, position bootstrap, ladder quoting, combined monitoring); `bots/midnight-crossed-books` resolves crossed Midnight books; `bots/kill-switch` is a proposal bot (docs only). - `/packages/` — shared libraries: `@repo/bot-kit` (the shared bot runtime — viem @@ -244,7 +244,7 @@ All commit messages, PR titles, and Linear ticket titles use the same format: | Bot | Scope | | ---------------------- | ------------------------ | | blue-liquidation | `blue-liquidation` | -| market-making | `market-making` | +| quoter-bot | `quoter-bot` | | midnight-crossed-books | `midnight-crossed-books` | | midnight-liquidation | `midnight-liquidation` | diff --git a/bots/blue-liquidation/test/fork/harness.ts b/bots/blue-liquidation/test/fork/harness.ts index 3f7eea8c..1e9aa097 100644 --- a/bots/blue-liquidation/test/fork/harness.ts +++ b/bots/blue-liquidation/test/fork/harness.ts @@ -165,7 +165,7 @@ async function waitForRpc(url: string, timeoutMs = 30_000): Promise { // Anvil port registry — vitest runs test FILES IN PARALLEL (bun's runner was serial, so fixed ports // used to be safe within a bot only). Every fork suite in the repo must claim a distinct port: // 8545 bots/blue-liquidation fork/liquidation -// 8546 bots/market-making e2e/setup-check +// 8546 bots/quoter-bot e2e/setup-check // 8547 bots/midnight-liquidation fork/liquidation // 8548 bots/midnight-liquidation fork/queue /** diff --git a/bots/market-making/src/application/market-making/market-making-monitor-halted.error.ts b/bots/market-making/src/application/market-making/market-making-monitor-halted.error.ts deleted file mode 100644 index beec22a9..00000000 --- a/bots/market-making/src/application/market-making/market-making-monitor-halted.error.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { MarketMakingMonitorReport } from './market-making.service' - -/** Expected CLI failure carrying a sanitized halted combined-monitor report. */ -export class MarketMakingMonitorHaltedError extends Error { - readonly name = 'MarketMakingMonitorHaltedError' - readonly code = 'MARKET_MAKING_MONITOR_HALTED' - readonly kind = 'safety-halt' - - /** - * Creates a combined monitor halt from its operator-safe terminal report. - * @param report - Complete terminal outcomes for setup, bootstrap, and ladder monitoring. - */ - constructor(readonly report: MarketMakingMonitorReport) { - super('Market making monitor halted for safety') - } -} diff --git a/bots/midnight-liquidation/test/fork/harness.ts b/bots/midnight-liquidation/test/fork/harness.ts index 3b4adc04..592e9bdc 100644 --- a/bots/midnight-liquidation/test/fork/harness.ts +++ b/bots/midnight-liquidation/test/fork/harness.ts @@ -115,7 +115,7 @@ async function waitForRpc(url: string, timeoutMs = 30_000): Promise { // Anvil port registry — vitest runs test FILES IN PARALLEL (bun's runner was serial, so fixed ports // used to be safe within a bot only). Every fork suite in the repo must claim a distinct port: // 8545 bots/blue-liquidation fork/liquidation -// 8546 bots/market-making e2e/setup-check +// 8546 bots/quoter-bot e2e/setup-check // 8547 bots/midnight-liquidation fork/liquidation // 8548 bots/midnight-liquidation fork/queue /** diff --git a/bots/market-making/.env.example b/bots/quoter-bot/.env.example similarity index 99% rename from bots/market-making/.env.example rename to bots/quoter-bot/.env.example index 2d4f2d41..ba9bf3e0 100644 --- a/bots/market-making/.env.example +++ b/bots/quoter-bot/.env.example @@ -33,7 +33,7 @@ TRANSACTION_RECEIPT_TIMEOUT_MS=180000 # logship.misconfigured error and ships nothing. BETTERSTACK_SOURCE_TOKEN= BETTERSTACK_INGESTING_HOST= -# Optional Better Stack heartbeat URL. Heartbeat failures never interrupt market making. +# Optional Better Stack heartbeat URL. Heartbeat failures never interrupt quoter-bot. BETTERSTACK_HEARTBEAT_URL= # BOOTSTRAP_MARKETS replaces the YAML list. Every integer property must be a quoted decimal string. BOOTSTRAP_MARKETS=[{"marketId":"0x5555555555555555555555555555555555555555555555555555555555555555","targetRate":{"strategy":"variable_rate_avg"},"creditTarget":"10000000000","acceptanceAssets":"100000000","offerSize":"500000000","premiumBps":"-50","maximumMarketExposure":"20000000000","maximumTotalExposure":"30000000000","minimumRateBps":"200","maximumRateBps":"800","autoRefill":false}] diff --git a/bots/market-making/Dockerfile b/bots/quoter-bot/Dockerfile similarity index 89% rename from bots/market-making/Dockerfile rename to bots/quoter-bot/Dockerfile index b5ea436b..3f688964 100644 --- a/bots/market-making/Dockerfile +++ b/bots/quoter-bot/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -# Image for the market-making bot. The build context MUST be the repository root so workspace +# Image for the quoter-bot bot. The build context MUST be the repository root so workspace # packages resolve. Node only: pnpm installs, esbuild bundles, node runs. FROM node:24.14.1-slim ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 @@ -22,5 +22,5 @@ COPY --chown=node:node bots ./bots RUN pnpm install --frozen-lockfile RUN pnpm -r --if-present run build -WORKDIR /repo/bots/market-making +WORKDIR /repo/bots/quoter-bot CMD ["node", "scripts/railway-entrypoint.mjs", "start", "--verbose"] diff --git a/bots/market-making/README.md b/bots/quoter-bot/README.md similarity index 93% rename from bots/market-making/README.md rename to bots/quoter-bot/README.md index d5005d1a..ce70c64d 100644 --- a/bots/market-making/README.md +++ b/bots/quoter-bot/README.md @@ -1,7 +1,7 @@ -# Market making bot +# Quoter bot > [!WARNING] -> The market-making bot is a work in progress, must not be used yet, and is expected to be ready for use around August 12, 2026. +> The quoter-bot bot is a work in progress, must not be used yet, and is expected to be ready for use around August 12, 2026. The bot validates its Base and Midnight setup, bootstraps target lending positions, maintains two-sided rate ladders, and provides explicit recovery commands. Start with read-only mode to inspect @@ -15,7 +15,7 @@ structure. Run the stateless parameter playground locally from the repository root: ```sh -pnpm run market-making:playground +pnpm run quoter-bot:playground ``` The launcher performs a frozen-lockfile dependency check before every build, then prints the local @@ -23,7 +23,7 @@ server URL after building the browser artifact. For a production-equivalent build without starting a server, run: ```sh -pnpm --filter @morpho-org/market-making-bot run playground:build +pnpm --filter @morpho-org/quoter-bot run playground:build ``` After this pull request is merged to `main`, relevant playground, browser-safe bot-kit, package, lock, @@ -31,28 +31,28 @@ or deployment-workflow changes deploy through GitHub Actions to . Repository Pages settings must use **GitHub Actions** as the publishing source; the workflow intentionally cannot change that repository setting with its least-privilege token. The Pages site is not live until that post-merge workflow completes -successfully; check the repository's **Deploy market-making playground to GitHub Pages** workflow and +successfully; check the repository's **Deploy quoter-bot playground to GitHub Pages** workflow and its `github-pages` environment for deployment status. ## Run ```sh -pnpm --filter @morpho-org/market-making-bot run start -- setup-check +pnpm --filter @morpho-org/quoter-bot run start -- setup-check # Address-only setup inspection: MAKER_PRIVATE_KEY may be omitted. -pnpm --filter @morpho-org/market-making-bot run start -- --readonly setup-check +pnpm --filter @morpho-org/quoter-bot run start -- --readonly setup-check # Explicit signer sources (root options precede the command). -pnpm --filter @morpho-org/market-making-bot run start -- --private-key '' setup-check -pnpm --filter @morpho-org/market-making-bot run start -- --keystore ./maker.json --interactive setup-check -pnpm --filter @morpho-org/market-making-bot run start -- --aws setup-check +pnpm --filter @morpho-org/quoter-bot run start -- --private-key '' setup-check +pnpm --filter @morpho-org/quoter-bot run start -- --keystore ./maker.json --interactive setup-check +pnpm --filter @morpho-org/quoter-bot run start -- --aws setup-check ``` For unattended keystore operation, provision `KEYSTORE_PASSWORD` separately through the deployment secret manager or process environment, then run the keystore command without an inline value: ```sh -pnpm --filter @morpho-org/market-making-bot run start -- --keystore ./maker.json setup-check +pnpm --filter @morpho-org/quoter-bot run start -- --keystore ./maker.json setup-check ``` `--private-key ` and `--password ` remain available for explicit automation, but they @@ -62,49 +62,49 @@ place secrets in argv, where process listings and shell history may expose them. ```sh # Repeat read-only readiness checks every minute until SIGINT/SIGTERM. -pnpm --filter @morpho-org/market-making-bot run start -- setup-check --monitor +pnpm --filter @morpho-org/quoter-bot run start -- setup-check --monitor # Emit compact JSON Lines for automation instead of the default human-readable output. -pnpm --filter @morpho-org/market-making-bot run start -- --json setup-check +pnpm --filter @morpho-org/quoter-bot run start -- --json setup-check # One live position-bootstrap cycle. -pnpm --filter @morpho-org/market-making-bot run start -- bootstrap +pnpm --filter @morpho-org/quoter-bot run start -- bootstrap # One address-only cycle that logs desired make operations without submitting them. -pnpm --filter @morpho-org/market-making-bot run start -- --readonly bootstrap +pnpm --filter @morpho-org/quoter-bot run start -- --readonly bootstrap # Repeat bootstrap every minute; SIGINT/SIGTERM drains the current cycle and removes owned offers. -pnpm --filter @morpho-org/market-making-bot run start -- bootstrap --monitor +pnpm --filter @morpho-org/quoter-bot run start -- bootstrap --monitor # Stream full safe diagnostics and emit publication/cancellation hashes as soon as submitted. -pnpm --filter @morpho-org/market-making-bot run start -- bootstrap --monitor --verbose +pnpm --filter @morpho-org/quoter-bot run start -- bootstrap --monitor --verbose # Exercise the complete monitor and cleanup lifecycle without signing or submitting. -pnpm --filter @morpho-org/market-making-bot run start -- --readonly bootstrap --monitor +pnpm --filter @morpho-org/quoter-bot run start -- --readonly bootstrap --monitor # Validate and continuously render ladder decisions without loading a private key or submitting. -pnpm --filter @morpho-org/market-making-bot run start -- ladder --monitor --verbose --readonly +pnpm --filter @morpho-org/quoter-bot run start -- ladder --monitor --verbose --readonly # Sign, broadcast, and confirm one ladder reconciliation cycle. -pnpm --filter @morpho-org/market-making-bot run start -- ladder +pnpm --filter @morpho-org/quoter-bot run start -- ladder # Continuously reconcile the live ladder and remove owned offers on SIGINT/SIGTERM. -pnpm --filter @morpho-org/market-making-bot run start -- ladder --monitor --verbose +pnpm --filter @morpho-org/quoter-bot run start -- ladder --monitor --verbose # Run setup checks, bootstrap, and ladder monitoring together until SIGINT/SIGTERM. -pnpm --filter @morpho-org/market-making-bot run start -- start --verbose +pnpm --filter @morpho-org/quoter-bot run start -- start --verbose # Exercise the same combined lifecycle without signing or submitting transactions. -pnpm --filter @morpho-org/market-making-bot run start -- --readonly start --verbose +pnpm --filter @morpho-org/quoter-bot run start -- --readonly start --verbose # Cancel every active offer group for the configured maker. -pnpm --filter @morpho-org/market-making-bot run start -- invalidate +pnpm --filter @morpho-org/quoter-bot run start -- invalidate # Cancel one explicit offer group, even when it has not been indexed by the API. -pnpm --filter @morpho-org/market-making-bot run start -- invalidate 0x<64-hex-characters> +pnpm --filter @morpho-org/quoter-bot run start -- invalidate 0x<64-hex-characters> # Preview the active groups that maker-wide invalidation would cancel. -pnpm --filter @morpho-org/market-making-bot run start -- invalidate --readonly +pnpm --filter @morpho-org/quoter-bot run start -- invalidate --readonly ``` Success exits zero and writes human-readable output to standard output. Add the root `--json` flag for @@ -112,7 +112,7 @@ compact JSON Lines suitable for automation. In JSON mode, ordinary commands emit a read-only writer command emits zero or more `readonly.make` records followed by its final cycle report. Consumers must parse stdout one line at a time rather than as one JSON document. Bigints are serialized as decimal strings. Failures always produce an explicit error on standard error and exit -non-zero; with `--json`, that error is one `market-making.error` JSON record with optional structured +non-zero; with `--json`, that error is one `quoter-bot.error` JSON record with optional structured details. Any failed check throws `SetupFailedError` and identifies the failed check names. The check is strictly read-only; remediation transaction descriptions are reported but never submitted. With `--readonly`, only private-key/maker agreement is reported as `not-required`; balance, allowance, @@ -187,7 +187,7 @@ immediately as `ladder.transaction-submitted` records. `start` requires at least one configured bootstrap market and one configured ladder market. It runs the readiness gate before constructing either writer, then launches setup monitoring, position bootstrap monitoring, and ladder monitoring concurrently. Cycle records are tagged with -`event: "market-making.cycle"` and their `workflow`; verbose transaction records retain the existing +`event: "quoter-bot.cycle"` and their `workflow`; verbose transaction records retain the existing bootstrap and ladder event names. The first halted, rejected, or unexpectedly stopped workflow aborts its peers, waits for both writer monitors to drain their in-flight cycles and cleanup owned offers, and emits one combined terminal report. Bootstrap and ladder reads remain concurrent, while @@ -240,13 +240,13 @@ Run the exact read-only monitor command first to inspect whether current cash/cr produces a lower side, a higher side, or both: ```sh -pnpm --filter @morpho-org/market-making-bot run start -- ladder --monitor --verbose --readonly +pnpm --filter @morpho-org/quoter-bot run start -- ladder --monitor --verbose --readonly ``` Version output remains available: ```sh -pnpm --filter @morpho-org/market-making-bot run start -- --version +pnpm --filter @morpho-org/quoter-bot run start -- --version ``` ## Deploy @@ -257,13 +257,13 @@ The package owns its production [Dockerfile](./Dockerfile), local repository root so pnpm can resolve every workspace dependency; the image builds the workspace and starts the combined setup, bootstrap, and ladder monitor as an unprivileged Node process. -A full deployment creates the `market-making` Railway service, selects the package Dockerfile, +A full deployment creates the `quoter-bot` Railway service, selects the package Dockerfile, provisions a persistent volume at `/state`, and writes the effective environment configuration through stdin so values never appear in process arguments or logs: ```sh RAILWAY_PROJECT_ID=... \ -pnpm --filter @morpho-org/market-making-bot run deploy:railway +pnpm --filter @morpho-org/quoter-bot run deploy:railway ``` Provide the required values from [`.env.example`](./.env.example) in the invoking environment. @@ -302,8 +302,8 @@ Configuration can come from environment variables, a YAML file, or both. YAML fi 1. `--config ` selects that exact `.yaml` or `.yml` file. Other path extensions and a missing, unreadable, empty, oversized, malformed, symlinked, or non-regular explicitly named file fail startup. Default-discovered symlinks are rejected as unreadable too. -2. Without `--config`, the CLI searches the process working directory from which `mm` was invoked. - It checks `market-making.yaml` first, then `market-making.yml`. If both exist, `.yaml` wins. +2. Without `--config`, the CLI searches the process working directory from which `quoter-bot` was invoked. + It checks `quoter-bot.yaml` first, then `quoter-bot.yml`. If both exist, `.yaml` wins. 3. If neither default file exists, environment-only startup remains supported. 4. Every supplied environment variable overrides the corresponding YAML value. CLI signer flags override environment and YAML signer selection. A higher-precedence signer selection discards @@ -317,19 +317,19 @@ source-safety checks run before overlay, then only the effective merged configuration is semantically validated, so replaced invalid values do not block startup while parser hazards in replaced sections still do. -Use [`market-making.example.yaml`](./market-making.example.yaml) as the complete YAML template and +Use [`quoter-bot.example.yaml`](./quoter-bot.example.yaml) as the complete YAML template and [`.env.example`](./.env.example) as the environment template. Default discovery never selects the example filename. ```sh # Explicit file; relative paths resolve from the invocation working directory. -pnpm --filter @morpho-org/market-making-bot run start -- --config ./market-making.yml setup-check +pnpm --filter @morpho-org/quoter-bot run start -- --config ./quoter-bot.yml setup-check # Default discovery in the current working directory. -pnpm --filter @morpho-org/market-making-bot run start -- setup-check +pnpm --filter @morpho-org/quoter-bot run start -- setup-check # Address-only mode works with either configuration source. -pnpm --filter @morpho-org/market-making-bot run start -- --readonly setup-check +pnpm --filter @morpho-org/quoter-bot run start -- --readonly setup-check ``` ### Environment variables @@ -366,7 +366,7 @@ unit; for six-decimal USDC, `101000000` is 101 USDC. No value is inferred from a | `LADDER_MARKETS` | `ladder` | Optional exact JSON array of ladder entries documented below; defaults to `[]` and replaces the complete YAML `ladder` list when supplied. | | `BETTERSTACK_SOURCE_TOKEN` | — | Optional Better Stack source token. Must be set together with `BETTERSTACK_INGESTING_HOST`; partial configuration emits `logship.misconfigured` and ships nothing. | | `BETTERSTACK_INGESTING_HOST` | — | Optional Better Stack ingest host, with or without an `https://` prefix. Must be set together with `BETTERSTACK_SOURCE_TOKEN`. | -| `BETTERSTACK_HEARTBEAT_URL` | — | Optional HTTP(S) heartbeat URL pinged at startup and once per minute. Invalid URLs and ping failures are reported safely and never interrupt market making. | +| `BETTERSTACK_HEARTBEAT_URL` | — | Optional HTTP(S) heartbeat URL pinged at startup and once per minute. Invalid URLs and ping failures are reported safely and never interrupt quoter-bot. | There is no separate Mempool endpoint or API-key field. Books and cursor-paginated maker offer groups are read through `MORPHO_API_BASE_URL`; `ROUTER_API_BASE_URL` is used only for the @@ -382,7 +382,7 @@ duplicate flag), so active positions, bootstrap offers, ladder quotes/offers, de submitted/confirmed transactions are available to the log source. Unset shipping variables are inert; partial configuration fails loud locally and does not enable verbose diagnostics. -Every record carries `bot: "market-making"`, `chainId: 8453`, and available Railway deployment +Every record carries `bot: "quoter-bot"`, `chainId: 8453`, and available Railway deployment context. Existing event names remain the top-level `event`, and the sanitized report fields remain searchable structured fields. Nested `status: "failed"`, `status: "halted"`, and `errorName` values are emitted at error level. Unexpected failures include only a sanitized `errorName`; private keys, @@ -391,11 +391,11 @@ messages are never added to observability records. Useful Better Stack source queries/filters include: -- lifecycle and restarts: `bot:market-making AND event:(bot.started OR bot.stopped)`; -- actions and monitor cycles: `bot:market-making AND event:*` plus `workflow`, `action`, or `status`; +- lifecycle and restarts: `bot:quoter-bot AND event:(bot.started OR bot.stopped)`; +- actions and monitor cycles: `bot:quoter-bot AND event:*` plus `workflow`, `action`, or `status`; - active state: filter/search `activePosition`, `activeOffers`, `offers`, `quotes`, or the verbose bootstrap/ladder event names; -- failures: `bot:market-making AND level:error`, optionally grouped by `event` and `errorName`. +- failures: `bot:quoter-bot AND level:error`, optionally grouped by `event` and `errorName`. `BETTERSTACK_HEARTBEAT_URL` is independent and optional. It starts with the process, stops during normal teardown, and cannot interrupt strategy execution. Create the log source, heartbeat, saved @@ -406,7 +406,7 @@ or claim a deployed dashboard URL. The root accepts exactly `chain`, `identity`, `contracts`, `apis`, `markets`, `setup`, `bootstrap`, and `ladder`; unknown keys at any level are rejected. Every supported key appears in -[`market-making.example.yaml`](./market-making.example.yaml). +[`quoter-bot.example.yaml`](./quoter-bot.example.yaml). - `chain`: `id`, `rpcUrl`, `archiveRpcUrl`. - `identity`: `makerAddress`, `keyStorageMethod`, `makerPrivateKey`, `keystorePath`, @@ -449,7 +449,7 @@ configured IDs plus bot-issued IDs from the maker-and-market-bound state file. P reserves the SDK-derived group ID, broadcasts only after that write succeeds, and then promotes the reservation to confirmed ownership. A failed broadcast removes its reservation; if confirmation storage fails after a successful broadcast, the reservation remains sufficient to recognize the group from fresh -provider data without claiming that an absent group is live. A same-market maker group absent from these +provider data without claiming that an absent group is live. A same-quoter group absent from these sources remains unknown, fails readiness, and requires an operator decision; market membership alone never permits reconciliation or hard-halt cancellation. The request timeout is an aggregate fetch/RPC bound and does not reveal endpoint details in failures. @@ -518,13 +518,13 @@ ladder: targetRate: { strategy: 'hardcoded', hardcodedRateBps: '400' } ``` -`mm setup-check --monitor` repeats non-overlapping read-only readiness observations every minute -until its shutdown signal or the first failed report. `mm bootstrap` first runs the same one-shot +`quoter-bot setup-check --monitor` repeats non-overlapping read-only readiness observations every minute +until its shutdown signal or the first failed report. `quoter-bot bootstrap` first runs the same one-shot readiness gate as `setup-check`, then executes exactly one position-bootstrap cycle and prints its -bigint-safe JSON result. `mm bootstrap --monitor` uses the same gate, repeats non-overlapping cycles -every minute, and performs owned-group cleanup after its shutdown signal. `mm bootstrap --verbose` +bigint-safe JSON result. `quoter-bot bootstrap --monitor` uses the same gate, repeats non-overlapping cycles +every minute, and performs owned-group cleanup after its shutdown signal. `quoter-bot bootstrap --verbose` adds safe rate, offer, transaction-hash, configuration, and before/after position diagnostics to -each result. `mm ladder --monitor` similarly repeats at the shortest configured ladder cadence, +each result. `quoter-bot ladder --monitor` similarly repeats at the shortest configured ladder cadence, streams cycles, and cleans active owned ladder groups after shutdown; `--verbose` adds safe configuration, rate, quote, transaction-hash, and before/after capacity diagnostics. Version output, setup monitoring, and invalid usage never start either writer. @@ -722,10 +722,10 @@ parser hazards still fail closed. ### Secrets and failure behavior -Do not commit real configuration. The repository ignores `market-making.yaml` and -`market-making.yml` while keeping the example trackable. Prefer environment variables for the maker +Do not commit real configuration. The repository ignores `quoter-bot.yaml` and +`quoter-bot.yml` while keeping the example trackable. Prefer environment variables for the maker private key and future credentials. If a local YAML file contains a secret, restrict access (for -example `chmod 600 market-making.yaml`). +example `chmod 600 quoter-bot.yaml`). Configuration errors contain stable field/reason metadata but never rejected values, URLs, private keys, parser snippets, or nested third-party errors. Explicit file failures are loud but do not echo @@ -757,7 +757,7 @@ workspaces, where it is fast), creates a fresh isolated build, and serves it on run test assertions or require Chromium: ```sh -pnpm run market-making:playground +pnpm run quoter-bot:playground ``` Open the exact URL printed by the command (default `http://127.0.0.1:4173`). Override the listener diff --git a/bots/market-making/docker-compose.yml b/bots/quoter-bot/docker-compose.yml similarity index 93% rename from bots/market-making/docker-compose.yml rename to bots/quoter-bot/docker-compose.yml index 1dda668d..b9c79094 100644 --- a/bots/market-making/docker-compose.yml +++ b/bots/quoter-bot/docker-compose.yml @@ -3,7 +3,7 @@ services: bot: build: context: ../.. - dockerfile: bots/market-making/Dockerfile + dockerfile: bots/quoter-bot/Dockerfile environment: CHAIN_ID: ${CHAIN_ID:-8453} RPC_URL: ${RPC_URL:?set RPC_URL} @@ -30,7 +30,7 @@ services: XDG_STATE_HOME: /state restart: unless-stopped volumes: - - market-making-state:/state + - quoter-bot-state:/state volumes: - market-making-state: + quoter-bot-state: diff --git a/bots/market-making/docs/architecture.md b/bots/quoter-bot/docs/architecture.md similarity index 90% rename from bots/market-making/docs/architecture.md rename to bots/quoter-bot/docs/architecture.md index 4cee7300..e6c439b6 100644 --- a/bots/market-making/docs/architecture.md +++ b/bots/quoter-bot/docs/architecture.md @@ -1,11 +1,11 @@ -# Market-making bot architecture +# Quoter bot architecture This document describes the package structure and implementation boundaries for contributors. For installation, configuration, strategy behavior, commands, and operational safety, see the [operator README](../README.md). -The implementation follows the market-maker design from -[TIB-2026-07-27](../../../docs/decisions/TIB-2026-07-27-midnight-market-making-bot.md) and the +The implementation follows the quoter design from +[TIB-2026-07-27](../../../docs/decisions/TIB-2026-07-27-midnight-quoter-bot.md) and the repository's [coding conventions](../../../docs/CONVENTIONS.md). ## Architectural boundaries @@ -23,7 +23,7 @@ The package uses a pragmatic hexagonal architecture: - `src/bootstrap.ts` is the manual composition root. It selects live or read-only adapters and wires shared lifecycle dependencies. - `src/infrastructure/cli/cli.ts` is the operator-facing adapter, - `src/infrastructure/cli/market-making-entrypoint.ts` maps application results to JSON Lines and + `src/infrastructure/cli/quoter-bot-entrypoint.ts` maps application results to JSON Lines and process exit codes, and `src/index.ts` only installs signal handling and starts the application. Dependencies point inward: infrastructure depends on application-owned interfaces and domain @@ -64,9 +64,9 @@ mutation port by emitting `readonly.make` records without loading a signer or mu Continuous bootstrap cycles never overlap. Shutdown waits for the current cycle and then calls the same make port to clean all strategy-owned bootstrap groups. -### Ladder market making +### Ladder quoter-bot -`LadderMarketMakerService` consumes the analogous `LadderPositionService`, +`LadderQuoterService` consumes the analogous `LadderPositionService`, `LadderReferenceRateService`, and `LadderMakeService` ports. The domain module validates ladder configuration, generates deterministic quote sets, and decides whether a live center must be recentered. The application service reconstructs the active quote, derives a complete desired quote @@ -89,8 +89,8 @@ exhaustive owned-group cleanup. ### Combined lifecycle -`MarketMakingService` supervises readiness, position bootstrap, and ladder monitoring as one -fail-together lifecycle. `serializeMarketMakingWrites()` wraps the two make ports in one shared queue, +`QuoterBotService` supervises readiness, position bootstrap, and ladder monitoring as one +fail-together lifecycle. `serializeQuoterBotWrites()` wraps the two make ports in one shared queue, so otherwise concurrent strategy reads cannot turn into signer-nonce or maker-book mutation races. The first rejected, halted, or unexpectedly stopped workflow aborts its peers. The supervisor then @@ -137,7 +137,7 @@ errors are translated into stable application outcomes before reaching the CLI. reports omit private keys, maker identity, endpoints, signatures, raw transactions, response bodies, provider payloads, and untrusted nested error text. -`runMarketMakingEntrypoint()` is the final boundary. It serializes bigint values as decimal strings, +`runQuoterBotEntrypoint()` is the final boundary. It serializes bigint values as decimal strings, writes one JSON value per line, emits sanitized handled reports on standard error, and maps success or failure to process exit code `0` or `1`. @@ -149,10 +149,10 @@ historical block and requires `anvil` on `PATH` plus an archive-capable `RPC_URL Run package-focused checks with: ```sh -pnpm --filter @morpho-org/market-making-bot exec vitest run -pnpm --filter @morpho-org/market-making-bot run test:e2e -pnpm --filter @morpho-org/market-making-bot run typecheck -pnpm --filter @morpho-org/market-making-bot run jsdoc:build +pnpm --filter @morpho-org/quoter-bot exec vitest run +pnpm --filter @morpho-org/quoter-bot run test:e2e +pnpm --filter @morpho-org/quoter-bot run typecheck +pnpm --filter @morpho-org/quoter-bot run jsdoc:build ``` Before committing or when performing full validation, follow the repository-level validation suite diff --git a/bots/market-making/package.json b/bots/quoter-bot/package.json similarity index 96% rename from bots/market-making/package.json rename to bots/quoter-bot/package.json index d1d41758..43ff5332 100644 --- a/bots/market-making/package.json +++ b/bots/quoter-bot/package.json @@ -1,10 +1,10 @@ { - "name": "@morpho-org/market-making-bot", + "name": "@morpho-org/quoter-bot", "version": "0.0.0", "private": true, "license": "Apache-2.0", "bin": { - "mm": "./dist/src/index.js" + "quoter-bot": "./dist/src/index.js" }, "type": "module", "scripts": { diff --git a/bots/market-making/playground/app.tsx b/bots/quoter-bot/playground/app.tsx similarity index 100% rename from bots/market-making/playground/app.tsx rename to bots/quoter-bot/playground/app.tsx diff --git a/bots/market-making/playground/collection-import.error.ts b/bots/quoter-bot/playground/collection-import.error.ts similarity index 100% rename from bots/market-making/playground/collection-import.error.ts rename to bots/quoter-bot/playground/collection-import.error.ts diff --git a/bots/market-making/playground/collection-validation.error.ts b/bots/quoter-bot/playground/collection-validation.error.ts similarity index 100% rename from bots/market-making/playground/collection-validation.error.ts rename to bots/quoter-bot/playground/collection-validation.error.ts diff --git a/bots/market-making/playground/field-visibility.utils.ts b/bots/quoter-bot/playground/field-visibility.utils.ts similarity index 100% rename from bots/market-making/playground/field-visibility.utils.ts rename to bots/quoter-bot/playground/field-visibility.utils.ts diff --git a/bots/market-making/playground/fragment-codec.error.ts b/bots/quoter-bot/playground/fragment-codec.error.ts similarity index 100% rename from bots/market-making/playground/fragment-codec.error.ts rename to bots/quoter-bot/playground/fragment-codec.error.ts diff --git a/bots/market-making/playground/index.html b/bots/quoter-bot/playground/index.html similarity index 100% rename from bots/market-making/playground/index.html rename to bots/quoter-bot/playground/index.html diff --git a/bots/market-making/playground/model.ts b/bots/quoter-bot/playground/model.ts similarity index 100% rename from bots/market-making/playground/model.ts rename to bots/quoter-bot/playground/model.ts diff --git a/bots/market-making/playground/playground-error.utils.ts b/bots/quoter-bot/playground/playground-error.utils.ts similarity index 100% rename from bots/market-making/playground/playground-error.utils.ts rename to bots/quoter-bot/playground/playground-error.utils.ts diff --git a/bots/market-making/playground/playground-initialization.error.ts b/bots/quoter-bot/playground/playground-initialization.error.ts similarity index 100% rename from bots/market-making/playground/playground-initialization.error.ts rename to bots/quoter-bot/playground/playground-initialization.error.ts diff --git a/bots/market-making/playground/preview-generation.error.ts b/bots/quoter-bot/playground/preview-generation.error.ts similarity index 100% rename from bots/market-making/playground/preview-generation.error.ts rename to bots/quoter-bot/playground/preview-generation.error.ts diff --git a/bots/market-making/playground/strict-json.error.ts b/bots/quoter-bot/playground/strict-json.error.ts similarity index 100% rename from bots/market-making/playground/strict-json.error.ts rename to bots/quoter-bot/playground/strict-json.error.ts diff --git a/bots/market-making/playground/styles.css b/bots/quoter-bot/playground/styles.css similarity index 100% rename from bots/market-making/playground/styles.css rename to bots/quoter-bot/playground/styles.css diff --git a/bots/market-making/market-making.example.yaml b/bots/quoter-bot/quoter-bot.example.yaml similarity index 98% rename from bots/market-making/market-making.example.yaml rename to bots/quoter-bot/quoter-bot.example.yaml index 7d6c82cd..5d39655d 100644 --- a/bots/market-making/market-making.example.yaml +++ b/bots/quoter-bot/quoter-bot.example.yaml @@ -1,4 +1,4 @@ -# Copy to market-making.yaml (preferred) or market-making.yml. +# Copy to quoter-bot.yaml (preferred) or quoter-bot.yml. # Never commit the real file. Prefer environment variables for secrets and chmod 600 the file. chain: id: 8453 diff --git a/bots/market-making/scripts/build.ts b/bots/quoter-bot/scripts/build.ts similarity index 100% rename from bots/market-making/scripts/build.ts rename to bots/quoter-bot/scripts/build.ts diff --git a/bots/market-making/scripts/bundle-failed.error.ts b/bots/quoter-bot/scripts/bundle-failed.error.ts similarity index 100% rename from bots/market-making/scripts/bundle-failed.error.ts rename to bots/quoter-bot/scripts/bundle-failed.error.ts diff --git a/bots/market-making/scripts/check-jsdoc.test.ts b/bots/quoter-bot/scripts/check-jsdoc.test.ts similarity index 100% rename from bots/market-making/scripts/check-jsdoc.test.ts rename to bots/quoter-bot/scripts/check-jsdoc.test.ts diff --git a/bots/market-making/scripts/check-jsdoc.ts b/bots/quoter-bot/scripts/check-jsdoc.ts similarity index 98% rename from bots/market-making/scripts/check-jsdoc.ts rename to bots/quoter-bot/scripts/check-jsdoc.ts index 968ff5d4..8dcc7845 100644 --- a/bots/market-making/scripts/check-jsdoc.ts +++ b/bots/quoter-bot/scripts/check-jsdoc.ts @@ -300,8 +300,8 @@ export const inspectJSDocSource = (file: string, source: string): JSDocInspectio const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..') /** - * Discovers the TypeScript files that define the documented market-making surface. - * @param root - Absolute market-making package directory to scan. + * Discovers the TypeScript files that define the documented quoter-bot surface. + * @param root - Absolute quoter-bot package directory to scan. * @returns Relevant source and checker files in deterministic package-relative order. * @remarks The scan is read-only and excludes the executable entrypoint and test files. */ diff --git a/bots/market-making/scripts/deploy-railway.ts b/bots/quoter-bot/scripts/deploy-railway.ts similarity index 97% rename from bots/market-making/scripts/deploy-railway.ts rename to bots/quoter-bot/scripts/deploy-railway.ts index fa04f9d3..d29e913d 100644 --- a/bots/market-making/scripts/deploy-railway.ts +++ b/bots/quoter-bot/scripts/deploy-railway.ts @@ -1,5 +1,5 @@ /** - * Reproducible Railway provisioning and deployment for the market-making bot. + * Reproducible Railway provisioning and deployment for the quoter-bot bot. * * A full run creates the service, configures its package-owned Dockerfile, and uploads runtime * variables through stdin. CI sets DEPLOY_ONLY=true to re-ship the already-provisioned service using @@ -24,8 +24,8 @@ import { synchronizedOptionalRailwayVariables } from './railway.utils' -const SERVICE = 'market-making' -const DOCKERFILE_PATH = 'bots/market-making/Dockerfile' +const SERVICE = 'quoter-bot' +const DOCKERFILE_PATH = 'bots/quoter-bot/Dockerfile' const STATE_MOUNT_PATH = '/state' const REPO_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..', '..') const ENVIRONMENT = process.env.RAILWAY_ENVIRONMENT?.trim() || 'production' @@ -224,7 +224,7 @@ const latestDeploymentJson = async () => { } const startDeployment = async () => { - const message = `deploy market-making ${ENVIRONMENT}` + const message = `deploy quoter-bot ${ENVIRONMENT}` const { error } = await tryCatch( $({ cwd: REPO_ROOT diff --git a/bots/market-making/scripts/js-doc-validation.error.ts b/bots/quoter-bot/scripts/js-doc-validation.error.ts similarity index 100% rename from bots/market-making/scripts/js-doc-validation.error.ts rename to bots/quoter-bot/scripts/js-doc-validation.error.ts diff --git a/bots/market-making/scripts/playground-atomic-publish.mjs b/bots/quoter-bot/scripts/playground-atomic-publish.mjs similarity index 100% rename from bots/market-making/scripts/playground-atomic-publish.mjs rename to bots/quoter-bot/scripts/playground-atomic-publish.mjs diff --git a/bots/market-making/scripts/playground-atomic-publish.test.mjs b/bots/quoter-bot/scripts/playground-atomic-publish.test.mjs similarity index 100% rename from bots/market-making/scripts/playground-atomic-publish.test.mjs rename to bots/quoter-bot/scripts/playground-atomic-publish.test.mjs diff --git a/bots/market-making/scripts/playground-build-arguments.d.mts b/bots/quoter-bot/scripts/playground-build-arguments.d.mts similarity index 100% rename from bots/market-making/scripts/playground-build-arguments.d.mts rename to bots/quoter-bot/scripts/playground-build-arguments.d.mts diff --git a/bots/market-making/scripts/playground-build-arguments.mjs b/bots/quoter-bot/scripts/playground-build-arguments.mjs similarity index 100% rename from bots/market-making/scripts/playground-build-arguments.mjs rename to bots/quoter-bot/scripts/playground-build-arguments.mjs diff --git a/bots/market-making/scripts/playground-build.mjs b/bots/quoter-bot/scripts/playground-build.mjs similarity index 96% rename from bots/market-making/scripts/playground-build.mjs rename to bots/quoter-bot/scripts/playground-build.mjs index 5f4a2dd1..0878cf06 100644 --- a/bots/market-making/scripts/playground-build.mjs +++ b/bots/quoter-bot/scripts/playground-build.mjs @@ -16,9 +16,9 @@ import { revalidateCanonicalPathIdentity } from './playground-path-safety.mjs' -export const TEMPORARY_BUILD_PREFIX = 'market-making-playground-dist-' -export const CANONICAL_STAGING_PREFIX = 'market-making-playground-staging-' -export const BUILD_OUTPUT_KIND = 'market-making-playground-build' +export const TEMPORARY_BUILD_PREFIX = 'quoter-bot-playground-dist-' +export const CANONICAL_STAGING_PREFIX = 'quoter-bot-playground-staging-' +export const BUILD_OUTPUT_KIND = 'quoter-bot-playground-build' const packageRoot = fileURLToPath(new URL('..', import.meta.url)) const repoRoot = fileURLToPath(new URL('../../..', import.meta.url)) diff --git a/bots/market-making/scripts/playground-build.test.mjs b/bots/quoter-bot/scripts/playground-build.test.mjs similarity index 89% rename from bots/market-making/scripts/playground-build.test.mjs rename to bots/quoter-bot/scripts/playground-build.test.mjs index 207b0ec0..555db257 100644 --- a/bots/market-making/scripts/playground-build.test.mjs +++ b/bots/quoter-bot/scripts/playground-build.test.mjs @@ -37,13 +37,13 @@ const makeCanonicalChain = async () => { const container = await mkdtemp(join(tmpdir(), 'playground-path-chain-')) owned.add(container) const repoRoot = join(container, 'repo') - const packageRoot = join(repoRoot, 'bots', 'market-making') + const packageRoot = join(repoRoot, 'bots', 'quoter-bot') const playground = join(packageRoot, 'playground') await mkdir(playground, { recursive: true }) return { container, packageRoot, playground, repoRoot } } const makeFakeVite = async source => { - const root = await mkdtemp(join(tmpdir(), 'market-making-fake-vite-')) + const root = await mkdtemp(join(tmpdir(), 'quoter-bot-fake-vite-')) owned.add(root) const executable = join(root, 'vite') await writeFile(executable, `#!/usr/bin/env node\n${source}`) @@ -114,7 +114,7 @@ const { tmpdir } = require('node:os') const { basename, dirname } = require('node:path') const outdir = process.argv[process.argv.indexOf('--outDir') + 1] if (dirname(outdir) !== tmpdir()) throw new Error('not under OS temp') -if (!basename(outdir).startsWith('market-making-playground-dist-')) throw new Error('wrong prefix') +if (!basename(outdir).startsWith('quoter-bot-playground-dist-')) throw new Error('wrong prefix') writeFileSync(outdir + '/index.html', '') writeFileSync(outdir + '/index.js', 'globalThis.temporary = true') `) @@ -122,10 +122,10 @@ writeFileSync(outdir + '/index.js', 'globalThis.temporary = true') assert.equal(result.code, 0, result.stderr) const record = outputRecord(result.stdout) assert.deepEqual(Object.keys(record).sort(), ['kind', 'mode', 'path']) - assert.equal(record.kind, 'market-making-playground-build') + assert.equal(record.kind, 'quoter-bot-playground-build') assert.equal(record.mode, 'temporary') assert.equal(dirname(record.path), tmpdir()) - assert.match(basename(record.path), /^market-making-playground-dist-/) + assert.match(basename(record.path), /^quoter-bot-playground-dist-/) assert.equal((await lstat(record.path)).isDirectory(), true) if (process.platform !== 'win32') assert.equal((await lstat(record.path)).mode & 0o777, 0o700) assert.match(await readFile(join(record.path, 'index.html'), 'utf8'), /index\.[0-9a-f]{12}\.js/) @@ -134,7 +134,7 @@ writeFileSync(outdir + '/index.js', 'globalThis.temporary = true') test('failed temporary build removes its internally-created partial output', async () => { const before = new Set( - (await readdir(tmpdir())).filter(name => name.startsWith('market-making-playground-dist-')) + (await readdir(tmpdir())).filter(name => name.startsWith('quoter-bot-playground-dist-')) ) const fakeVite = await makeFakeVite(` const { writeFileSync } = require('node:fs') @@ -146,7 +146,7 @@ process.exit(23) assert.notEqual(result.code, 0) assert.match(result.stderr, /Production playground build failed with exit code 23/) const after = (await readdir(tmpdir())).filter( - name => name.startsWith('market-making-playground-dist-') && !before.has(name) + name => name.startsWith('quoter-bot-playground-dist-') && !before.has(name) ) assert.deepEqual(after, []) }) @@ -160,7 +160,7 @@ const { tmpdir } = require('node:os') const { basename, dirname } = require('node:path') const outdir = process.argv[process.argv.indexOf('--outDir') + 1] if (dirname(outdir) !== tmpdir()) throw new Error('canonical staging not in OS temp') -if (!basename(outdir).startsWith('market-making-playground-staging-')) throw new Error('wrong staging prefix') +if (!basename(outdir).startsWith('quoter-bot-playground-staging-')) throw new Error('wrong staging prefix') writeFileSync(outdir + '/index.html', '') writeFileSync(outdir + '/index.css', 'body { color: red }') writeFileSync(outdir + '/index.js', 'globalThis.built = true') @@ -183,7 +183,7 @@ test('failed canonical build preserves the prior index and removes OS-temp stagi await writeFile(join(canonical, 'index.html'), '

prior artifact

') const beforeIndex = await readFile(join(canonical, 'index.html')) const beforeTemp = new Set( - (await readdir(tmpdir())).filter(name => name.startsWith('market-making-playground-staging-')) + (await readdir(tmpdir())).filter(name => name.startsWith('quoter-bot-playground-staging-')) ) const fakeVite = await makeFakeVite(` const { writeFileSync } = require('node:fs') @@ -197,7 +197,7 @@ process.exit(29) assert.deepEqual(await readFile(join(canonical, 'index.html')), beforeIndex) assert.deepEqual( (await readdir(tmpdir())).filter( - name => name.startsWith('market-making-playground-staging-') && !beforeTemp.has(name) + name => name.startsWith('quoter-bot-playground-staging-') && !beforeTemp.has(name) ), [] ) @@ -213,12 +213,12 @@ test('canonical path identity captures and revalidates the real repo/package/pla }) test('canonical path identity rejects static symlinks in every repo descendant', async () => { - for (const component of ['bots', 'market-making', 'playground']) { + for (const component of ['bots', 'quoter-bot', 'playground']) { const chain = await makeCanonicalChain() const path = component === 'bots' ? join(chain.repoRoot, 'bots') - : component === 'market-making' + : component === 'quoter-bot' ? chain.packageRoot : chain.playground const displaced = `${path}-real` @@ -236,8 +236,8 @@ test('canonical path identity rejects a symlink ancestor above the repository ro await assert.rejects( captureCanonicalPathIdentity({ repoRoot: join(linkedContainer, 'repo'), - packageRoot: join(linkedContainer, 'repo', 'bots', 'market-making'), - playground: join(linkedContainer, 'repo', 'bots', 'market-making', 'playground') + packageRoot: join(linkedContainer, 'repo', 'bots', 'quoter-bot'), + playground: join(linkedContainer, 'repo', 'bots', 'quoter-bot', 'playground') }), /symlink ancestor/ ) diff --git a/bots/market-making/scripts/playground-path-safety.mjs b/bots/quoter-bot/scripts/playground-path-safety.mjs similarity index 100% rename from bots/market-making/scripts/playground-path-safety.mjs rename to bots/quoter-bot/scripts/playground-path-safety.mjs diff --git a/bots/market-making/scripts/playground-process.mjs b/bots/quoter-bot/scripts/playground-process.mjs similarity index 100% rename from bots/market-making/scripts/playground-process.mjs rename to bots/quoter-bot/scripts/playground-process.mjs diff --git a/bots/market-making/scripts/playground-process.test.mjs b/bots/quoter-bot/scripts/playground-process.test.mjs similarity index 100% rename from bots/market-making/scripts/playground-process.test.mjs rename to bots/quoter-bot/scripts/playground-process.test.mjs diff --git a/bots/market-making/scripts/playground-serve-support.mjs b/bots/quoter-bot/scripts/playground-serve-support.mjs similarity index 100% rename from bots/market-making/scripts/playground-serve-support.mjs rename to bots/quoter-bot/scripts/playground-serve-support.mjs diff --git a/bots/market-making/scripts/playground-serve.mjs b/bots/quoter-bot/scripts/playground-serve.mjs similarity index 100% rename from bots/market-making/scripts/playground-serve.mjs rename to bots/quoter-bot/scripts/playground-serve.mjs diff --git a/bots/market-making/scripts/playground-serve.test.mjs b/bots/quoter-bot/scripts/playground-serve.test.mjs similarity index 96% rename from bots/market-making/scripts/playground-serve.test.mjs rename to bots/quoter-bot/scripts/playground-serve.test.mjs index e872d80c..32f990ae 100644 --- a/bots/market-making/scripts/playground-serve.test.mjs +++ b/bots/quoter-bot/scripts/playground-serve.test.mjs @@ -134,7 +134,7 @@ test('serve options accept only loopback hosts and normalize bracketed IPv6', () test('a frozen install runs unconditionally and resolves partial workspace dependencies', async () => { const repoRoot = await temporaryDirectory('playground-install-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') const bin = join(repoRoot, 'bin') const log = join(repoRoot, 'install.json') await writeResolvableDependencies(packageRoot, ['viem']) @@ -157,7 +157,7 @@ test('a frozen install runs unconditionally and resolves partial workspace depen test('installed package dependencies still run the fast frozen lockfile check', async () => { const repoRoot = await temporaryDirectory('playground-installed-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') await writeResolvableDependencies(packageRoot) const calls = [] @@ -175,7 +175,7 @@ test('installed package dependencies still run the fast frozen lockfile check', ) }) -test('declared market-making package bin retains its original tracked mode', async () => { +test('declared quoter-bot package bin retains its original tracked mode', async () => { const { stdout } = await execFileAsync('git', ['ls-files', '--stage', '--', 'src/index.ts'], { cwd: root }) @@ -188,7 +188,7 @@ for (const [platform, originalMode] of [ ]) { test(`frozen launcher install restores package bin mode ${originalMode.toString(8)} and content (${platform})`, async () => { const repoRoot = await temporaryDirectory(`playground-clean-install-${platform}-`) - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') const entrypoint = join(packageRoot, 'src/index.ts') const executable = join(repoRoot, 'fake-pnpm') const source = 'console.log("package bin content must stay unchanged")\n' @@ -196,7 +196,7 @@ for (const [platform, originalMode] of [ await mkdir(join(packageRoot, 'src'), { recursive: true }) await writeFile( join(packageRoot, 'package.json'), - JSON.stringify({ type: 'module', bin: { mm: './src/index.ts' } }) + JSON.stringify({ type: 'module', bin: { 'quoter-bot': './src/index.ts' } }) ) await writeFile(entrypoint, source, { mode: originalMode }) await writeFile( @@ -243,7 +243,7 @@ for (const [platform, originalMode] of [ for (const outcome of ['failure', 'abort']) { test(`frozen install ${outcome} restores declared bin permissions and content`, async () => { const repoRoot = await temporaryDirectory(`playground-restore-${outcome}-`) - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') const entrypoint = join(packageRoot, 'src/index.ts') const source = 'unchanged through failed install\n' await writeResolvableDependencies(packageRoot) @@ -275,7 +275,7 @@ for (const outcome of ['failure', 'abort']) { test('permission restoration aggregates every failure with the install error', async () => { const repoRoot = await temporaryDirectory('playground-restore-errors-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') await writeResolvableDependencies(packageRoot) await mkdir(join(packageRoot, 'src'), { recursive: true }) await writeFile(join(repoRoot, 'package.json'), JSON.stringify({ workspaces: ['bots/*'] })) @@ -312,7 +312,7 @@ test('permission restoration aggregates every failure with the install error', a test('bin mode protection is non-destructive on Windows', async () => { const repoRoot = await temporaryDirectory('playground-windows-modes-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') await writeResolvableDependencies(packageRoot) await ensureFrozenDependencies({ repoRoot, @@ -327,7 +327,7 @@ test('bin mode protection is non-destructive on Windows', async () => { test('workspace bin discovery skips escaping and symlink targets', async () => { const repoRoot = await temporaryDirectory('playground-safe-bin-metadata-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') const outside = join(repoRoot, 'outside.js') await writeResolvableDependencies(packageRoot) await writeFile(outside, 'outside\n', { mode: 0o644 }) @@ -355,7 +355,7 @@ test('workspace bin discovery skips escaping and symlink targets', async () => { test('frozen install failures report the exact command and exit code', async () => { const repoRoot = await temporaryDirectory('playground-install-failure-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') const executable = join(repoRoot, 'pnpm-failure') await writeResolvableDependencies(packageRoot, []) await writeFile(executable, '#!/usr/bin/env node\nprocess.exit(23)\n', { mode: 0o755 }) @@ -368,7 +368,7 @@ test('frozen install failures report the exact command and exit code', async () test('successful install clearly lists dependencies that remain unresolved', async () => { const repoRoot = await temporaryDirectory('playground-unresolved-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') const executable = join(repoRoot, 'pnpm-noop') await writeResolvableDependencies(packageRoot, []) await writeFile(executable, '#!/usr/bin/env node\n', { mode: 0o755 }) @@ -383,7 +383,7 @@ test('successful install clearly lists dependencies that remain unresolved', asy test('frozen dependency install honors a pre-aborted signal without running', async () => { const repoRoot = await temporaryDirectory('playground-install-aborted-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') await writeResolvableDependencies(packageRoot) const controller = new AbortController() controller.abort(new Error('pre-aborted install')) @@ -404,7 +404,7 @@ test('frozen dependency install honors a pre-aborted signal without running', as test('signal during frozen install kills its descendant tree', { timeout: 10_000 }, async () => { const repoRoot = await temporaryDirectory('playground-install-signal-') - const packageRoot = join(repoRoot, 'bots/market-making') + const packageRoot = join(repoRoot, 'bots/quoter-bot') const pidFile = join(repoRoot, 'descendant.pid') await writeResolvableDependencies(packageRoot) const executable = await writeBlockingPnpm(repoRoot) @@ -442,14 +442,14 @@ test('fresh build preserves canonical dist, uses only temporary output, and vali join(packageRoot, 'scripts/playground-build.mjs'), '--temporary' ]) - const dist = await mkdtemp(join(tmpdir(), 'market-making-playground-dist-')) + const dist = await mkdtemp(join(tmpdir(), 'quoter-bot-playground-dist-')) temporaryDirectories.push(dist) await writeFile(join(dist, 'index.html'), 'fresh') return { code: 0, signal: null, stderr: '', - stdout: `${JSON.stringify({ kind: 'market-making-playground-build', mode: 'temporary', path: dist })}\n` + stdout: `${JSON.stringify({ kind: 'quoter-bot-playground-build', mode: 'temporary', path: dist })}\n` } } }) diff --git a/bots/market-making/scripts/playground-smoke-output-probe.mjs b/bots/quoter-bot/scripts/playground-smoke-output-probe.mjs similarity index 100% rename from bots/market-making/scripts/playground-smoke-output-probe.mjs rename to bots/quoter-bot/scripts/playground-smoke-output-probe.mjs diff --git a/bots/market-making/scripts/playground-smoke-persistence.error.mjs b/bots/quoter-bot/scripts/playground-smoke-persistence.error.mjs similarity index 100% rename from bots/market-making/scripts/playground-smoke-persistence.error.mjs rename to bots/quoter-bot/scripts/playground-smoke-persistence.error.mjs diff --git a/bots/market-making/scripts/playground-smoke-suite.test.mjs b/bots/quoter-bot/scripts/playground-smoke-suite.test.mjs similarity index 93% rename from bots/market-making/scripts/playground-smoke-suite.test.mjs rename to bots/quoter-bot/scripts/playground-smoke-suite.test.mjs index c4052a0c..692b621e 100644 --- a/bots/market-making/scripts/playground-smoke-suite.test.mjs +++ b/bots/quoter-bot/scripts/playground-smoke-suite.test.mjs @@ -12,29 +12,29 @@ const scriptsDirectory = fileURLToPath(new URL('.', import.meta.url)) const readJson = async path => JSON.parse(await readFile(path, 'utf8')) test('CI runs every Node playground suite after the Vitest unit suite', async () => { - const [rootPackage, marketMakingPackage, workflow, scriptNames] = await Promise.all([ + const [rootPackage, quoterBotPackage, workflow, scriptNames] = await Promise.all([ readJson(join(root, 'package.json')), - readJson(join(root, 'bots/market-making/package.json')), + readJson(join(root, 'bots/quoter-bot/package.json')), readFile(join(root, '.github/workflows/checks.yml'), 'utf8'), readdir(scriptsDirectory) ]) assert.equal( rootPackage.scripts.test, - 'vitest run && pnpm --filter @morpho-org/market-making-bot run playground:test' + 'vitest run && pnpm --filter @morpho-org/quoter-bot run playground:test' ) assert.equal( - marketMakingPackage.scripts['playground:test'], + quoterBotPackage.scripts['playground:test'], 'node --test scripts/playground-atomic-publish.test.mjs scripts/playground-build.test.mjs scripts/playground-process.test.mjs scripts/playground-serve.test.mjs scripts/playground-smoke-suite.test.mjs scripts/playground-smoke.test.mjs' ) assert.equal( - marketMakingPackage.scripts['playground:smoke:test'], + quoterBotPackage.scripts['playground:smoke:test'], 'node --test scripts/playground-smoke.browser.mjs' ) const unitStep = workflow.indexOf('- name: Run unit tests\n run: pnpm test') const browserStep = workflow.indexOf( - '- name: Run browser smoke tests\n run: pnpm --filter @morpho-org/market-making-bot run playground:smoke:test' + '- name: Run browser smoke tests\n run: pnpm --filter @morpho-org/quoter-bot run playground:smoke:test' ) assert.ok(unitStep >= 0) assert.ok(browserStep > unitStep, 'browser smoke command must run after the unit suite') @@ -43,7 +43,7 @@ test('CI runs every Node playground suite after the Vitest unit suite', async () name => /\.test\.mjs$/.test(name) && name !== 'playground-smoke-suite.test.mjs' ) for (const name of nodeTests) - assert.ok(marketMakingPackage.scripts['playground:test'].includes(name)) + assert.ok(quoterBotPackage.scripts['playground:test'].includes(name)) const nodeSources = await Promise.all( nodeTests.map(name => readFile(join(scriptsDirectory, name), 'utf8')) ) @@ -128,7 +128,7 @@ test('the root lint command explicitly checks the playground smoke mjs files', a assert.equal( rootPackage.scripts['lint:playground-smoke'], - 'oxlint --config bots/market-making/scripts/playground-smoke.oxlintrc.json bots/market-making/scripts/playground-smoke*.mjs' + 'oxlint --config bots/quoter-bot/scripts/playground-smoke.oxlintrc.json bots/quoter-bot/scripts/playground-smoke*.mjs' ) assert.match(rootPackage.scripts.lint, /pnpm run lint:playground-smoke/) assert.match(workflow, /- name: Run lint\n run: pnpm lint/) diff --git a/bots/market-making/scripts/playground-smoke-support.mjs b/bots/quoter-bot/scripts/playground-smoke-support.mjs similarity index 99% rename from bots/market-making/scripts/playground-smoke-support.mjs rename to bots/quoter-bot/scripts/playground-smoke-support.mjs index d6045a30..74c0755d 100644 --- a/bots/market-making/scripts/playground-smoke-support.mjs +++ b/bots/quoter-bot/scripts/playground-smoke-support.mjs @@ -1057,7 +1057,7 @@ export const prepareFreshDist = async ({ .flatMap(line => { try { const value = JSON.parse(line) - return value?.kind === 'market-making-playground-build' && value?.mode === 'temporary' + return value?.kind === 'quoter-bot-playground-build' && value?.mode === 'temporary' ? [value] : [] } catch { @@ -1075,7 +1075,7 @@ export const prepareFreshDist = async ({ metadata.isSymbolicLink() || !metadata.isDirectory() || dirname(actual) !== allowedRoot || - !/^market-making-playground-dist-.+/.test(basename(dist)) + !/^quoter-bot-playground-dist-.+/.test(basename(dist)) ) { throw new Error(`Fresh playground build reported an invalid temporary directory: ${dist}`) } diff --git a/bots/market-making/scripts/playground-smoke.browser.mjs b/bots/quoter-bot/scripts/playground-smoke.browser.mjs similarity index 98% rename from bots/market-making/scripts/playground-smoke.browser.mjs rename to bots/quoter-bot/scripts/playground-smoke.browser.mjs index 920968f8..149d5d6f 100644 --- a/bots/market-making/scripts/playground-smoke.browser.mjs +++ b/bots/quoter-bot/scripts/playground-smoke.browser.mjs @@ -286,8 +286,8 @@ os.execv(chromium, [chromium, *sys.argv[1:]]) assert.deepEqual( (await readdir(isolatedTmp)).filter( name => - name.startsWith('market-making-playground-dist-') || - name.startsWith('market-making-playground-') + name.startsWith('quoter-bot-playground-dist-') || + name.startsWith('quoter-bot-playground-') ), [], `smoke output (tail):\n${output().slice(-8000)}` @@ -370,8 +370,8 @@ chrome.on('close', (code, signal) => process.exitCode = signal ? 1 : (code ?? 0) assert.deepEqual( (await readdir(isolatedTmp)).filter( name => - name.startsWith('market-making-playground-dist-') || - name.startsWith('market-making-playground-') + name.startsWith('quoter-bot-playground-dist-') || + name.startsWith('quoter-bot-playground-') ), [] ) @@ -411,9 +411,7 @@ test( await assert.rejects(runSmokesConcurrently([sibling, failing]), /smoke failed with exit code 1/) await waitForIdentitiesGone(siblingTree) assert.deepEqual( - (await readdir(isolatedTmp)).filter(name => - name.startsWith('market-making-playground-dist-') - ), + (await readdir(isolatedTmp)).filter(name => name.startsWith('quoter-bot-playground-dist-')), [] ) } @@ -484,7 +482,7 @@ setInterval(() => {}, 1000) new RegExp(`Timed out after ${timeoutMs}ms during fresh playground build`) ) const recordedBuildTree = JSON.parse(await readFile(captureFile, 'utf8')) - assert.equal(recordedBuildTree.kind, 'market-making-playground-build-process-tree') + assert.equal(recordedBuildTree.kind, 'quoter-bot-playground-build-process-tree') assert.equal(recordedBuildTree.rootPid, recordedBuildTree.processes[0]?.pid) assert.ok( recordedBuildTree.processes.length >= 4, @@ -504,7 +502,7 @@ setInterval(() => {}, 1000) await waitForIdentitiesGone(captured) assert.deepEqual( - (await readdir(isolatedTmp)).filter(name => name.startsWith('market-making-playground-dist-')), + (await readdir(isolatedTmp)).filter(name => name.startsWith('quoter-bot-playground-dist-')), [] ) await Promise.all([rm(captureFile), rm(captureBarrierFile)]) @@ -705,7 +703,7 @@ test( assert.equal(new Set(smokeTemporaryRoots).size, 2) for (const [index, isolatedTmp] of isolatedRoots.entries()) { const resources = await readdir(isolatedTmp) - assert.ok(resources.some(name => name.startsWith('market-making-playground-dist-'))) + assert.ok(resources.some(name => name.startsWith('quoter-bot-playground-dist-'))) assert.ok(capturedTrees[index].length > 3) assert.ok( (await readdir(smokeTemporaryRoots[index])).some(name => name.startsWith('profile-')) diff --git a/bots/market-making/scripts/playground-smoke.mjs b/bots/quoter-bot/scripts/playground-smoke.mjs similarity index 99% rename from bots/market-making/scripts/playground-smoke.mjs rename to bots/quoter-bot/scripts/playground-smoke.mjs index dd5dd098..82fb4077 100644 --- a/bots/market-making/scripts/playground-smoke.mjs +++ b/bots/quoter-bot/scripts/playground-smoke.mjs @@ -126,7 +126,7 @@ const captureBuildTree = async build => { await writeFile( buildCaptureFile, JSON.stringify({ - kind: 'market-making-playground-build-process-tree', + kind: 'quoter-bot-playground-build-process-tree', processes: [root, ...descendants], rootPid: build.pid }) @@ -221,7 +221,7 @@ const createOwnedTempDirectory = async (prefix, parent = tmpdir()) => { try { const chromiumPath = await discoverChromium() const runTemporaryRoot = await createOwnedTempDirectory( - 'mm-smoke-', + 'quoter-bot-smoke-', process.platform === 'win32' ? tmpdir() : '/tmp' ) const preparedDist = await runBounded( diff --git a/bots/market-making/scripts/playground-smoke.oxlintrc.json b/bots/quoter-bot/scripts/playground-smoke.oxlintrc.json similarity index 100% rename from bots/market-making/scripts/playground-smoke.oxlintrc.json rename to bots/quoter-bot/scripts/playground-smoke.oxlintrc.json diff --git a/bots/market-making/scripts/playground-smoke.test.mjs b/bots/quoter-bot/scripts/playground-smoke.test.mjs similarity index 98% rename from bots/market-making/scripts/playground-smoke.test.mjs rename to bots/quoter-bot/scripts/playground-smoke.test.mjs index 69935a4b..3ff70a43 100644 --- a/bots/market-making/scripts/playground-smoke.test.mjs +++ b/bots/quoter-bot/scripts/playground-smoke.test.mjs @@ -988,7 +988,7 @@ child.on('close', () => process.exit(0)) await readFile(ready) descendantPid = Number(await readFile(descendantPidFile, 'utf8')) const temporaryDists = (await readdir(isolatedTmp)).filter(name => - name.startsWith('market-making-playground-dist-') + name.startsWith('quoter-bot-playground-dist-') ) assert.equal(temporaryDists.length, 1) }) @@ -1001,9 +1001,7 @@ child.on('close', () => process.exit(0)) assert.deepEqual(result, { code: null, signal }) assert.deepEqual( - (await readdir(isolatedTmp)).filter(name => - name.startsWith('market-making-playground-dist-') - ), + (await readdir(isolatedTmp)).filter(name => name.startsWith('quoter-bot-playground-dist-')), [] ) await waitForProcessesGone([buildPid, descendantPid]) @@ -1468,7 +1466,7 @@ test('failed fresh build preserves canonical output and does not invent a caller }) const reportTemporaryDist = async (html = 'fresh') => { - const dist = await temporaryDirectory('market-making-playground-dist-') + const dist = await temporaryDirectory('quoter-bot-playground-dist-') await writeFile(join(dist, 'index.html'), html) return { dist, @@ -1476,7 +1474,7 @@ const reportTemporaryDist = async (html = 'fresh') code: 0, signal: null, stderr: '', - stdout: `${JSON.stringify({ kind: 'market-making-playground-build', mode: 'temporary', path: dist })}\n` + stdout: `${JSON.stringify({ kind: 'quoter-bot-playground-build', mode: 'temporary', path: dist })}\n` } } } @@ -1485,7 +1483,7 @@ test('an ownership callback throw removes the unregistered temporary dist and pr const root = await temporaryDirectory('playground-dist-owner-throw-') const callbackError = new Error('deliberate ownership callback failure') const before = (await readdir(tmpdir())).filter(name => - name.startsWith('market-making-playground-dist-') + name.startsWith('quoter-bot-playground-dist-') ) await assert.rejects( @@ -1503,7 +1501,7 @@ test('an ownership callback throw removes the unregistered temporary dist and pr ) assert.deepEqual( - (await readdir(tmpdir())).filter(name => name.startsWith('market-making-playground-dist-')), + (await readdir(tmpdir())).filter(name => name.startsWith('quoter-bot-playground-dist-')), before ) }) @@ -1631,7 +1629,7 @@ test('fresh-dist parser rejects a caller-shaped path without touching it', async code: 0, signal: null, stderr: '', - stdout: `${JSON.stringify({ kind: 'market-making-playground-build', mode: 'temporary', path: callerPath })}\n` + stdout: `${JSON.stringify({ kind: 'quoter-bot-playground-build', mode: 'temporary', path: callerPath })}\n` }) }), /invalid temporary directory/ diff --git a/bots/market-making/scripts/railway-deployment.error.ts b/bots/quoter-bot/scripts/railway-deployment.error.ts similarity index 100% rename from bots/market-making/scripts/railway-deployment.error.ts rename to bots/quoter-bot/scripts/railway-deployment.error.ts diff --git a/bots/market-making/scripts/railway-entrypoint.mjs b/bots/quoter-bot/scripts/railway-entrypoint.mjs similarity index 100% rename from bots/market-making/scripts/railway-entrypoint.mjs rename to bots/quoter-bot/scripts/railway-entrypoint.mjs diff --git a/bots/market-making/scripts/railway.utils.ts b/bots/quoter-bot/scripts/railway.utils.ts similarity index 100% rename from bots/market-making/scripts/railway.utils.ts rename to bots/quoter-bot/scripts/railway.utils.ts diff --git a/bots/market-making/src/application/bootstrap/bootstrap-ownership-cleanup.error.ts b/bots/quoter-bot/src/application/bootstrap/bootstrap-ownership-cleanup.error.ts similarity index 100% rename from bots/market-making/src/application/bootstrap/bootstrap-ownership-cleanup.error.ts rename to bots/quoter-bot/src/application/bootstrap/bootstrap-ownership-cleanup.error.ts diff --git a/bots/market-making/src/application/bootstrap/position-bootstrap-halted.error.ts b/bots/quoter-bot/src/application/bootstrap/position-bootstrap-halted.error.ts similarity index 100% rename from bots/market-making/src/application/bootstrap/position-bootstrap-halted.error.ts rename to bots/quoter-bot/src/application/bootstrap/position-bootstrap-halted.error.ts diff --git a/bots/market-making/src/application/bootstrap/position-bootstrap-monitor-halted.error.ts b/bots/quoter-bot/src/application/bootstrap/position-bootstrap-monitor-halted.error.ts similarity index 100% rename from bots/market-making/src/application/bootstrap/position-bootstrap-monitor-halted.error.ts rename to bots/quoter-bot/src/application/bootstrap/position-bootstrap-monitor-halted.error.ts diff --git a/bots/market-making/src/application/bootstrap/position-bootstrap-verbose.ts b/bots/quoter-bot/src/application/bootstrap/position-bootstrap-verbose.ts similarity index 100% rename from bots/market-making/src/application/bootstrap/position-bootstrap-verbose.ts rename to bots/quoter-bot/src/application/bootstrap/position-bootstrap-verbose.ts diff --git a/bots/market-making/src/application/bootstrap/position-bootstrap.service.ts b/bots/quoter-bot/src/application/bootstrap/position-bootstrap.service.ts similarity index 100% rename from bots/market-making/src/application/bootstrap/position-bootstrap.service.ts rename to bots/quoter-bot/src/application/bootstrap/position-bootstrap.service.ts diff --git a/bots/market-making/src/application/invalidation/offer-invalidation-failed.error.ts b/bots/quoter-bot/src/application/invalidation/offer-invalidation-failed.error.ts similarity index 100% rename from bots/market-making/src/application/invalidation/offer-invalidation-failed.error.ts rename to bots/quoter-bot/src/application/invalidation/offer-invalidation-failed.error.ts diff --git a/bots/market-making/src/application/invalidation/offer-invalidation.service.ts b/bots/quoter-bot/src/application/invalidation/offer-invalidation.service.ts similarity index 100% rename from bots/market-making/src/application/invalidation/offer-invalidation.service.ts rename to bots/quoter-bot/src/application/invalidation/offer-invalidation.service.ts diff --git a/bots/market-making/src/application/ladder/ladder-cycle-halted.error.ts b/bots/quoter-bot/src/application/ladder/ladder-cycle-halted.error.ts similarity index 100% rename from bots/market-making/src/application/ladder/ladder-cycle-halted.error.ts rename to bots/quoter-bot/src/application/ladder/ladder-cycle-halted.error.ts diff --git a/bots/market-making/src/application/ladder/ladder-monitor-halted.error.ts b/bots/quoter-bot/src/application/ladder/ladder-monitor-halted.error.ts similarity index 87% rename from bots/market-making/src/application/ladder/ladder-monitor-halted.error.ts rename to bots/quoter-bot/src/application/ladder/ladder-monitor-halted.error.ts index 46c05e0f..71ff52c7 100644 --- a/bots/market-making/src/application/ladder/ladder-monitor-halted.error.ts +++ b/bots/quoter-bot/src/application/ladder/ladder-monitor-halted.error.ts @@ -1,4 +1,4 @@ -import type { LadderMonitorReport } from './ladder-market-maker.service' +import type { LadderMonitorReport } from './ladder-quoter.service' /** Expected CLI failure emitted when continuous ladder monitoring halts before a shutdown signal. */ export class LadderMonitorHaltedError extends Error { diff --git a/bots/market-making/src/application/ladder/ladder-ownership-cleanup.error.ts b/bots/quoter-bot/src/application/ladder/ladder-ownership-cleanup.error.ts similarity index 100% rename from bots/market-making/src/application/ladder/ladder-ownership-cleanup.error.ts rename to bots/quoter-bot/src/application/ladder/ladder-ownership-cleanup.error.ts diff --git a/bots/market-making/src/application/ladder/ladder-market-maker.service.ts b/bots/quoter-bot/src/application/ladder/ladder-quoter.service.ts similarity index 99% rename from bots/market-making/src/application/ladder/ladder-market-maker.service.ts rename to bots/quoter-bot/src/application/ladder/ladder-quoter.service.ts index 6c2ec3c3..23b752c4 100644 --- a/bots/market-making/src/application/ladder/ladder-market-maker.service.ts +++ b/bots/quoter-bot/src/application/ladder/ladder-quoter.service.ts @@ -17,8 +17,8 @@ import { generateLadder, shouldRecenter, validateLadderConfig } from '../../doma import { LadderConfigurationError } from '../../domain/ladder/ladder-configuration.error' import { LadderAdapterError } from '../../infrastructure/ladder/ladder-adapter.error' import { operatorErrorName } from '../operator-error-name.utils' -import { sameLadderQuoteSet } from './ladder-market-maker.utils' import { LadderOwnershipCleanupError } from './ladder-ownership-cleanup.error' +import { sameLadderQuoteSet } from './ladder-quoter.utils' /** Consumer-owned port for fresh position and capacity inputs for one ladder market. */ export interface LadderPositionService { @@ -170,7 +170,7 @@ export type LadderMonitorReport = { } /** Coordinates deterministic ladder decisions through fresh read and explicit make outcomes. */ -export class LadderMarketMakerService { +export class LadderQuoterService { /** * Creates one ladder application coordinator. * @param positions - Fresh position/capacity reader. diff --git a/bots/market-making/src/application/ladder/ladder-market-maker.utils.ts b/bots/quoter-bot/src/application/ladder/ladder-quoter.utils.ts similarity index 100% rename from bots/market-making/src/application/ladder/ladder-market-maker.utils.ts rename to bots/quoter-bot/src/application/ladder/ladder-quoter.utils.ts diff --git a/bots/market-making/src/application/ladder/ladder-verbose.ts b/bots/quoter-bot/src/application/ladder/ladder-verbose.ts similarity index 100% rename from bots/market-making/src/application/ladder/ladder-verbose.ts rename to bots/quoter-bot/src/application/ladder/ladder-verbose.ts diff --git a/bots/market-making/src/application/operator-error-name.utils.ts b/bots/quoter-bot/src/application/operator-error-name.utils.ts similarity index 98% rename from bots/market-making/src/application/operator-error-name.utils.ts rename to bots/quoter-bot/src/application/operator-error-name.utils.ts index 1cf2ed88..bbd76642 100644 --- a/bots/market-making/src/application/operator-error-name.utils.ts +++ b/bots/quoter-bot/src/application/operator-error-name.utils.ts @@ -21,7 +21,7 @@ const KNOWN_NAMES = [ 'SetupFailedError', 'SetupMonitorConfigurationError', 'SetupMonitorHaltedError', - 'MarketMakingMonitorHaltedError', + 'QuoterBotMonitorHaltedError', 'TypeError', 'RangeError', 'URIError' diff --git a/bots/quoter-bot/src/application/quoter-bot/quoter-bot-monitor-halted.error.ts b/bots/quoter-bot/src/application/quoter-bot/quoter-bot-monitor-halted.error.ts new file mode 100644 index 00000000..3f125086 --- /dev/null +++ b/bots/quoter-bot/src/application/quoter-bot/quoter-bot-monitor-halted.error.ts @@ -0,0 +1,16 @@ +import type { QuoterBotMonitorReport } from './quoter-bot.service' + +/** Expected CLI failure carrying a sanitized halted combined-monitor report. */ +export class QuoterBotMonitorHaltedError extends Error { + readonly name = 'QuoterBotMonitorHaltedError' + readonly code = 'QUOTER_BOT_MONITOR_HALTED' + readonly kind = 'safety-halt' + + /** + * Creates a combined monitor halt from its operator-safe terminal report. + * @param report - Complete terminal outcomes for setup, bootstrap, and ladder monitoring. + */ + constructor(readonly report: QuoterBotMonitorReport) { + super('Quoter bot monitor halted for safety') + } +} diff --git a/bots/market-making/src/application/market-making/market-making-mutation.utils.ts b/bots/quoter-bot/src/application/quoter-bot/quoter-bot-mutation.utils.ts similarity index 85% rename from bots/market-making/src/application/market-making/market-making-mutation.utils.ts rename to bots/quoter-bot/src/application/quoter-bot/quoter-bot-mutation.utils.ts index f58c48f0..01e86282 100644 --- a/bots/market-making/src/application/market-making/market-making-mutation.utils.ts +++ b/bots/quoter-bot/src/application/quoter-bot/quoter-bot-mutation.utils.ts @@ -1,9 +1,9 @@ import { createOperationQueue } from '@repo/monitoring' import type { BootstrapMakeService } from '../bootstrap/position-bootstrap.service' -import type { LadderMakeService } from '../ladder/ladder-market-maker.service' +import type { LadderMakeService } from '../ladder/ladder-quoter.service' -type MarketMakingMakeServices = { +type QuoterBotMakeServices = { bootstrap: BootstrapMakeService ladder: LadderMakeService } @@ -15,9 +15,9 @@ type MarketMakingMakeServices = { * @remarks Ladder state reads remain concurrent. Serializing writes across strategies prevents * separate wallet nonce managers from submitting concurrently and ensures shutdown cleanups drain. */ -export const serializeMarketMakingWrites = ( - services: MarketMakingMakeServices -): MarketMakingMakeServices => { +export const serializeQuoterBotWrites = ( + services: QuoterBotMakeServices +): QuoterBotMakeServices => { const enqueue = createOperationQueue() return { diff --git a/bots/market-making/src/application/market-making/market-making.service.ts b/bots/quoter-bot/src/application/quoter-bot/quoter-bot.service.ts similarity index 84% rename from bots/market-making/src/application/market-making/market-making.service.ts rename to bots/quoter-bot/src/application/quoter-bot/quoter-bot.service.ts index 11013e8c..d6870fc5 100644 --- a/bots/market-making/src/application/market-making/market-making.service.ts +++ b/bots/quoter-bot/src/application/quoter-bot/quoter-bot.service.ts @@ -4,14 +4,14 @@ import { createOperationQueue, cycleHasFailure } from '@repo/monitoring' import type { BootstrapTransactionSubmittedEvent } from '../bootstrap/position-bootstrap-verbose' import type { PositionBootstrapMonitorReport } from '../bootstrap/position-bootstrap.service' -import type { LadderMonitorReport } from '../ladder/ladder-market-maker.service' +import type { LadderMonitorReport } from '../ladder/ladder-quoter.service' import type { LadderTransactionSubmittedEvent } from '../ladder/ladder-verbose' import type { SetupCheckMonitorReport, SetupCheckReport } from '../setup/setup-check.service' import { operatorErrorName } from '../operator-error-name.utils' -/** Readiness monitor required by the combined market-making lifecycle. */ -export interface MarketMakingSetupMonitor { +/** Readiness monitor required by the combined quoter-bot lifecycle. */ +export interface QuoterBotSetupMonitor { /** * Monitors complete setup readiness until shutdown or the first failed check. * @param parameters - Shared shutdown signal and completed-cycle observer. @@ -24,8 +24,8 @@ export interface MarketMakingSetupMonitor { }): Promise } -/** Position-bootstrap monitor required by the combined market-making lifecycle. */ -export interface MarketMakingBootstrapMonitor { +/** Position-bootstrap monitor required by the combined quoter-bot lifecycle. */ +export interface QuoterBotBootstrapMonitor { /** * Monitors position-bootstrap decisions and cleans owned offers after shutdown. * @param parameters - Shared signal, cycle observer, and optional verbose submission observer. @@ -43,8 +43,8 @@ export interface MarketMakingBootstrapMonitor { }): Promise } -/** Ladder monitor required by the combined market-making lifecycle. */ -export interface MarketMakingLadderMonitor { +/** Ladder monitor required by the combined quoter-bot lifecycle. */ +export interface QuoterBotLadderMonitor { /** * Monitors ladder reconciliations and cleans owned offers after shutdown. * @param parameters - Shared signal, cycle observer, and optional verbose submission observer. @@ -61,20 +61,20 @@ export interface MarketMakingLadderMonitor { } /** One fulfilled workflow report or sanitized rejected-workflow classification. */ -export type MarketMakingWorkflowOutcome = +export type QuoterBotWorkflowOutcome = | { status: 'fulfilled'; report: Report } | { status: 'rejected'; errorName: string } /** Tagged JSON event emitted by one workflow within the combined lifecycle. */ -export type MarketMakingEvent = - | { event: 'market-making.cycle'; workflow: 'setup-check'; report: SetupCheckReport } +export type QuoterBotEvent = + | { event: 'quoter-bot.cycle'; workflow: 'setup-check'; report: SetupCheckReport } | { - event: 'market-making.cycle' + event: 'quoter-bot.cycle' workflow: 'bootstrap' results: readonly { status: string; [key: string]: unknown }[] } | { - event: 'market-making.cycle' + event: 'quoter-bot.cycle' workflow: 'ladder' results: readonly { status: string }[] } @@ -82,31 +82,31 @@ export type MarketMakingEvent = | LadderTransactionSubmittedEvent /** Final combined lifecycle report after every workflow and cleanup has settled. */ -export type MarketMakingMonitorReport = { +export type QuoterBotMonitorReport = { /** Whether the operator requested a clean stop or one workflow ended unexpectedly. */ status: 'stopped' | 'halted' /** Stable reason for the combined terminal state. */ reason: 'signal' | 'workflow-halted' | 'workflow-error' | 'workflow-stopped' /** Terminal outcomes retained for each concurrently started workflow. */ workflows: { - setupCheck: MarketMakingWorkflowOutcome - bootstrap: MarketMakingWorkflowOutcome - ladder: MarketMakingWorkflowOutcome + setupCheck: QuoterBotWorkflowOutcome + bootstrap: QuoterBotWorkflowOutcome + ladder: QuoterBotWorkflowOutcome } } /** Supervises setup, bootstrap, and ladder monitors as one fail-together lifecycle. */ -export class MarketMakingService { +export class QuoterBotService { /** - * Creates the combined market-making monitor. + * Creates the combined quoter-bot monitor. * @param setup - Read-only readiness monitor. * @param bootstrap - Position-bootstrap monitor with owned-offer cleanup. * @param ladder - Ladder monitor with owned-offer cleanup. */ constructor( - private readonly setup: MarketMakingSetupMonitor, - private readonly bootstrap: MarketMakingBootstrapMonitor, - private readonly ladder: MarketMakingLadderMonitor + private readonly setup: QuoterBotSetupMonitor, + private readonly bootstrap: QuoterBotBootstrapMonitor, + private readonly ladder: QuoterBotLadderMonitor ) {} /** @@ -119,9 +119,9 @@ export class MarketMakingService { */ async runContinuously(parameters: { signal: AbortSignal - onEvent?: (event: MarketMakingEvent) => void | Promise + onEvent?: (event: QuoterBotEvent) => void | Promise verbose?: boolean - }): Promise { + }): Promise { const controller = new AbortController() let stopRequested = parameters.signal.aborted let workflowSettledBeforeOperator = false @@ -154,7 +154,7 @@ export class MarketMakingService { onCycle: async report => { if (!report.ready) stopFromWorkflow() await parameters.onEvent?.({ - event: 'market-making.cycle', + event: 'quoter-bot.cycle', workflow: 'setup-check', report }) @@ -168,7 +168,7 @@ export class MarketMakingService { signal: controller.signal, onCycle: async results => { await parameters.onEvent?.({ - event: 'market-making.cycle', + event: 'quoter-bot.cycle', workflow: 'bootstrap', results }) @@ -187,7 +187,7 @@ export class MarketMakingService { signal: controller.signal, onCycle: async results => { await parameters.onEvent?.({ - event: 'market-making.cycle', + event: 'quoter-bot.cycle', workflow: 'ladder', results }) @@ -210,7 +210,7 @@ export class MarketMakingService { const toOutcome = ( settlement: PromiseSettledResult - ): MarketMakingWorkflowOutcome => + ): QuoterBotWorkflowOutcome => settlement.status === 'fulfilled' ? { status: 'fulfilled', report: settlement.value } : { status: 'rejected', errorName: operatorErrorName(settlement.reason) } diff --git a/bots/market-making/src/application/setup/safe-provider.error.ts b/bots/quoter-bot/src/application/setup/safe-provider.error.ts similarity index 100% rename from bots/market-making/src/application/setup/safe-provider.error.ts rename to bots/quoter-bot/src/application/setup/safe-provider.error.ts diff --git a/bots/market-making/src/application/setup/setup-check.service.ts b/bots/quoter-bot/src/application/setup/setup-check.service.ts similarity index 98% rename from bots/market-making/src/application/setup/setup-check.service.ts rename to bots/quoter-bot/src/application/setup/setup-check.service.ts index 22ca1960..258a4e17 100644 --- a/bots/market-making/src/application/setup/setup-check.service.ts +++ b/bots/quoter-bot/src/application/setup/setup-check.service.ts @@ -90,7 +90,7 @@ export type SetupCheckMonitorReport = lastReport: SetupCheckReport } -/** Validated configuration required to evaluate market-maker readiness on Base. */ +/** Validated configuration required to evaluate quoter readiness on Base. */ export type SetupCheckConfig = { /** Configured EVM chain identifier; V0 requires Base (`8453`). */ chainId: number @@ -191,7 +191,7 @@ export interface SetupStateService { checkPositionHealth(): Promise<{ status: 'not-required'; reason: string }> } -/** Application service that evaluates every V0 market-maker readiness requirement without writes. */ +/** Application service that evaluates every V0 quoter readiness requirement without writes. */ export class SetupCheckService { /** * Creates the setup readiness gate. diff --git a/bots/market-making/src/application/setup/setup-check.utils.ts b/bots/quoter-bot/src/application/setup/setup-check.utils.ts similarity index 100% rename from bots/market-making/src/application/setup/setup-check.utils.ts rename to bots/quoter-bot/src/application/setup/setup-check.utils.ts diff --git a/bots/market-making/src/application/setup/setup-failed.error.ts b/bots/quoter-bot/src/application/setup/setup-failed.error.ts similarity index 100% rename from bots/market-making/src/application/setup/setup-failed.error.ts rename to bots/quoter-bot/src/application/setup/setup-failed.error.ts diff --git a/bots/market-making/src/application/setup/setup-monitor-configuration.error.ts b/bots/quoter-bot/src/application/setup/setup-monitor-configuration.error.ts similarity index 100% rename from bots/market-making/src/application/setup/setup-monitor-configuration.error.ts rename to bots/quoter-bot/src/application/setup/setup-monitor-configuration.error.ts diff --git a/bots/market-making/src/application/setup/setup-monitor-halted.error.ts b/bots/quoter-bot/src/application/setup/setup-monitor-halted.error.ts similarity index 100% rename from bots/market-making/src/application/setup/setup-monitor-halted.error.ts rename to bots/quoter-bot/src/application/setup/setup-monitor-halted.error.ts diff --git a/bots/market-making/src/application/version.service.ts b/bots/quoter-bot/src/application/version.service.ts similarity index 100% rename from bots/market-making/src/application/version.service.ts rename to bots/quoter-bot/src/application/version.service.ts diff --git a/bots/market-making/src/bootstrap.ts b/bots/quoter-bot/src/bootstrap.ts similarity index 95% rename from bots/market-making/src/bootstrap.ts rename to bots/quoter-bot/src/bootstrap.ts index 1c3f2a66..c62167e9 100644 --- a/bots/market-making/src/bootstrap.ts +++ b/bots/quoter-bot/src/bootstrap.ts @@ -8,7 +8,7 @@ import type { LadderMakeService, LadderPositionService, LadderReferenceRateService -} from './application/ladder/ladder-market-maker.service' +} from './application/ladder/ladder-quoter.service' import type { SetupStateService } from './application/setup/setup-check.service' import type { ConfigService } from './config/config.service' import type { TargetRateStrategyConfig } from './domain/target-rate' @@ -16,9 +16,9 @@ import type { CliRuntimeOptions } from './infrastructure/cli/cli' import { PositionBootstrapService } from './application/bootstrap/position-bootstrap.service' import { OfferInvalidationService } from './application/invalidation/offer-invalidation.service' -import { LadderMarketMakerService } from './application/ladder/ladder-market-maker.service' -import { serializeMarketMakingWrites } from './application/market-making/market-making-mutation.utils' -import { MarketMakingService } from './application/market-making/market-making.service' +import { LadderQuoterService } from './application/ladder/ladder-quoter.service' +import { serializeQuoterBotWrites } from './application/quoter-bot/quoter-bot-mutation.utils' +import { QuoterBotService } from './application/quoter-bot/quoter-bot.service' import { SetupCheckService } from './application/setup/setup-check.service' import { VersionService } from './application/version.service' import { ConfigValidationError } from './config/config-validation.error' @@ -261,7 +261,7 @@ export const createApplication = ( adapters.validateReconcile ) : adapters.make - return new LadderMarketMakerService(adapters.positions, adapters.rates, make, config.ladder) + return new LadderQuoterService(adapters.positions, adapters.rates, make, config.ladder) }, async options => { const config = await loadConfig(options) @@ -311,9 +311,9 @@ export const createApplication = ( ladderAdapters.validateReconcile ) : ladderAdapters.make - const make = serializeMarketMakingWrites({ bootstrap: bootstrapMake, ladder: ladderMake }) + const make = serializeQuoterBotWrites({ bootstrap: bootstrapMake, ladder: ladderMake }) - return new MarketMakingService( + return new QuoterBotService( setup, new PositionBootstrapService( bootstrapAdapters.positions, @@ -321,7 +321,7 @@ export const createApplication = ( make.bootstrap, config.bootstrap ), - new LadderMarketMakerService( + new LadderQuoterService( ladderAdapters.positions, ladderAdapters.rates, make.ladder, diff --git a/bots/market-making/src/config/config-file.error.ts b/bots/quoter-bot/src/config/config-file.error.ts similarity index 100% rename from bots/market-making/src/config/config-file.error.ts rename to bots/quoter-bot/src/config/config-file.error.ts diff --git a/bots/market-making/src/config/config-source.utils.ts b/bots/quoter-bot/src/config/config-source.utils.ts similarity index 99% rename from bots/market-making/src/config/config-source.utils.ts rename to bots/quoter-bot/src/config/config-source.utils.ts index 1abad44c..0101b5eb 100644 --- a/bots/market-making/src/config/config-source.utils.ts +++ b/bots/quoter-bot/src/config/config-source.utils.ts @@ -554,7 +554,7 @@ export const loadConfigurationSources = async ( if (explicitPath) { document = await readConfiguration(explicitPath, true, fileSystem) } else { - for (const name of ['market-making.yaml', 'market-making.yml']) { + for (const name of ['quoter-bot.yaml', 'quoter-bot.yml']) { const candidate = join(cwd, name) const discovered = await readConfiguration(candidate, false, fileSystem) if (discovered !== undefined) { diff --git a/bots/market-making/src/config/config-validation.error.ts b/bots/quoter-bot/src/config/config-validation.error.ts similarity index 100% rename from bots/market-making/src/config/config-validation.error.ts rename to bots/quoter-bot/src/config/config-validation.error.ts diff --git a/bots/market-making/src/config/config.service.ts b/bots/quoter-bot/src/config/config.service.ts similarity index 97% rename from bots/market-making/src/config/config.service.ts rename to bots/quoter-bot/src/config/config.service.ts index 27c9fcbd..c0a8db64 100644 --- a/bots/market-making/src/config/config.service.ts +++ b/bots/quoter-bot/src/config/config.service.ts @@ -27,7 +27,7 @@ import { signerIdentity } from './signer-identity.utils' export type { MakerIdentity } from './signer-identity.utils' -/** Immutable, validated market-making runtime configuration loaded from YAML and environment values. */ +/** Immutable, validated quoter-bot runtime configuration loaded from YAML and environment values. */ export class ConfigService { /** * Parses the existing environment-only representation through the shared validation path. @@ -53,8 +53,8 @@ export class ConfigService { * @param options - Optional path, invocation directory, file reader, and identity-loading mode. * @returns A single immutable configuration shared by setup and bootstrap consumers. * @throws `ConfigFileError` or `ConfigValidationError` with no rejected values attached. - * @remarks Without an explicit path, discovery securely opens `market-making.yaml` before - * `market-making.yml` in `options.cwd` (or `process.cwd()`). Only an absent higher-precedence path + * @remarks Without an explicit path, discovery securely opens `quoter-bot.yaml` before + * `quoter-bot.yml` in `options.cwd` (or `process.cwd()`). Only an absent higher-precedence path * permits fallback; unsafe entries fail closed. No file means env-only loading. Read-only mode * omits YAML and environment private-key values before typed validation. */ diff --git a/bots/market-making/src/config/config.utils.ts b/bots/quoter-bot/src/config/config.utils.ts similarity index 99% rename from bots/market-making/src/config/config.utils.ts rename to bots/quoter-bot/src/config/config.utils.ts index 8ade9331..ff14ff01 100644 --- a/bots/market-making/src/config/config.utils.ts +++ b/bots/quoter-bot/src/config/config.utils.ts @@ -21,7 +21,7 @@ export { /** String-valued runtime environment boundary accepted by configuration parsing. */ export type Environment = Record -/** Base mainnet chain ID — the only chain the market-making bot supports. */ +/** Base mainnet chain ID — the only chain the quoter-bot bot supports. */ export const BASE_CHAIN_ID = 8453 const DEFAULT_REQUEST_TIMEOUT_MS = 10_000 diff --git a/bots/market-making/src/config/market-collections.ts b/bots/quoter-bot/src/config/market-collections.ts similarity index 100% rename from bots/market-making/src/config/market-collections.ts rename to bots/quoter-bot/src/config/market-collections.ts diff --git a/bots/market-making/src/config/signer-identity.utils.ts b/bots/quoter-bot/src/config/signer-identity.utils.ts similarity index 100% rename from bots/market-making/src/config/signer-identity.utils.ts rename to bots/quoter-bot/src/config/signer-identity.utils.ts diff --git a/bots/market-making/src/domain/bootstrap/bootstrap-configuration.error.ts b/bots/quoter-bot/src/domain/bootstrap/bootstrap-configuration.error.ts similarity index 100% rename from bots/market-making/src/domain/bootstrap/bootstrap-configuration.error.ts rename to bots/quoter-bot/src/domain/bootstrap/bootstrap-configuration.error.ts diff --git a/bots/market-making/src/domain/bootstrap/position-bootstrap.ts b/bots/quoter-bot/src/domain/bootstrap/position-bootstrap.ts similarity index 100% rename from bots/market-making/src/domain/bootstrap/position-bootstrap.ts rename to bots/quoter-bot/src/domain/bootstrap/position-bootstrap.ts diff --git a/bots/market-making/src/domain/bytes32.ts b/bots/quoter-bot/src/domain/bytes32.ts similarity index 100% rename from bots/market-making/src/domain/bytes32.ts rename to bots/quoter-bot/src/domain/bytes32.ts diff --git a/bots/market-making/src/domain/ladder/ladder-configuration.error.ts b/bots/quoter-bot/src/domain/ladder/ladder-configuration.error.ts similarity index 100% rename from bots/market-making/src/domain/ladder/ladder-configuration.error.ts rename to bots/quoter-bot/src/domain/ladder/ladder-configuration.error.ts diff --git a/bots/market-making/src/domain/ladder/ladder.ts b/bots/quoter-bot/src/domain/ladder/ladder.ts similarity index 100% rename from bots/market-making/src/domain/ladder/ladder.ts rename to bots/quoter-bot/src/domain/ladder/ladder.ts diff --git a/bots/market-making/src/domain/setup/.gitkeep b/bots/quoter-bot/src/domain/setup/.gitkeep similarity index 100% rename from bots/market-making/src/domain/setup/.gitkeep rename to bots/quoter-bot/src/domain/setup/.gitkeep diff --git a/bots/market-making/src/domain/target-rate.ts b/bots/quoter-bot/src/domain/target-rate.ts similarity index 100% rename from bots/market-making/src/domain/target-rate.ts rename to bots/quoter-bot/src/domain/target-rate.ts diff --git a/bots/market-making/src/index.ts b/bots/quoter-bot/src/index.ts similarity index 85% rename from bots/market-making/src/index.ts rename to bots/quoter-bot/src/index.ts index 21b7d900..8de4b9b3 100644 --- a/bots/market-making/src/index.ts +++ b/bots/quoter-bot/src/index.ts @@ -8,9 +8,9 @@ import { operatorErrorName } from './application/operator-error-name.utils' import { createApplication } from './bootstrap' import { BASE_CHAIN_ID } from './config/config.utils' import { - MARKET_MAKING_VERBOSE_COMMANDS, - runMarketMakingEntrypoint -} from './infrastructure/cli/market-making-entrypoint' + QUOTER_BOT_VERBOSE_COMMANDS, + runQuoterBotEntrypoint +} from './infrastructure/cli/quoter-bot-entrypoint' // oxlint-disable-next-line eslint/no-extend-native -- CLI root policy requested by maintainers. Object.defineProperty(BigInt.prototype, 'toJSON', { @@ -26,7 +26,7 @@ process.once('SIGINT', requestShutdown) process.once('SIGTERM', requestShutdown) const observability = createBotObservability({ - bot: 'market-making', + bot: 'quoter-bot', chainId: BASE_CHAIN_ID, errorName: operatorErrorName }) @@ -34,10 +34,10 @@ const removeProcessObservers = installProcessObservers(observability) await observability.start() try { - process.exitCode = await runMarketMakingEntrypoint( + process.exitCode = await runQuoterBotEntrypoint( createApplication(), enhanceVerboseArgv(process.argv.slice(2), { - commands: MARKET_MAKING_VERBOSE_COMMANDS, + commands: QUOTER_BOT_VERBOSE_COMMANDS, env: process.env }), { diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-adapter.error.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-adapter.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-adapter.error.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-adapter.error.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-exposure.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-exposure.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-exposure.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-exposure.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-group-ownership.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-group-ownership.utils.ts similarity index 99% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-group-ownership.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-group-ownership.utils.ts index 537a4307..cf4cdb82 100644 --- a/bots/market-making/src/infrastructure/bootstrap/bootstrap-group-ownership.utils.ts +++ b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-group-ownership.utils.ts @@ -140,7 +140,7 @@ export const createBootstrapGroupOwnership = ( const strategy = strategyId(config) const directory = dependencies.stateDirectory ?? - join(process.env.XDG_STATE_HOME ?? join(homedir(), '.local', 'state'), 'morpho-market-making') + join(process.env.XDG_STATE_HOME ?? join(homedir(), '.local', 'state'), 'morpho-quoter-bot') const path = join(directory, `${strategy}.json`) const configured = config.configuredGroupIds.map(canonicalId) diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-groups.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-groups.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-groups.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-groups.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-hard-halt.error.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-hard-halt.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-hard-halt.error.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-hard-halt.error.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-make.service.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-make.service.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-make.service.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-make.service.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-mempool-validation.error.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-mempool-validation.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-mempool-validation.error.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-mempool-validation.error.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-mempool-validation.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-mempool-validation.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-mempool-validation.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-mempool-validation.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-offer.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-offer.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-offer.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-offer.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-pending-offer.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-pending-offer.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-pending-offer.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-pending-offer.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-position.service.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-position.service.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-position.service.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-position.service.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-reference-rate.service.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-reference-rate.service.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-reference-rate.service.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-reference-rate.service.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-requirement-client.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-requirement-client.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-requirement-client.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-requirement-client.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-requirements.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-requirements.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-requirements.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-requirements.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-spread.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-spread.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-spread.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-spread.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/bootstrap-transaction.utils.ts b/bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-transaction.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/bootstrap-transaction.utils.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/bootstrap-transaction.utils.ts diff --git a/bots/market-making/src/infrastructure/bootstrap/production-bootstrap.ts b/bots/quoter-bot/src/infrastructure/bootstrap/production-bootstrap.ts similarity index 100% rename from bots/market-making/src/infrastructure/bootstrap/production-bootstrap.ts rename to bots/quoter-bot/src/infrastructure/bootstrap/production-bootstrap.ts diff --git a/bots/market-making/src/infrastructure/cli/cli-usage.error.ts b/bots/quoter-bot/src/infrastructure/cli/cli-usage.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/cli/cli-usage.error.ts rename to bots/quoter-bot/src/infrastructure/cli/cli-usage.error.ts diff --git a/bots/market-making/src/infrastructure/cli/cli.ts b/bots/quoter-bot/src/infrastructure/cli/cli.ts similarity index 92% rename from bots/market-making/src/infrastructure/cli/cli.ts rename to bots/quoter-bot/src/infrastructure/cli/cli.ts index 350d2ccc..009f0fb4 100644 --- a/bots/market-making/src/infrastructure/cli/cli.ts +++ b/bots/quoter-bot/src/infrastructure/cli/cli.ts @@ -9,12 +9,12 @@ import type { OfferInvalidationSuccessReport, OfferInvalidationTransactionSubmittedEvent } from '../../application/invalidation/offer-invalidation.service' -import type { LadderMonitorReport } from '../../application/ladder/ladder-market-maker.service' +import type { LadderMonitorReport } from '../../application/ladder/ladder-quoter.service' import type { LadderTransactionSubmittedEvent } from '../../application/ladder/ladder-verbose' import type { - MarketMakingEvent, - MarketMakingMonitorReport -} from '../../application/market-making/market-making.service' + QuoterBotEvent, + QuoterBotMonitorReport +} from '../../application/quoter-bot/quoter-bot.service' import type { SetupCheckMonitorReport, SetupCheckReport @@ -25,7 +25,7 @@ import { PositionBootstrapHaltedError } from '../../application/bootstrap/positi import { PositionBootstrapMonitorHaltedError } from '../../application/bootstrap/position-bootstrap-monitor-halted.error' import { LadderCycleHaltedError } from '../../application/ladder/ladder-cycle-halted.error' import { LadderMonitorHaltedError } from '../../application/ladder/ladder-monitor-halted.error' -import { MarketMakingMonitorHaltedError } from '../../application/market-making/market-making-monitor-halted.error' +import { QuoterBotMonitorHaltedError } from '../../application/quoter-bot/quoter-bot-monitor-halted.error' import { SetupMonitorHaltedError } from '../../application/setup/setup-monitor-halted.error' import { CliUsageError } from './cli-usage.error' import { offerInvalidationGroup } from './offer-invalidation-argument.utils' @@ -53,7 +53,7 @@ interface PositionBootstrapService { }): Promise } -interface LadderMarketMakerService { +interface LadderQuoterService { runOnce(parameters?: { verbose?: boolean onTransactionSubmitted?: (event: LadderTransactionSubmittedEvent) => void | Promise @@ -75,12 +75,12 @@ interface OfferInvalidationService { }): Promise } -interface MarketMakingMonitorService { +interface QuoterBotMonitorService { runContinuously(parameters: { signal: AbortSignal - onEvent?: (event: MarketMakingEvent) => void | Promise + onEvent?: (event: QuoterBotEvent) => void | Promise verbose?: boolean - }): Promise + }): Promise } /** CLI-selected runtime and configuration-file options. */ @@ -100,7 +100,7 @@ export type CliRuntimeOptions = { writeEvent?: (value: unknown) => void | Promise } -/** Infrastructure adapter: wires the `mm` CLI (commander) to application services. */ +/** Infrastructure adapter: wires the `quoter-bot` CLI (commander) to application services. */ export class Cli { private readonly program: Command private output: unknown @@ -127,7 +127,7 @@ export class Cli { * @param bootstrap - Lazy position-bootstrap factory, invoked only for `bootstrap`. * @param ladder - Lazy production or test ladder-service factory. * @param invalidation - Optional lazy all-groups or one-group invalidation factory. - * @param marketMaking - Optional lazy combined setup, bootstrap, and ladder monitor factory. + * @param quoterBot - Optional lazy combined setup, bootstrap, and ladder monitor factory. * @remarks Construction performs no provider calls and does not start writer workflows. The * `--readonly` option is a positive Boolean flag and defaults to write-enabled configuration. */ @@ -141,17 +141,17 @@ export class Cli { ) => PositionBootstrapService | Promise, ladder: ( options: CliConfigurationOptions - ) => LadderMarketMakerService | Promise, + ) => LadderQuoterService | Promise, invalidation?: ( options: CliConfigurationOptions ) => OfferInvalidationService | Promise, - marketMaking?: ( + quoterBot?: ( options: CliConfigurationOptions - ) => MarketMakingMonitorService | Promise + ) => QuoterBotMonitorService | Promise ) { this.program = new Command() - .name('mm') - .description('Morpho market making bot CLI') + .name('quoter-bot') + .description('Morpho quoter bot CLI') .version(version.getVersion(), '-v, --version', 'output the current version') .option('-c, --config ', 'load configuration from an explicit .yaml or .yml file') .option('--json', 'emit machine-parseable JSON Lines instead of human-readable output') @@ -172,7 +172,7 @@ export class Cli { const setupCommand = this.program .command('setup-check') - .description('run market-maker readiness checks once or monitor continuously') + .description('run quoter readiness checks once or monitor continuously') .option('--monitor', 'repeat readiness checks every minute until shutdown') setupCommand.action(async () => { @@ -238,7 +238,7 @@ export class Cli { const ladderCommand = this.program .command('ladder') - .description('run one market-maker ladder cycle or monitor continuously') + .description('run one quoter ladder cycle or monitor continuously') .option('--monitor', 'repeat at the configured cadence and clean up owned offers on shutdown') .option( '--verbose', @@ -282,10 +282,10 @@ export class Cli { .option('--verbose', 'show bootstrap and ladder diagnostics and submitted transaction hashes') startCommand.action(async () => { - if (!marketMaking) throw new CliUsageError() + if (!quoterBot) throw new CliUsageError() const options = this.configurationOptions() const startOptions = startCommand.opts<{ verbose?: boolean }>() - const service = await marketMaking({ + const service = await quoterBot({ ...options, writeEvent: this.runtime.writeEvent }) @@ -294,7 +294,7 @@ export class Cli { onEvent: event => this.runtime.writeEvent?.(event), verbose: startOptions.verbose === true }) - if (result.status === 'halted') throw new MarketMakingMonitorHaltedError(result) + if (result.status === 'halted') throw new QuoterBotMonitorHaltedError(result) this.capture(result) }) diff --git a/bots/market-making/src/infrastructure/cli/offer-invalidation-argument.utils.ts b/bots/quoter-bot/src/infrastructure/cli/offer-invalidation-argument.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/cli/offer-invalidation-argument.utils.ts rename to bots/quoter-bot/src/infrastructure/cli/offer-invalidation-argument.utils.ts diff --git a/bots/market-making/src/infrastructure/cli/password-prompt.utils.ts b/bots/quoter-bot/src/infrastructure/cli/password-prompt.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/cli/password-prompt.utils.ts rename to bots/quoter-bot/src/infrastructure/cli/password-prompt.utils.ts diff --git a/bots/market-making/src/infrastructure/cli/market-making-entrypoint.ts b/bots/quoter-bot/src/infrastructure/cli/quoter-bot-entrypoint.ts similarity index 88% rename from bots/market-making/src/infrastructure/cli/market-making-entrypoint.ts rename to bots/quoter-bot/src/infrastructure/cli/quoter-bot-entrypoint.ts index 3adadf0f..6d6eb165 100644 --- a/bots/market-making/src/infrastructure/cli/market-making-entrypoint.ts +++ b/bots/quoter-bot/src/infrastructure/cli/quoter-bot-entrypoint.ts @@ -7,8 +7,8 @@ import { PositionBootstrapMonitorHaltedError } from '../../application/bootstrap import { OfferInvalidationFailedError } from '../../application/invalidation/offer-invalidation-failed.error' import { LadderCycleHaltedError } from '../../application/ladder/ladder-cycle-halted.error' import { LadderMonitorHaltedError } from '../../application/ladder/ladder-monitor-halted.error' -import { MarketMakingMonitorHaltedError } from '../../application/market-making/market-making-monitor-halted.error' import { operatorErrorName } from '../../application/operator-error-name.utils' +import { QuoterBotMonitorHaltedError } from '../../application/quoter-bot/quoter-bot-monitor-halted.error' import { SafeProviderError } from '../../application/setup/safe-provider.error' import { SetupFailedError } from '../../application/setup/setup-failed.error' import { SetupMonitorHaltedError } from '../../application/setup/setup-monitor-halted.error' @@ -19,7 +19,7 @@ import { LadderConfigurationError } from '../../domain/ladder/ladder-configurati import { MakerAccountError } from '../make/maker-account.error' import { CliUsageError } from './cli-usage.error' -type MarketMakingApplication = { +type QuoterBotApplication = { run(argv: readonly string[], runtime?: CliRuntimeOptions): Promise } type EntrypointOutput = { writeOut(value: string): void; writeError(value: string): void } @@ -29,10 +29,10 @@ type EntrypointObservability = { } /** CLI commands whose safe verbose event stream may be auto-enabled by observability shipping. */ -export const MARKET_MAKING_VERBOSE_COMMANDS = ['start', 'bootstrap', 'ladder'] as const +export const QUOTER_BOT_VERBOSE_COMMANDS = ['start', 'bootstrap', 'ladder'] as const const REPORTED_ERRORS = [ - MarketMakingMonitorHaltedError, + QuoterBotMonitorHaltedError, SetupMonitorHaltedError, OfferInvalidationFailedError, PositionBootstrapMonitorHaltedError, @@ -66,7 +66,7 @@ const failureMessage = (error: unknown) => { } /** - * Runs one market-making CLI invocation and maps sanitized output to a process exit contract. + * Runs one quoter-bot CLI invocation and maps sanitized output to a process exit contract. * @param application - Composed CLI application. * @param argv - User arguments without runtime/executable prefixes. * @param output - Standard output and error writers. @@ -77,8 +77,8 @@ const failureMessage = (error: unknown) => { * Failure reports exclude causes, provider payloads, and credentials and always include an * explicit error message. */ -export const runMarketMakingEntrypoint = async ( - application: MarketMakingApplication, +export const runQuoterBotEntrypoint = async ( + application: QuoterBotApplication, argv: readonly string[], output: EntrypointOutput, runtime: Pick = {}, @@ -88,7 +88,7 @@ export const runMarketMakingEntrypoint = async ( const json = argv .slice(0, optionDelimiter === -1 ? undefined : optionDelimiter) .includes('--json') - const logger = createCliLogger(output, { json, errorEvent: 'market-making.error' }) + const logger = createCliLogger(output, { json, errorEvent: 'quoter-bot.error' }) try { const result = await application.run(argv, { ...runtime, diff --git a/bots/market-making/src/infrastructure/invalidation/batch-offer-invalidation.utils.ts b/bots/quoter-bot/src/infrastructure/invalidation/batch-offer-invalidation.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/invalidation/batch-offer-invalidation.utils.ts rename to bots/quoter-bot/src/infrastructure/invalidation/batch-offer-invalidation.utils.ts diff --git a/bots/market-making/src/infrastructure/invalidation/offer-invalidation-adapter.error.ts b/bots/quoter-bot/src/infrastructure/invalidation/offer-invalidation-adapter.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/invalidation/offer-invalidation-adapter.error.ts rename to bots/quoter-bot/src/infrastructure/invalidation/offer-invalidation-adapter.error.ts diff --git a/bots/market-making/src/infrastructure/invalidation/offer-invalidation-group.utils.ts b/bots/quoter-bot/src/infrastructure/invalidation/offer-invalidation-group.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/invalidation/offer-invalidation-group.utils.ts rename to bots/quoter-bot/src/infrastructure/invalidation/offer-invalidation-group.utils.ts diff --git a/bots/market-making/src/infrastructure/invalidation/offer-invalidation-transaction.utils.ts b/bots/quoter-bot/src/infrastructure/invalidation/offer-invalidation-transaction.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/invalidation/offer-invalidation-transaction.utils.ts rename to bots/quoter-bot/src/infrastructure/invalidation/offer-invalidation-transaction.utils.ts diff --git a/bots/market-making/src/infrastructure/invalidation/production-offer-invalidation.ts b/bots/quoter-bot/src/infrastructure/invalidation/production-offer-invalidation.ts similarity index 100% rename from bots/market-making/src/infrastructure/invalidation/production-offer-invalidation.ts rename to bots/quoter-bot/src/infrastructure/invalidation/production-offer-invalidation.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-active-publication.utils.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-active-publication.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-active-publication.utils.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-active-publication.utils.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-adapter.error.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-adapter.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-adapter.error.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-adapter.error.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-cash-reservation.utils.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-cash-reservation.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-cash-reservation.utils.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-cash-reservation.utils.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-group-ownership.utils.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-group-ownership.utils.ts similarity index 99% rename from bots/market-making/src/infrastructure/ladder/ladder-group-ownership.utils.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-group-ownership.utils.ts index 0a35ca0b..26600df8 100644 --- a/bots/market-making/src/infrastructure/ladder/ladder-group-ownership.utils.ts +++ b/bots/quoter-bot/src/infrastructure/ladder/ladder-group-ownership.utils.ts @@ -211,7 +211,7 @@ export const createLadderGroupOwnership = ( const strategy = strategyId(config) const directory = dependencies.stateDirectory ?? - join(process.env.XDG_STATE_HOME ?? join(homedir(), '.local', 'state'), 'morpho-market-making') + join(process.env.XDG_STATE_HOME ?? join(homedir(), '.local', 'state'), 'morpho-quoter-bot') const path = join(directory, `${strategy}.json`) const read = async (): Promise => { diff --git a/bots/market-making/src/infrastructure/ladder/ladder-hard-halt.error.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-hard-halt.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-hard-halt.error.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-hard-halt.error.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-make.service.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-make.service.ts similarity index 99% rename from bots/market-making/src/infrastructure/ladder/ladder-make.service.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-make.service.ts index bfcfb60a..3ebdc0dd 100644 --- a/bots/market-making/src/infrastructure/ladder/ladder-make.service.ts +++ b/bots/quoter-bot/src/infrastructure/ladder/ladder-make.service.ts @@ -1,6 +1,6 @@ import type { Hex } from 'viem' -import type { LadderMakeService } from '../../application/ladder/ladder-market-maker.service' +import type { LadderMakeService } from '../../application/ladder/ladder-quoter.service' import type { LadderMakeResult, LadderSubmittedTransaction, diff --git a/bots/market-making/src/infrastructure/ladder/ladder-offer.utils.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-offer.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-offer.utils.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-offer.utils.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-ratification.utils.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-ratification.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-ratification.utils.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-ratification.utils.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-signature.utils.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-signature.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-signature.utils.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-signature.utils.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-spread.utils.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-spread.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-spread.utils.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-spread.utils.ts diff --git a/bots/market-making/src/infrastructure/ladder/ladder-transaction.utils.ts b/bots/quoter-bot/src/infrastructure/ladder/ladder-transaction.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/ladder/ladder-transaction.utils.ts rename to bots/quoter-bot/src/infrastructure/ladder/ladder-transaction.utils.ts diff --git a/bots/market-making/src/infrastructure/ladder/production-ladder.ts b/bots/quoter-bot/src/infrastructure/ladder/production-ladder.ts similarity index 99% rename from bots/market-making/src/infrastructure/ladder/production-ladder.ts rename to bots/quoter-bot/src/infrastructure/ladder/production-ladder.ts index c1ad7dfd..a04117f0 100644 --- a/bots/market-making/src/infrastructure/ladder/production-ladder.ts +++ b/bots/quoter-bot/src/infrastructure/ladder/production-ladder.ts @@ -16,7 +16,7 @@ import type { LadderMakeService, LadderPositionService, LadderReferenceRateService -} from '../../application/ladder/ladder-market-maker.service' +} from '../../application/ladder/ladder-quoter.service' import type { LadderSubmittedTransaction, LadderTransactionSubmittedObserver diff --git a/bots/market-making/src/infrastructure/make/maker-account.error.ts b/bots/quoter-bot/src/infrastructure/make/maker-account.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/make/maker-account.error.ts rename to bots/quoter-bot/src/infrastructure/make/maker-account.error.ts diff --git a/bots/market-making/src/infrastructure/make/maker-account.utils.ts b/bots/quoter-bot/src/infrastructure/make/maker-account.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/make/maker-account.utils.ts rename to bots/quoter-bot/src/infrastructure/make/maker-account.utils.ts diff --git a/bots/market-making/src/infrastructure/make/managed-maker-account.utils.ts b/bots/quoter-bot/src/infrastructure/make/managed-maker-account.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/make/managed-maker-account.utils.ts rename to bots/quoter-bot/src/infrastructure/make/managed-maker-account.utils.ts diff --git a/bots/market-making/src/infrastructure/make/read-only-bootstrap-make.service.ts b/bots/quoter-bot/src/infrastructure/make/read-only-bootstrap-make.service.ts similarity index 100% rename from bots/market-making/src/infrastructure/make/read-only-bootstrap-make.service.ts rename to bots/quoter-bot/src/infrastructure/make/read-only-bootstrap-make.service.ts diff --git a/bots/market-making/src/infrastructure/make/read-only-ladder-make.service.ts b/bots/quoter-bot/src/infrastructure/make/read-only-ladder-make.service.ts similarity index 99% rename from bots/market-making/src/infrastructure/make/read-only-ladder-make.service.ts rename to bots/quoter-bot/src/infrastructure/make/read-only-ladder-make.service.ts index 4483b158..809a36af 100644 --- a/bots/market-making/src/infrastructure/make/read-only-ladder-make.service.ts +++ b/bots/quoter-bot/src/infrastructure/make/read-only-ladder-make.service.ts @@ -1,4 +1,4 @@ -import type { LadderMakeService } from '../../application/ladder/ladder-market-maker.service' +import type { LadderMakeService } from '../../application/ladder/ladder-quoter.service' import { formatReadOnlyMakeEvent } from './read-only-make.utils' diff --git a/bots/market-making/src/infrastructure/make/read-only-make.utils.ts b/bots/quoter-bot/src/infrastructure/make/read-only-make.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/make/read-only-make.utils.ts rename to bots/quoter-bot/src/infrastructure/make/read-only-make.utils.ts diff --git a/bots/market-making/src/infrastructure/reference/blue-reference-reader.utils.ts b/bots/quoter-bot/src/infrastructure/reference/blue-reference-reader.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/reference/blue-reference-reader.utils.ts rename to bots/quoter-bot/src/infrastructure/reference/blue-reference-reader.utils.ts diff --git a/bots/market-making/src/infrastructure/reference/reference-adapter.error.ts b/bots/quoter-bot/src/infrastructure/reference/reference-adapter.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/reference/reference-adapter.error.ts rename to bots/quoter-bot/src/infrastructure/reference/reference-adapter.error.ts diff --git a/bots/market-making/src/infrastructure/setup-state/chain-reader.utils.ts b/bots/quoter-bot/src/infrastructure/setup-state/chain-reader.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/setup-state/chain-reader.utils.ts rename to bots/quoter-bot/src/infrastructure/setup-state/chain-reader.utils.ts diff --git a/bots/market-making/src/infrastructure/setup-state/http-json.utils.ts b/bots/quoter-bot/src/infrastructure/setup-state/http-json.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/setup-state/http-json.utils.ts rename to bots/quoter-bot/src/infrastructure/setup-state/http-json.utils.ts diff --git a/bots/market-making/src/infrastructure/setup-state/provider-pagination.error.ts b/bots/quoter-bot/src/infrastructure/setup-state/provider-pagination.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/setup-state/provider-pagination.error.ts rename to bots/quoter-bot/src/infrastructure/setup-state/provider-pagination.error.ts diff --git a/bots/market-making/src/infrastructure/setup-state/provider-read.error.ts b/bots/quoter-bot/src/infrastructure/setup-state/provider-read.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/setup-state/provider-read.error.ts rename to bots/quoter-bot/src/infrastructure/setup-state/provider-read.error.ts diff --git a/bots/market-making/src/infrastructure/setup-state/provider-read.utils.ts b/bots/quoter-bot/src/infrastructure/setup-state/provider-read.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/setup-state/provider-read.utils.ts rename to bots/quoter-bot/src/infrastructure/setup-state/provider-read.utils.ts diff --git a/bots/market-making/src/infrastructure/setup-state/provider-response.error.ts b/bots/quoter-bot/src/infrastructure/setup-state/provider-response.error.ts similarity index 100% rename from bots/market-making/src/infrastructure/setup-state/provider-response.error.ts rename to bots/quoter-bot/src/infrastructure/setup-state/provider-response.error.ts diff --git a/bots/market-making/src/infrastructure/setup-state/viem-setup-state.service.ts b/bots/quoter-bot/src/infrastructure/setup-state/viem-setup-state.service.ts similarity index 100% rename from bots/market-making/src/infrastructure/setup-state/viem-setup-state.service.ts rename to bots/quoter-bot/src/infrastructure/setup-state/viem-setup-state.service.ts diff --git a/bots/market-making/src/infrastructure/setup-state/viem-setup-state.utils.ts b/bots/quoter-bot/src/infrastructure/setup-state/viem-setup-state.utils.ts similarity index 100% rename from bots/market-making/src/infrastructure/setup-state/viem-setup-state.utils.ts rename to bots/quoter-bot/src/infrastructure/setup-state/viem-setup-state.utils.ts diff --git a/bots/market-making/test/application/bootstrap/position-bootstrap.service.test.ts b/bots/quoter-bot/test/application/bootstrap/position-bootstrap.service.test.ts similarity index 100% rename from bots/market-making/test/application/bootstrap/position-bootstrap.service.test.ts rename to bots/quoter-bot/test/application/bootstrap/position-bootstrap.service.test.ts diff --git a/bots/market-making/test/application/invalidation/offer-invalidation.service.test.ts b/bots/quoter-bot/test/application/invalidation/offer-invalidation.service.test.ts similarity index 100% rename from bots/market-making/test/application/invalidation/offer-invalidation.service.test.ts rename to bots/quoter-bot/test/application/invalidation/offer-invalidation.service.test.ts diff --git a/bots/market-making/test/application/ladder/ladder-market-maker.service.test.ts b/bots/quoter-bot/test/application/ladder/ladder-quoter.service.test.ts similarity index 96% rename from bots/market-making/test/application/ladder/ladder-market-maker.service.test.ts rename to bots/quoter-bot/test/application/ladder/ladder-quoter.service.test.ts index 4b203b6a..318e7c20 100644 --- a/bots/market-making/test/application/ladder/ladder-market-maker.service.test.ts +++ b/bots/quoter-bot/test/application/ladder/ladder-quoter.service.test.ts @@ -5,14 +5,14 @@ import { describe, expect, test, vi } from 'vitest' import type { LadderMakeService, LadderPositionService -} from '../../../src/application/ladder/ladder-market-maker.service' +} from '../../../src/application/ladder/ladder-quoter.service' import type { LadderConfig, LadderMarketState, LadderQuoteSet } from '../../../src/domain/ladder/ladder' -import { LadderMarketMakerService } from '../../../src/application/ladder/ladder-market-maker.service' +import { LadderQuoterService } from '../../../src/application/ladder/ladder-quoter.service' import { LadderAdapterError } from '../../../src/infrastructure/ladder/ladder-adapter.error' const marketId: Hex = `0x${'55'.repeat(32)}` @@ -94,7 +94,7 @@ const harness = (configs: readonly LadderConfig[] = [config()]) => { }, cleanup } - let service = new LadderMarketMakerService(positions, rates, make, configs) + let service = new LadderQuoterService(positions, rates, make, configs) return { get service() { return service @@ -114,11 +114,11 @@ const harness = (configs: readonly LadderConfig[] = [config()]) => { failMarket: (id: Hex) => (readFailure = id), failReconcile: (id: Hex) => (reconcileFailure = id), expireRoots: (id: Hex) => liveDesired.delete(id), - recreateService: () => (service = new LadderMarketMakerService(positions, rates, make, configs)) + recreateService: () => (service = new LadderQuoterService(positions, rates, make, configs)) } } -describe('LadderMarketMakerService', () => { +describe('LadderQuoterService', () => { test('monitors sequential cycles and cleans owned groups after shutdown', async () => { const subject = harness([{ ...config(), loopIntervalSeconds: 1 }]) const controller = new AbortController() @@ -222,12 +222,9 @@ describe('LadderMarketMakerService', () => { } } } - const service = new LadderMarketMakerService( - { readMarket }, - { readRate: async () => 500n }, - make, - [config()] - ) + const service = new LadderQuoterService({ readMarket }, { readRate: async () => 500n }, make, [ + config() + ]) const cycles: unknown[] = [] const submittedEvents: unknown[] = [] @@ -421,7 +418,7 @@ describe('LadderMarketMakerService', () => { test('retains failed-market cancellation hashes in verbose output', async () => { const cancellationHash: Hex = `0x${'cc'.repeat(32)}` - const service = new LadderMarketMakerService( + const service = new LadderQuoterService( { async readMarket() { throw new TypeError('private provider detail') @@ -473,7 +470,7 @@ describe('LadderMarketMakerService', () => { ])('hard-halts on %s', async (failure, reason) => { const subject = harness() if (failure === 'reference read') { - subject.service = new LadderMarketMakerService( + subject.service = new LadderQuoterService( { async readMarket() { return state() diff --git a/bots/market-making/test/application/operator-error-name.utils.test.ts b/bots/quoter-bot/test/application/operator-error-name.utils.test.ts similarity index 93% rename from bots/market-making/test/application/operator-error-name.utils.test.ts rename to bots/quoter-bot/test/application/operator-error-name.utils.test.ts index 16723c70..bf67db31 100644 --- a/bots/market-making/test/application/operator-error-name.utils.test.ts +++ b/bots/quoter-bot/test/application/operator-error-name.utils.test.ts @@ -1,10 +1,10 @@ import { describe, expect, test } from 'vitest' -import { MarketMakingMonitorHaltedError } from '../../src/application/market-making/market-making-monitor-halted.error' import { operatorErrorDetails, operatorErrorName } from '../../src/application/operator-error-name.utils' +import { QuoterBotMonitorHaltedError } from '../../src/application/quoter-bot/quoter-bot-monitor-halted.error' import { SetupMonitorConfigurationError } from '../../src/application/setup/setup-monitor-configuration.error' import { SetupMonitorHaltedError } from '../../src/application/setup/setup-monitor-halted.error' import { BootstrapConfigurationError } from '../../src/domain/bootstrap/bootstrap-configuration.error' @@ -85,8 +85,8 @@ describe('operatorErrorName', () => { ).toBe('SetupMonitorHaltedError') }) - test('keeps the combined market-making monitor classification', () => { - const error = new MarketMakingMonitorHaltedError({ + test('keeps the combined quoter-bot monitor classification', () => { + const error = new QuoterBotMonitorHaltedError({ status: 'halted', reason: 'workflow-error', workflows: { @@ -96,7 +96,7 @@ describe('operatorErrorName', () => { } }) - expect(operatorErrorName(error)).toBe('MarketMakingMonitorHaltedError') + expect(operatorErrorName(error)).toBe('QuoterBotMonitorHaltedError') }) test('maps hostile arbitrary names to one generic classification', () => { diff --git a/bots/market-making/test/application/market-making/market-making-mutation.utils.test.ts b/bots/quoter-bot/test/application/quoter-bot/quoter-bot-mutation.utils.test.ts similarity index 88% rename from bots/market-making/test/application/market-making/market-making-mutation.utils.test.ts rename to bots/quoter-bot/test/application/quoter-bot/quoter-bot-mutation.utils.test.ts index 323cbaff..bb866059 100644 --- a/bots/market-making/test/application/market-making/market-making-mutation.utils.test.ts +++ b/bots/quoter-bot/test/application/quoter-bot/quoter-bot-mutation.utils.test.ts @@ -1,9 +1,9 @@ import { describe, expect, test, vi } from 'vitest' import type { BootstrapMakeService } from '../../../src/application/bootstrap/position-bootstrap.service' -import type { LadderMakeService } from '../../../src/application/ladder/ladder-market-maker.service' +import type { LadderMakeService } from '../../../src/application/ladder/ladder-quoter.service' -import { serializeMarketMakingWrites } from '../../../src/application/market-making/market-making-mutation.utils' +import { serializeQuoterBotWrites } from '../../../src/application/quoter-bot/quoter-bot-mutation.utils' const marketId = `0x${'11'.repeat(32)}` as const @@ -37,7 +37,7 @@ const createServices = (events: string[]) => { return { bootstrap, ladder } } -describe('serializeMarketMakingWrites', () => { +describe('serializeQuoterBotWrites', () => { test('serializes bootstrap and ladder mutations through one queue', async () => { const events: string[] = [] let releaseBootstrap: (() => void) | undefined @@ -49,7 +49,7 @@ describe('serializeMarketMakingWrites', () => { releaseBootstrap = resolve }) ) - const serialized = serializeMarketMakingWrites(services) + const serialized = serializeQuoterBotWrites(services) const bootstrapWrite = serialized.bootstrap.reconcile({ marketId, reason: 'publish' }) const ladderWrite = serialized.ladder.cleanup() @@ -68,7 +68,7 @@ describe('serializeMarketMakingWrites', () => { events.push('bootstrap:failed') throw new TypeError('publication failed') }) - const serialized = serializeMarketMakingWrites(services) + const serialized = serializeQuoterBotWrites(services) const failed = serialized.bootstrap.cleanup().catch(error => error) const following = serialized.ladder.hardHalt({ reason: 'ladder-configuration-failed' }) @@ -89,7 +89,7 @@ describe('serializeMarketMakingWrites', () => { releaseBootstrap = resolve }) ) - const serialized = serializeMarketMakingWrites(services) + const serialized = serializeQuoterBotWrites(services) const mutation = serialized.bootstrap.hardHalt({ reason: 'reference-read-failed' }) await Promise.resolve() diff --git a/bots/market-making/test/application/market-making/market-making.service.test.ts b/bots/quoter-bot/test/application/quoter-bot/quoter-bot.service.test.ts similarity index 82% rename from bots/market-making/test/application/market-making/market-making.service.test.ts rename to bots/quoter-bot/test/application/quoter-bot/quoter-bot.service.test.ts index 8df49f3c..3a018e6c 100644 --- a/bots/market-making/test/application/market-making/market-making.service.test.ts +++ b/bots/quoter-bot/test/application/quoter-bot/quoter-bot.service.test.ts @@ -1,13 +1,13 @@ import { describe, expect, test } from 'vitest' import type { - MarketMakingBootstrapMonitor, - MarketMakingEvent, - MarketMakingLadderMonitor, - MarketMakingSetupMonitor -} from '../../../src/application/market-making/market-making.service' + QuoterBotBootstrapMonitor, + QuoterBotEvent, + QuoterBotLadderMonitor, + QuoterBotSetupMonitor +} from '../../../src/application/quoter-bot/quoter-bot.service' -import { MarketMakingService } from '../../../src/application/market-making/market-making.service' +import { QuoterBotService } from '../../../src/application/quoter-bot/quoter-bot.service' const waitForAbort = (signal: AbortSignal) => new Promise(resolve => { @@ -38,7 +38,7 @@ const stoppedLadderReport = { cleanup: { status: 'applied' as const } } -const waitingBootstrapMonitor = (drained: string[]): MarketMakingBootstrapMonitor => ({ +const waitingBootstrapMonitor = (drained: string[]): QuoterBotBootstrapMonitor => ({ runContinuously: async ({ signal, onCycle }) => { await onCycle?.([{ status: 'observed', action: 'rest' }]) await waitForAbort(signal) @@ -47,7 +47,7 @@ const waitingBootstrapMonitor = (drained: string[]): MarketMakingBootstrapMonito } }) -const waitingLadderMonitor = (drained: string[]): MarketMakingLadderMonitor => ({ +const waitingLadderMonitor = (drained: string[]): QuoterBotLadderMonitor => ({ runContinuously: async ({ signal, onCycle }) => { await onCycle?.([{ status: 'observed' }]) await waitForAbort(signal) @@ -56,10 +56,10 @@ const waitingLadderMonitor = (drained: string[]): MarketMakingLadderMonitor => ( } }) -describe('MarketMakingService', () => { +describe('QuoterBotService', () => { test('aborts peer workflows and waits for writer cleanup after one workflow halts', async () => { const failedReport = { ready: false, checks: [] } - const setup: MarketMakingSetupMonitor = { + const setup: QuoterBotSetupMonitor = { runContinuously: async ({ onCycle }) => { await onCycle?.(failedReport) return { @@ -71,8 +71,8 @@ describe('MarketMakingService', () => { } } const drained: string[] = [] - const events: MarketMakingEvent[] = [] - const service = new MarketMakingService( + const events: QuoterBotEvent[] = [] + const service = new QuoterBotService( setup, waitingBootstrapMonitor(drained), waitingLadderMonitor(drained) @@ -96,14 +96,14 @@ describe('MarketMakingService', () => { }) expect(drained).toEqual(['bootstrap', 'ladder']) expect(events).toEqual([ - { event: 'market-making.cycle', workflow: 'setup-check', report: failedReport }, + { event: 'quoter-bot.cycle', workflow: 'setup-check', report: failedReport }, { - event: 'market-making.cycle', + event: 'quoter-bot.cycle', workflow: 'bootstrap', results: [{ status: 'observed', action: 'rest' }] }, { - event: 'market-making.cycle', + event: 'quoter-bot.cycle', workflow: 'ladder', results: [{ status: 'observed' }] } @@ -125,7 +125,7 @@ describe('MarketMakingService', () => { markWriterChecked = resolve }) let writerObservedAbort = false - const setup: MarketMakingSetupMonitor = { + const setup: QuoterBotSetupMonitor = { runContinuously: async ({ onCycle }) => { await onCycle?.(failedReport) return { @@ -136,7 +136,7 @@ describe('MarketMakingService', () => { } } } - const bootstrap: MarketMakingBootstrapMonitor = { + const bootstrap: QuoterBotBootstrapMonitor = { runContinuously: async ({ signal, runOperation }) => { if (!runOperation) throw new Error('missing operation queue') await runOperation(async () => { @@ -146,16 +146,16 @@ describe('MarketMakingService', () => { return stoppedBootstrapReport } } - const ladder: MarketMakingLadderMonitor = { + const ladder: QuoterBotLadderMonitor = { runContinuously: async ({ signal }) => { await waitForAbort(signal) return stoppedLadderReport } } - const running = new MarketMakingService(setup, bootstrap, ladder).runContinuously({ + const running = new QuoterBotService(setup, bootstrap, ladder).runContinuously({ signal: new AbortController().signal, onEvent: async event => { - if (event.event !== 'market-making.cycle' || event.workflow !== 'setup-check') return + if (event.event !== 'quoter-bot.cycle' || event.workflow !== 'setup-check') return markEventStarted?.() await eventDelivery } @@ -172,13 +172,13 @@ describe('MarketMakingService', () => { test('serializes writer cycles and aborts peers before cleanup begins', async () => { const events: string[] = [] const failedResults = [{ status: 'failed', stage: 'make' }] - const setup: MarketMakingSetupMonitor = { + const setup: QuoterBotSetupMonitor = { runContinuously: async ({ signal }) => { await waitForAbort(signal) return stoppedSetupReport } } - const bootstrap: MarketMakingBootstrapMonitor = { + const bootstrap: QuoterBotBootstrapMonitor = { runContinuously: async ({ signal, onCycle, runOperation }) => { if (!runOperation) throw new Error('missing operation queue') await runOperation(async () => { @@ -197,7 +197,7 @@ describe('MarketMakingService', () => { } } } - const ladder: MarketMakingLadderMonitor = { + const ladder: QuoterBotLadderMonitor = { runContinuously: async ({ signal, runOperation }) => { if (!runOperation) throw new Error('missing operation queue') await runOperation(async () => { @@ -215,7 +215,7 @@ describe('MarketMakingService', () => { } } - const report = await new MarketMakingService(setup, bootstrap, ladder).runContinuously({ + const report = await new QuoterBotService(setup, bootstrap, ladder).runContinuously({ signal: new AbortController().signal }) @@ -232,21 +232,21 @@ describe('MarketMakingService', () => { test('returns a clean stop only after an operator signal drains every workflow', async () => { const started: string[] = [] - const setup: MarketMakingSetupMonitor = { + const setup: QuoterBotSetupMonitor = { runContinuously: async ({ signal }) => { started.push('setup') await waitForAbort(signal) return stoppedSetupReport } } - const bootstrap: MarketMakingBootstrapMonitor = { + const bootstrap: QuoterBotBootstrapMonitor = { runContinuously: async ({ signal }) => { started.push('bootstrap') await waitForAbort(signal) return stoppedBootstrapReport } } - const ladder: MarketMakingLadderMonitor = { + const ladder: QuoterBotLadderMonitor = { runContinuously: async ({ signal }) => { started.push('ladder') await waitForAbort(signal) @@ -254,7 +254,7 @@ describe('MarketMakingService', () => { } } const controller = new AbortController() - const running = new MarketMakingService(setup, bootstrap, ladder).runContinuously({ + const running = new QuoterBotService(setup, bootstrap, ladder).runContinuously({ signal: controller.signal }) @@ -274,13 +274,13 @@ describe('MarketMakingService', () => { }) test('sanitizes a rejected workflow and waits for both writer monitors to drain', async () => { - const setup: MarketMakingSetupMonitor = { + const setup: QuoterBotSetupMonitor = { runContinuously: async () => { throw new TypeError('provider https://rpc.example/?token=secret') } } const drained: string[] = [] - const service = new MarketMakingService( + const service = new QuoterBotService( setup, waitingBootstrapMonitor(drained), waitingLadderMonitor(drained) @@ -301,11 +301,11 @@ describe('MarketMakingService', () => { }) test('classifies a workflow that stops without an operator signal as unexpected', async () => { - const setup: MarketMakingSetupMonitor = { + const setup: QuoterBotSetupMonitor = { runContinuously: async () => stoppedSetupReport } const drained: string[] = [] - const service = new MarketMakingService( + const service = new QuoterBotService( setup, waitingBootstrapMonitor(drained), waitingLadderMonitor(drained) @@ -326,10 +326,10 @@ describe('MarketMakingService', () => { const bootstrapDrain = new Promise(resolve => { releaseBootstrapDrain = resolve }) - const setup: MarketMakingSetupMonitor = { + const setup: QuoterBotSetupMonitor = { runContinuously: async () => stoppedSetupReport } - const bootstrap: MarketMakingBootstrapMonitor = { + const bootstrap: QuoterBotBootstrapMonitor = { runContinuously: async ({ signal }) => { await waitForAbort(signal) observePeerAbort?.() @@ -337,14 +337,14 @@ describe('MarketMakingService', () => { return stoppedBootstrapReport } } - const ladder: MarketMakingLadderMonitor = { + const ladder: QuoterBotLadderMonitor = { runContinuously: async ({ signal }) => { await waitForAbort(signal) return stoppedLadderReport } } const controller = new AbortController() - const running = new MarketMakingService(setup, bootstrap, ladder).runContinuously({ + const running = new QuoterBotService(setup, bootstrap, ladder).runContinuously({ signal: controller.signal }) diff --git a/bots/market-making/test/application/setup/setup-check.service.test.ts b/bots/quoter-bot/test/application/setup/setup-check.service.test.ts similarity index 100% rename from bots/market-making/test/application/setup/setup-check.service.test.ts rename to bots/quoter-bot/test/application/setup/setup-check.service.test.ts diff --git a/bots/market-making/test/application/version.service.test.ts b/bots/quoter-bot/test/application/version.service.test.ts similarity index 100% rename from bots/market-making/test/application/version.service.test.ts rename to bots/quoter-bot/test/application/version.service.test.ts diff --git a/bots/market-making/test/bootstrap.test.ts b/bots/quoter-bot/test/bootstrap.test.ts similarity index 98% rename from bots/market-making/test/bootstrap.test.ts rename to bots/quoter-bot/test/bootstrap.test.ts index 35b3817c..8b426ddb 100644 --- a/bots/market-making/test/bootstrap.test.ts +++ b/bots/quoter-bot/test/bootstrap.test.ts @@ -200,7 +200,7 @@ describe('createApplication', () => { ])( 'CLI --%s clears the opposite YAML keystore password mode', async (_mode, yamlPasswordMode, cliPasswordMode, expectedPassword) => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-cli-precedence-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-cli-precedence-')) const configPath = join(directory, 'operator.yaml') await writeFile( configPath, @@ -291,7 +291,7 @@ describe('createApplication', () => { expect(events).toEqual(['preflight', 'list', `invalidateBatch:${groupId}`, `forget:${groupId}`]) }) - test('mm bootstrap passes readiness before composing one bootstrap cycle', async () => { + test('quoter-bot bootstrap passes readiness before composing one bootstrap cycle', async () => { const events: string[] = [] const state = readyState() state.getChainId = async () => { @@ -542,7 +542,7 @@ describe('createApplication', () => { await expect(application.run(['setup-check'])).rejects.toBeInstanceOf(ConfigValidationError) }) - test('mm ladder passes readiness before running one ladder cycle', async () => { + test('quoter-bot ladder passes readiness before running one ladder cycle', async () => { const events: string[] = [] const state = readyState() state.getChainId = async () => { @@ -1092,7 +1092,7 @@ describe('createApplication', () => { }) test('wires explicit --config and default working-directory discovery into startup', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-bootstrap-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-bootstrap-')) const configuration = ` chain: id: 8453 @@ -1116,7 +1116,7 @@ setup: maximumLendExposureAssets: "100" ` try { - await writeFile(join(directory, 'market-making.yml'), configuration) + await writeFile(join(directory, 'quoter-bot.yml'), configuration) await writeFile( join(directory, 'explicit.yaml'), configuration.replace('yaml-rpc', 'explicit-rpc') diff --git a/bots/market-making/test/config/config-loading.test.ts b/bots/quoter-bot/test/config/config-loading.test.ts similarity index 97% rename from bots/market-making/test/config/config-loading.test.ts rename to bots/quoter-bot/test/config/config-loading.test.ts index 27cc9220..b3cd7019 100644 --- a/bots/market-making/test/config/config-loading.test.ts +++ b/bots/quoter-bot/test/config/config-loading.test.ts @@ -36,7 +36,7 @@ const environment = { const directories: string[] = [] const temporaryDirectory = async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-config-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-config-')) directories.push(directory) return directory } @@ -360,9 +360,9 @@ describe('ConfigService YAML and environment loading', () => { test('discovers .yaml first when both default filenames exist', async () => { const directory = await temporaryDirectory() - await writeFile(join(directory, 'market-making.yaml'), yaml()) + await writeFile(join(directory, 'quoter-bot.yaml'), yaml()) await writeFile( - join(directory, 'market-making.yml'), + join(directory, 'quoter-bot.yml'), yaml().replace('https://rpc.yaml.example', 'https://rpc.fallback.example') ) expect((await ConfigService.load({}, { cwd: directory })).rpcUrl).toBe( @@ -370,10 +370,10 @@ describe('ConfigService YAML and environment loading', () => { ) }) - test('falls back to market-making.yml when market-making.yaml is absent', async () => { + test('falls back to quoter-bot.yml when quoter-bot.yaml is absent', async () => { const directory = await temporaryDirectory() await writeFile( - join(directory, 'market-making.yml'), + join(directory, 'quoter-bot.yml'), yaml().replace('https://rpc.yaml.example', 'https://rpc.fallback.example') ) expect((await ConfigService.load({}, { cwd: directory })).rpcUrl).toBe( @@ -393,10 +393,10 @@ describe('ConfigService YAML and environment loading', () => { expect(result.stdout).toContain('"reason":"unreadable-explicit"') }) - test('a discovered market-making.yaml FIFO fails closed without falling back', async () => { + test('a discovered quoter-bot.yaml FIFO fails closed without falling back', async () => { const directory = await temporaryDirectory() - await createFifo(join(directory, 'market-making.yaml')) - await writeFile(join(directory, 'market-making.yml'), yaml()) + await createFifo(join(directory, 'quoter-bot.yaml')) + await writeFile(join(directory, 'quoter-bot.yml'), yaml()) const result = await loadInBoundedSubprocess({ cwd: directory }) @@ -407,7 +407,7 @@ describe('ConfigService YAML and environment loading', () => { test('an explicit .yml path wins over default discovery', async () => { const directory = await temporaryDirectory() - await writeFile(join(directory, 'market-making.yaml'), yaml()) + await writeFile(join(directory, 'quoter-bot.yaml'), yaml()) await writeFile( join(directory, 'chosen.yml'), yaml().replace('https://rpc.yaml.example', 'https://rpc.explicit.example') @@ -433,7 +433,7 @@ describe('ConfigService YAML and environment loading', () => { const directory = await temporaryDirectory() const target = join(directory, 'target.yaml') const explicitLink = join(directory, 'operator.yaml') - const discoveredLink = join(directory, 'market-making.yaml') + const discoveredLink = join(directory, 'quoter-bot.yaml') await writeFile(target, yaml()) await symlink(target, explicitLink) await symlink(target, discoveredLink) @@ -459,8 +459,8 @@ describe('ConfigService YAML and environment loading', () => { test('rejects a dangling discovered YAML symlink without .yml or env-only fallback', async () => { const directory = await temporaryDirectory() - await symlink(join(directory, 'missing-target.yaml'), join(directory, 'market-making.yaml')) - await writeFile(join(directory, 'market-making.yml'), yaml()) + await symlink(join(directory, 'missing-target.yaml'), join(directory, 'quoter-bot.yaml')) + await writeFile(join(directory, 'quoter-bot.yml'), yaml()) const error = await ConfigService.load(environment, { cwd: directory }).catch(error => error) @@ -558,7 +558,7 @@ describe('ConfigService YAML and environment loading', () => { expect(error).toBeInstanceOf(ConfigFileError) expect(error.reason).toBe('unreadable-discovered') - expect(opened).toEqual(['/virtual/market-making.yaml']) + expect(opened).toEqual(['/virtual/quoter-bot.yaml']) expect(closed).toBe(true) } ) @@ -595,7 +595,7 @@ describe('ConfigService YAML and environment loading', () => { expect(error).toBeInstanceOf(ConfigFileError) expect(error.reason).toBe('unreadable-discovered') - expect(opened).toEqual(['/virtual/market-making.yaml']) + expect(opened).toEqual(['/virtual/quoter-bot.yaml']) }) test('rejects an explicit configuration path without a .yaml or .yml extension', async () => { diff --git a/bots/market-making/test/config/config-private-key.test.ts b/bots/quoter-bot/test/config/config-private-key.test.ts similarity index 100% rename from bots/market-making/test/config/config-private-key.test.ts rename to bots/quoter-bot/test/config/config-private-key.test.ts diff --git a/bots/market-making/test/config/config.service.test.ts b/bots/quoter-bot/test/config/config.service.test.ts similarity index 100% rename from bots/market-making/test/config/config.service.test.ts rename to bots/quoter-bot/test/config/config.service.test.ts diff --git a/bots/market-making/test/config/config.utils.test.ts b/bots/quoter-bot/test/config/config.utils.test.ts similarity index 100% rename from bots/market-making/test/config/config.utils.test.ts rename to bots/quoter-bot/test/config/config.utils.test.ts diff --git a/bots/market-making/test/config/key-storage.test.ts b/bots/quoter-bot/test/config/key-storage.test.ts similarity index 96% rename from bots/market-making/test/config/key-storage.test.ts rename to bots/quoter-bot/test/config/key-storage.test.ts index f3f32647..7fddf734 100644 --- a/bots/market-making/test/config/key-storage.test.ts +++ b/bots/quoter-bot/test/config/key-storage.test.ts @@ -119,13 +119,13 @@ describe('maker key storage configuration', () => { const config = ConfigService.from({ ...baseEnvironment, KEY_STORAGE_METHOD: 'aws', - AWS_KMS_KEY_ID: 'alias/market-maker', + AWS_KMS_KEY_ID: 'alias/quoter', AWS_REGION: 'eu-west-1' }) expect(config.keyStorageMethod).toBe('aws') expect(config.identity).toMatchObject({ method: 'aws', - keyId: 'alias/market-maker', + keyId: 'alias/quoter', region: 'eu-west-1' }) expect(config.privateKey).toBeUndefined() @@ -188,7 +188,7 @@ describe('maker key storage configuration', () => { }) test('environment source selection overrides the YAML source while scalar environment values still win', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-key-storage-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-key-storage-')) directories.push(directory) const path = join(directory, 'operator.yaml') await writeFile( @@ -236,7 +236,7 @@ describe('maker key storage configuration', () => { ])( 'blank environment signer selectors do not override valid YAML %s configuration', async (_method, identity, signerEnvironment, expectedIdentity) => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-key-storage-blank-env-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-key-storage-blank-env-')) directories.push(directory) const path = join(directory, 'operator.yaml') await writeFile(path, configurationYaml(identity)) @@ -248,7 +248,7 @@ describe('maker key storage configuration', () => { ) test('a whitespace-only environment password overrides the YAML password byte-for-byte', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-key-storage-password-env-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-key-storage-password-env-')) directories.push(directory) const path = join(directory, 'operator.yaml') await writeFile( @@ -285,7 +285,7 @@ describe('maker key storage configuration', () => { ])( 'non-blank malformed %s still reaches final validation', async (_field, signerEnvironment, reason, identity) => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-key-storage-invalid-env-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-key-storage-invalid-env-')) directories.push(directory) const path = join(directory, 'operator.yaml') await writeFile(path, configurationYaml(identity)) diff --git a/bots/market-making/test/config/ladder-config.test.ts b/bots/quoter-bot/test/config/ladder-config.test.ts similarity index 99% rename from bots/market-making/test/config/ladder-config.test.ts rename to bots/quoter-bot/test/config/ladder-config.test.ts index 1ba7373d..2c18b4b5 100644 --- a/bots/market-making/test/config/ladder-config.test.ts +++ b/bots/quoter-bot/test/config/ladder-config.test.ts @@ -204,7 +204,7 @@ describe('ladder configuration loading', () => { expect(ConfigService.from(baseEnvironment).ladder).toEqual([]) const directory = await mkdtemp(join(tmpdir(), 'ladder-config-')) directories.push(directory) - const path = join(directory, 'market-making.yaml') + const path = join(directory, 'quoter-bot.yaml') const yamlItem = Object.entries(item()) .map(([key, value]) => ` ${key}: '${value}'`) .join('\n') diff --git a/bots/market-making/test/domain/bootstrap/position-bootstrap.test.ts b/bots/quoter-bot/test/domain/bootstrap/position-bootstrap.test.ts similarity index 100% rename from bots/market-making/test/domain/bootstrap/position-bootstrap.test.ts rename to bots/quoter-bot/test/domain/bootstrap/position-bootstrap.test.ts diff --git a/bots/market-making/test/domain/ladder/ladder.test.ts b/bots/quoter-bot/test/domain/ladder/ladder.test.ts similarity index 100% rename from bots/market-making/test/domain/ladder/ladder.test.ts rename to bots/quoter-bot/test/domain/ladder/ladder.test.ts diff --git a/bots/market-making/test/e2e/anvil-startup.error.ts b/bots/quoter-bot/test/e2e/anvil-startup.error.ts similarity index 100% rename from bots/market-making/test/e2e/anvil-startup.error.ts rename to bots/quoter-bot/test/e2e/anvil-startup.error.ts diff --git a/bots/market-making/test/e2e/anvil.ts b/bots/quoter-bot/test/e2e/anvil.ts similarity index 99% rename from bots/market-making/test/e2e/anvil.ts rename to bots/quoter-bot/test/e2e/anvil.ts index ebc724c3..95b3b057 100644 --- a/bots/market-making/test/e2e/anvil.ts +++ b/bots/quoter-bot/test/e2e/anvil.ts @@ -25,7 +25,7 @@ const requireForkUrl = () => { const forkUrl = process.env.RPC_URL_8453?.trim() if (!forkUrl) { throw new AnvilStartupError( - 'RPC_URL_8453 is required to start the pinned Base fork for market-making e2e tests' + 'RPC_URL_8453 is required to start the pinned Base fork for quoter-bot e2e tests' ) } return forkUrl diff --git a/bots/market-making/test/e2e/constants.ts b/bots/quoter-bot/test/e2e/constants.ts similarity index 100% rename from bots/market-making/test/e2e/constants.ts rename to bots/quoter-bot/test/e2e/constants.ts diff --git a/bots/market-making/test/e2e/setup-api.ts b/bots/quoter-bot/test/e2e/setup-api.ts similarity index 100% rename from bots/market-making/test/e2e/setup-api.ts rename to bots/quoter-bot/test/e2e/setup-api.ts diff --git a/bots/market-making/test/e2e/setup-check.e2e.test.ts b/bots/quoter-bot/test/e2e/setup-check.e2e.test.ts similarity index 97% rename from bots/market-making/test/e2e/setup-check.e2e.test.ts rename to bots/quoter-bot/test/e2e/setup-check.e2e.test.ts index d8f00673..faeb6042 100644 --- a/bots/market-making/test/e2e/setup-check.e2e.test.ts +++ b/bots/quoter-bot/test/e2e/setup-check.e2e.test.ts @@ -29,7 +29,7 @@ const isSetupCheckReport = (value: unknown): value is SetupCheckReport => 'checks' in value && Array.isArray(value.checks) -describe('market-making setup check on a pinned Base fork', () => { +describe('quoter-bot setup check on a pinned Base fork', () => { let anvil: AnvilHandle | undefined let api: SetupApiHandle | undefined diff --git a/bots/market-making/test/e2e/setup-maker.ts b/bots/quoter-bot/test/e2e/setup-maker.ts similarity index 97% rename from bots/market-making/test/e2e/setup-maker.ts rename to bots/quoter-bot/test/e2e/setup-maker.ts index 45a397aa..e0328259 100644 --- a/bots/market-making/test/e2e/setup-maker.ts +++ b/bots/quoter-bot/test/e2e/setup-maker.ts @@ -35,7 +35,7 @@ const tokenBalanceStorageKey = () => ) /** - * Funds and authorizes Anvil's default account as the market maker. + * Funds and authorizes Anvil's default account as the quoter. * * @param anvil - Running pinned Base fork. * @returns The seeded USDC balance and receipts for the approval and ratifier authorization. diff --git a/bots/market-making/test/error-convention.test.ts b/bots/quoter-bot/test/error-convention.test.ts similarity index 98% rename from bots/market-making/test/error-convention.test.ts rename to bots/quoter-bot/test/error-convention.test.ts index 8e7649ac..7b577faf 100644 --- a/bots/market-making/test/error-convention.test.ts +++ b/bots/quoter-bot/test/error-convention.test.ts @@ -52,7 +52,7 @@ const inspect = (file: string) => { return { source, errorClasses, plainErrors } } -describe('market-making error convention', () => { +describe('quoter-bot error convention', () => { test('keeps each exported Error subclass alone in its matching kebab-case error file', () => { const failures: string[] = [] for (const file of sourceFiles) { diff --git a/bots/market-making/test/fixtures/ecrecover-ratifier-base.hex b/bots/quoter-bot/test/fixtures/ecrecover-ratifier-base.hex similarity index 100% rename from bots/market-making/test/fixtures/ecrecover-ratifier-base.hex rename to bots/quoter-bot/test/fixtures/ecrecover-ratifier-base.hex diff --git a/bots/market-making/test/fixtures/setter-ratifier-base.hex b/bots/quoter-bot/test/fixtures/setter-ratifier-base.hex similarity index 100% rename from bots/market-making/test/fixtures/setter-ratifier-base.hex rename to bots/quoter-bot/test/fixtures/setter-ratifier-base.hex diff --git a/bots/market-making/test/infrastructure/bootstrap/bootstrap-make.service.test.ts b/bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-make.service.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/bootstrap/bootstrap-make.service.test.ts rename to bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-make.service.test.ts diff --git a/bots/market-making/test/infrastructure/bootstrap/bootstrap-mempool-validation.utils.test.ts b/bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-mempool-validation.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/bootstrap/bootstrap-mempool-validation.utils.test.ts rename to bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-mempool-validation.utils.test.ts diff --git a/bots/market-making/test/infrastructure/bootstrap/bootstrap-pending-offer.utils.test.ts b/bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-pending-offer.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/bootstrap/bootstrap-pending-offer.utils.test.ts rename to bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-pending-offer.utils.test.ts diff --git a/bots/market-making/test/infrastructure/bootstrap/bootstrap-position.service.test.ts b/bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-position.service.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/bootstrap/bootstrap-position.service.test.ts rename to bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-position.service.test.ts diff --git a/bots/market-making/test/infrastructure/bootstrap/bootstrap-reference-rate.service.test.ts b/bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-reference-rate.service.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/bootstrap/bootstrap-reference-rate.service.test.ts rename to bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-reference-rate.service.test.ts diff --git a/bots/market-making/test/infrastructure/bootstrap/bootstrap-requirement-client.utils.test.ts b/bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-requirement-client.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/bootstrap/bootstrap-requirement-client.utils.test.ts rename to bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-requirement-client.utils.test.ts diff --git a/bots/market-making/test/infrastructure/bootstrap/bootstrap-spread.utils.test.ts b/bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-spread.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/bootstrap/bootstrap-spread.utils.test.ts rename to bots/quoter-bot/test/infrastructure/bootstrap/bootstrap-spread.utils.test.ts diff --git a/bots/market-making/test/infrastructure/bootstrap/production-bootstrap.test.ts b/bots/quoter-bot/test/infrastructure/bootstrap/production-bootstrap.test.ts similarity index 99% rename from bots/market-making/test/infrastructure/bootstrap/production-bootstrap.test.ts rename to bots/quoter-bot/test/infrastructure/bootstrap/production-bootstrap.test.ts index b545130f..cc6df0c3 100644 --- a/bots/market-making/test/infrastructure/bootstrap/production-bootstrap.test.ts +++ b/bots/quoter-bot/test/infrastructure/bootstrap/production-bootstrap.test.ts @@ -968,7 +968,7 @@ describe('readBootstrapGroups', () => { describe('createBootstrapGroupOwnership', () => { test('persists reservations across instances and removes unpublished IDs safely', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-reservation-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-reservation-')) const ownership = createBootstrapGroupOwnership( { maker, marketIds: [marketId], configuredGroupIds: [] }, { stateDirectory: directory } @@ -990,7 +990,7 @@ describe('createBootstrapGroupOwnership', () => { }) test('persists the intended offer metadata used to rehydrate a confirmed group', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-offer-metadata-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-offer-metadata-')) const ownership = createBootstrapGroupOwnership( { maker, marketIds: [marketId], configuredGroupIds: [] }, { stateDirectory: directory } @@ -1018,7 +1018,7 @@ describe('createBootstrapGroupOwnership', () => { }) test('rejects a negative protocol tick before persisting offer ownership', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-invalid-tick-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-invalid-tick-')) const ownership = createBootstrapGroupOwnership( { maker, marketIds: [marketId], configuredGroupIds: [] }, { stateDirectory: directory } @@ -1044,7 +1044,7 @@ describe('createBootstrapGroupOwnership', () => { }) test('retains bot-issued IDs across instances without sharing them with another strategy', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-ownership-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-ownership-')) const ownership = createBootstrapGroupOwnership( { maker, marketIds: [marketId], configuredGroupIds: [] }, { stateDirectory: directory } @@ -1070,7 +1070,7 @@ describe('createBootstrapGroupOwnership', () => { }) test('forgets canceled persisted groups while retaining configured ownership', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-making-forget-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-bot-forget-')) const configuredGroupId: Hex = `0x${'34'.repeat(32)}` const ownership = createBootstrapGroupOwnership( { maker, marketIds: [marketId], configuredGroupIds: [configuredGroupId] }, diff --git a/bots/market-making/test/infrastructure/cli/cli.test.ts b/bots/quoter-bot/test/infrastructure/cli/cli.test.ts similarity index 92% rename from bots/market-making/test/infrastructure/cli/cli.test.ts rename to bots/quoter-bot/test/infrastructure/cli/cli.test.ts index 1d6fb2bc..8a1c2150 100644 --- a/bots/market-making/test/infrastructure/cli/cli.test.ts +++ b/bots/quoter-bot/test/infrastructure/cli/cli.test.ts @@ -10,12 +10,12 @@ import { PositionBootstrapMonitorHaltedError } from '../../../src/application/bo import { OfferInvalidationFailedError } from '../../../src/application/invalidation/offer-invalidation-failed.error' import { LadderCycleHaltedError } from '../../../src/application/ladder/ladder-cycle-halted.error' import { LadderMonitorHaltedError } from '../../../src/application/ladder/ladder-monitor-halted.error' -import { MarketMakingMonitorHaltedError } from '../../../src/application/market-making/market-making-monitor-halted.error' +import { QuoterBotMonitorHaltedError } from '../../../src/application/quoter-bot/quoter-bot-monitor-halted.error' import { SetupMonitorHaltedError } from '../../../src/application/setup/setup-monitor-halted.error' import { VersionService } from '../../../src/application/version.service' import { Cli } from '../../../src/infrastructure/cli/cli' import { CliUsageError } from '../../../src/infrastructure/cli/cli-usage.error' -import { runMarketMakingEntrypoint } from '../../../src/infrastructure/cli/market-making-entrypoint' +import { runQuoterBotEntrypoint } from '../../../src/infrastructure/cli/quoter-bot-entrypoint' const readyReport = { ready: true, @@ -54,7 +54,7 @@ const runEntrypointWith = async ( env: { PATH: process.env.PATH, ...env }, extendEnv: false, reject: false - })`tsx bots/market-making/src/index.ts ${argv}` + })`tsx bots/quoter-bot/src/index.ts ${argv}` return { exitCode: exitCode ?? 0, stdout, stderr } } @@ -71,7 +71,7 @@ const expectHumanFailure = (stderr: string[], message: string, details: unknown) } describe('Cli', () => { - test('mm --version returns 0.0.0', async () => { + test('quoter-bot --version returns 0.0.0', async () => { expect(await cli().run(['--version'])).toBe('0.0.0') }) @@ -133,7 +133,7 @@ describe('Cli', () => { for (const marker of markers) expect(output).not.toContain(marker) }) - test('mm -v is an alias for --version', async () => { + test('quoter-bot -v is an alias for --version', async () => { expect(await cli().run(['-v'])).toBe('0.0.0') }) @@ -234,7 +234,7 @@ describe('Cli', () => { expect(await cli().run(['setup-check'])).toEqual(readyReport) }) - test('mm setup-check --monitor streams readiness reports until shutdown', async () => { + test('quoter-bot setup-check --monitor streams readiness reports until shutdown', async () => { const report = { status: 'stopped' as const, reason: 'signal' as const, @@ -272,7 +272,7 @@ describe('Cli', () => { expect(assertReady).not.toHaveBeenCalled() }) - test('mm setup-check --monitor rejects a halted lifecycle report', async () => { + test('quoter-bot setup-check --monitor rejects a halted lifecycle report', async () => { const report = { status: 'halted' as const, reason: 'setup-failed' as const, @@ -295,7 +295,7 @@ describe('Cli', () => { expect(error).toMatchObject({ report }) }) - test('mm bootstrap triggers one explicit position-bootstrap run', async () => { + test('quoter-bot bootstrap triggers one explicit position-bootstrap run', async () => { const runOnce = vi.fn(async () => [ { marketId: `0x${'11'.repeat(32)}`, status: 'applied', action: 'publish', assets: 10n } ]) @@ -313,7 +313,7 @@ describe('Cli', () => { expect(runOnce).toHaveBeenCalledWith({ verbose: false }) }) - test('mm bootstrap --verbose requests expanded bootstrap diagnostics', async () => { + test('quoter-bot bootstrap --verbose requests expanded bootstrap diagnostics', async () => { const txHash = `0x${'aa'.repeat(32)}` as const const runOnce = vi.fn( async (parameters?: { @@ -357,7 +357,7 @@ describe('Cli', () => { ]) }) - test('mm bootstrap --monitor streams cycles and returns shutdown cleanup evidence', async () => { + test('quoter-bot bootstrap --monitor streams cycles and returns shutdown cleanup evidence', async () => { const cycle = [{ marketId: `0x${'11'.repeat(32)}`, status: 'observed', action: 'rest' }] const report = { status: 'stopped' as const, @@ -398,7 +398,7 @@ describe('Cli', () => { expect(runOnce).not.toHaveBeenCalled() }) - test('mm bootstrap --monitor --verbose forwards verbose monitoring', async () => { + test('quoter-bot bootstrap --monitor --verbose forwards verbose monitoring', async () => { const controller = new AbortController() const runContinuously = vi.fn( async (_parameters: { signal: AbortSignal; verbose?: boolean }) => ({ @@ -425,7 +425,7 @@ describe('Cli', () => { }) }) - test('mm bootstrap --monitor preserves a halted terminal report object', async () => { + test('quoter-bot bootstrap --monitor preserves a halted terminal report object', async () => { const report = { status: 'halted' as const, reason: 'cycle-failed' as const, @@ -457,7 +457,7 @@ describe('Cli', () => { expect(error).toMatchObject({ report }) }) - test('mm ladder is exposed alongside setup-check and bootstrap', async () => { + test('quoter-bot ladder is exposed alongside setup-check and bootstrap', async () => { const assertReady = vi.fn(async () => readyReport) const bootstrap = vi.fn(async () => []) const runOnce = vi.fn(async () => [ @@ -478,7 +478,7 @@ describe('Cli', () => { expect(bootstrap).not.toHaveBeenCalled() }) - test('mm invalidate targets every active maker group and streams submitted hashes', async () => { + test('quoter-bot invalidate targets every active maker group and streams submitted hashes', async () => { const groupId = `0x${'12'.repeat(32)}` as const const txHash = `0x${'ab'.repeat(32)}` as const const report = { @@ -526,7 +526,7 @@ describe('Cli', () => { ]) }) - test('mm invalidate canonicalizes one explicit group and forwards read-only mode', async () => { + test('quoter-bot invalidate canonicalizes one explicit group and forwards read-only mode', async () => { const groupId = `0x${'ab'.repeat(32)}` as const let readOnly: boolean | undefined const run = vi.fn(async (_parameters?: { groupId?: `0x${string}` }) => ({ @@ -552,7 +552,7 @@ describe('Cli', () => { expect(run.mock.calls[0]?.[0]?.groupId).toBe(groupId) }) - test('mm invalidate rejects a malformed group before constructing the writer', async () => { + test('quoter-bot invalidate rejects a malformed group before constructing the writer', async () => { const invalidation = vi.fn(() => ({ run: async () => undefined as never })) const application = new Cli( new VersionService(), @@ -568,7 +568,7 @@ describe('Cli', () => { expect(invalidation).not.toHaveBeenCalled() }) - test('mm ladder --monitor --verbose --readonly streams cycles and cleanup evidence', async () => { + test('quoter-bot ladder --monitor --verbose --readonly streams cycles and cleanup evidence', async () => { const marketId = `0x${'11'.repeat(32)}` as const const txHash = `0x${'aa'.repeat(32)}` as const const cycle = [{ marketId, status: 'observed' as const, action: 'rest' as const }] @@ -630,7 +630,7 @@ describe('Cli', () => { ]) }) - test('mm ladder --monitor rejects a halted lifecycle report', async () => { + test('quoter-bot ladder --monitor rejects a halted lifecycle report', async () => { const report = { status: 'halted' as const, reason: 'cycle-failed' as const, @@ -662,9 +662,9 @@ describe('Cli', () => { expect(error).toMatchObject({ report }) }) - test('mm start forwards the shared signal, verbose mode, read-only mode, and events', async () => { + test('quoter-bot start forwards the shared signal, verbose mode, read-only mode, and events', async () => { const event = { - event: 'market-making.cycle' as const, + event: 'quoter-bot.cycle' as const, workflow: 'setup-check' as const, report: readyReport } @@ -742,7 +742,7 @@ describe('Cli', () => { expect(streamed).toEqual([event]) }) - test('mm start rejects a halted combined lifecycle report', async () => { + test('quoter-bot start rejects a halted combined lifecycle report', async () => { const report = { status: 'halted' as const, reason: 'workflow-error' as const, @@ -779,7 +779,7 @@ describe('Cli', () => { const error = await application.run(['start']).catch(value => value) - expect(error).toBeInstanceOf(MarketMakingMonitorHaltedError) + expect(error).toBeInstanceOf(QuoterBotMonitorHaltedError) expect(error).toMatchObject({ report }) }) @@ -871,7 +871,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => ({ ready: true, checks: [{ name: 'chain', status: 'passed' }] }) }, ['setup-check'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } @@ -898,7 +898,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async (_argv, runtime) => { await runtime?.writeEvent?.({ event: 'cycle.completed', assets: 7n }) @@ -922,7 +922,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new Error('Bot cycle failed')) }, ['ladder'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } @@ -936,7 +936,7 @@ describe('Cli', () => { test('entrypoint emits one structured JSON error record with --json', async () => { const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new Error('Bot cycle failed')) }, ['--json', 'ladder'], { writeOut: () => {}, writeError: value => stderr.push(value) } @@ -946,7 +946,7 @@ describe('Cli', () => { expect(stderr).toHaveLength(1) expect(JSON.parse(stderr[0] ?? '')).toEqual({ level: 'error', - event: 'market-making.error', + event: 'quoter-bot.error', message: 'UnknownError' }) expect(stderr[0]).not.toContain('\n') @@ -972,7 +972,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new PositionBootstrapHaltedError(report)) }, ['bootstrap'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } @@ -1000,7 +1000,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new OfferInvalidationFailedError(report)) }, ['invalidate'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } @@ -1021,7 +1021,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new SetupMonitorHaltedError(report)) }, ['setup-check', '--monitor'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } @@ -1061,7 +1061,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new PositionBootstrapMonitorHaltedError(report)) }, ['bootstrap', '--monitor'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } @@ -1083,7 +1083,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async (_argv, runtime) => { await runtime?.writeEvent?.(cycle) @@ -1112,7 +1112,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new LadderCycleHaltedError(report)) }, ['ladder'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } @@ -1133,7 +1133,7 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new LadderMonitorHaltedError(report)) }, ['ladder', '--monitor'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } @@ -1173,15 +1173,15 @@ describe('Cli', () => { const stdout: string[] = [] const stderr: string[] = [] - const exitCode = await runMarketMakingEntrypoint( - { run: async () => Promise.reject(new MarketMakingMonitorHaltedError(report)) }, + const exitCode = await runQuoterBotEntrypoint( + { run: async () => Promise.reject(new QuoterBotMonitorHaltedError(report)) }, ['start'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) } ) expect(exitCode).toBe(1) expect(stdout).toEqual([]) - expectHumanFailure(stderr, 'Market making monitor halted for safety', report) + expectHumanFailure(stderr, 'Quoter bot monitor halted for safety', report) }) test('propagates a readiness failure for a deterministic non-zero entrypoint exit', async () => { diff --git a/bots/market-making/test/infrastructure/cli/key-storage-cli.test.ts b/bots/quoter-bot/test/infrastructure/cli/key-storage-cli.test.ts similarity index 98% rename from bots/market-making/test/infrastructure/cli/key-storage-cli.test.ts rename to bots/quoter-bot/test/infrastructure/cli/key-storage-cli.test.ts index f912dc52..862a47b8 100644 --- a/bots/market-making/test/infrastructure/cli/key-storage-cli.test.ts +++ b/bots/quoter-bot/test/infrastructure/cli/key-storage-cli.test.ts @@ -117,7 +117,7 @@ describe('maker key storage CLI options', () => { test('entrypoint --help emits both argv warnings without exposing an ambient secret', async () => { const secret = 'must-not-appear-in-help-output' const repoRoot = dirname(fileURLToPath(new URL('../../../../../package.json', import.meta.url))) - const process = await execa('tsx', ['bots/market-making/src/index.ts', '--help'], { + const process = await execa('tsx', ['bots/quoter-bot/src/index.ts', '--help'], { cwd: repoRoot, env: { MAKER_PRIVATE_KEY: secret, KEYSTORE_PASSWORD: secret }, reject: false diff --git a/bots/market-making/test/infrastructure/cli/password-prompt.test.ts b/bots/quoter-bot/test/infrastructure/cli/password-prompt.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/cli/password-prompt.test.ts rename to bots/quoter-bot/test/infrastructure/cli/password-prompt.test.ts diff --git a/bots/market-making/test/infrastructure/cli/market-making-entrypoint-observability.test.ts b/bots/quoter-bot/test/infrastructure/cli/quoter-bot-entrypoint-observability.test.ts similarity index 84% rename from bots/market-making/test/infrastructure/cli/market-making-entrypoint-observability.test.ts rename to bots/quoter-bot/test/infrastructure/cli/quoter-bot-entrypoint-observability.test.ts index 581fb379..6341bb36 100644 --- a/bots/market-making/test/infrastructure/cli/market-making-entrypoint-observability.test.ts +++ b/bots/quoter-bot/test/infrastructure/cli/quoter-bot-entrypoint-observability.test.ts @@ -3,12 +3,12 @@ import { describe, expect, test, vi } from 'vitest' import { ConfigFileError } from '../../../src/config/config-file.error' import { - MARKET_MAKING_VERBOSE_COMMANDS, - runMarketMakingEntrypoint -} from '../../../src/infrastructure/cli/market-making-entrypoint' + QUOTER_BOT_VERBOSE_COMMANDS, + runQuoterBotEntrypoint +} from '../../../src/infrastructure/cli/quoter-bot-entrypoint' import { MakerAccountError } from '../../../src/infrastructure/make/maker-account.error' -describe('runMarketMakingEntrypoint observability', () => { +describe('runQuoterBotEntrypoint observability', () => { test('mirrors streamed actions and terminal results while preserving stdout', async () => { const stdout: string[] = [] const stderr: string[] = [] @@ -16,7 +16,7 @@ describe('runMarketMakingEntrypoint observability', () => { const cycle = { event: 'ladder.cycle', status: 'resting', activeOffers: [{ assets: 9n }] } const result = { status: 'stopped', cycles: 1 } - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async (_argv, runtime) => { await runtime?.writeEvent?.(cycle) @@ -45,7 +45,7 @@ describe('runMarketMakingEntrypoint observability', () => { const error = new Error('raw provider payload with api credential') error.name = 'ProviderFailureError' - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(error) }, ['start'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) }, @@ -66,7 +66,7 @@ describe('runMarketMakingEntrypoint observability', () => { const unexpected = vi.fn((_error: unknown, _origin: 'entrypoint') => undefined) const error = new MakerAccountError('keystore-decrypt') - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(error) }, ['setup-check'], { writeOut: () => undefined, writeError: value => stderr.push(value) }, @@ -88,7 +88,7 @@ describe('runMarketMakingEntrypoint observability', () => { }) error.name = 'ProviderFailureError' - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(error) }, ['start'], { writeOut: value => stdout.push(value), writeError: value => stderr.push(value) }, @@ -109,14 +109,14 @@ describe('runMarketMakingEntrypoint observability', () => { BETTERSTACK_INGESTING_HOST: 's1.betterstackdata.com' } - expect(MARKET_MAKING_VERBOSE_COMMANDS).toEqual(['start', 'bootstrap', 'ladder']) - for (const command of MARKET_MAKING_VERBOSE_COMMANDS) { - expect( - enhanceVerboseArgv([command], { commands: MARKET_MAKING_VERBOSE_COMMANDS, env }) - ).toEqual([command, '--verbose']) + expect(QUOTER_BOT_VERBOSE_COMMANDS).toEqual(['start', 'bootstrap', 'ladder']) + for (const command of QUOTER_BOT_VERBOSE_COMMANDS) { + expect(enhanceVerboseArgv([command], { commands: QUOTER_BOT_VERBOSE_COMMANDS, env })).toEqual( + [command, '--verbose'] + ) } expect( - enhanceVerboseArgv(['setup-check'], { commands: MARKET_MAKING_VERBOSE_COMMANDS, env }) + enhanceVerboseArgv(['setup-check'], { commands: QUOTER_BOT_VERBOSE_COMMANDS, env }) ).toEqual(['setup-check']) }) @@ -124,7 +124,7 @@ describe('runMarketMakingEntrypoint observability', () => { const stderr: string[] = [] const unexpected = vi.fn((_error: unknown, _origin: 'entrypoint') => undefined) - const exitCode = await runMarketMakingEntrypoint( + const exitCode = await runQuoterBotEntrypoint( { run: async () => Promise.reject(new ConfigFileError('malformed')) }, ['start'], { writeOut: () => undefined, writeError: value => stderr.push(value) }, diff --git a/bots/market-making/test/infrastructure/invalidation/batch-offer-invalidation-transaction.utils.test.ts b/bots/quoter-bot/test/infrastructure/invalidation/batch-offer-invalidation-transaction.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/invalidation/batch-offer-invalidation-transaction.utils.test.ts rename to bots/quoter-bot/test/infrastructure/invalidation/batch-offer-invalidation-transaction.utils.test.ts diff --git a/bots/market-making/test/infrastructure/invalidation/batch-offer-invalidation.utils.test.ts b/bots/quoter-bot/test/infrastructure/invalidation/batch-offer-invalidation.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/invalidation/batch-offer-invalidation.utils.test.ts rename to bots/quoter-bot/test/infrastructure/invalidation/batch-offer-invalidation.utils.test.ts diff --git a/bots/market-making/test/infrastructure/invalidation/offer-invalidation-group.utils.test.ts b/bots/quoter-bot/test/infrastructure/invalidation/offer-invalidation-group.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/invalidation/offer-invalidation-group.utils.test.ts rename to bots/quoter-bot/test/infrastructure/invalidation/offer-invalidation-group.utils.test.ts diff --git a/bots/market-making/test/infrastructure/invalidation/offer-invalidation-transaction.utils.test.ts b/bots/quoter-bot/test/infrastructure/invalidation/offer-invalidation-transaction.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/invalidation/offer-invalidation-transaction.utils.test.ts rename to bots/quoter-bot/test/infrastructure/invalidation/offer-invalidation-transaction.utils.test.ts diff --git a/bots/market-making/test/infrastructure/invalidation/production-offer-invalidation.test.ts b/bots/quoter-bot/test/infrastructure/invalidation/production-offer-invalidation.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/invalidation/production-offer-invalidation.test.ts rename to bots/quoter-bot/test/infrastructure/invalidation/production-offer-invalidation.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-active-publication.utils.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-active-publication.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-active-publication.utils.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-active-publication.utils.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-cash-reservation.utils.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-cash-reservation.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-cash-reservation.utils.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-cash-reservation.utils.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-group-ownership.utils.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-group-ownership.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-group-ownership.utils.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-group-ownership.utils.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-make.service.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-make.service.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-make.service.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-make.service.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-offer.utils.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-offer.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-offer.utils.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-offer.utils.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-ratification.utils.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-ratification.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-ratification.utils.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-ratification.utils.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-signature.utils.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-signature.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-signature.utils.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-signature.utils.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-spread.utils.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-spread.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-spread.utils.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-spread.utils.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/ladder-transaction.utils.test.ts b/bots/quoter-bot/test/infrastructure/ladder/ladder-transaction.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/ladder-transaction.utils.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/ladder-transaction.utils.test.ts diff --git a/bots/market-making/test/infrastructure/ladder/production-ladder.test.ts b/bots/quoter-bot/test/infrastructure/ladder/production-ladder.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/ladder/production-ladder.test.ts rename to bots/quoter-bot/test/infrastructure/ladder/production-ladder.test.ts diff --git a/bots/market-making/test/infrastructure/make/maker-account.test.ts b/bots/quoter-bot/test/infrastructure/make/maker-account.test.ts similarity index 98% rename from bots/market-making/test/infrastructure/make/maker-account.test.ts rename to bots/quoter-bot/test/infrastructure/make/maker-account.test.ts index e323e7d3..fd22f93b 100644 --- a/bots/market-making/test/infrastructure/make/maker-account.test.ts +++ b/bots/quoter-bot/test/infrastructure/make/maker-account.test.ts @@ -95,7 +95,7 @@ describe('maker signer selection', () => { }) test('decrypts and signs with a real Web3 Secret Storage keystore', async () => { - const directory = await mkdtemp(join(tmpdir(), 'market-maker-keystore-')) + const directory = await mkdtemp(join(tmpdir(), 'quoter-keystore-')) const path = join(directory, 'maker.json') const password = ' actual-keystore-秘密🔐 ' try { @@ -131,7 +131,7 @@ describe('maker signer selection', () => { readOnly: false, maker, method: 'aws', - keyId: 'alias/market-maker', + keyId: 'alias/quoter', region: 'eu-west-1' }, { kms: { getPublicKey, signDigest } } @@ -152,9 +152,9 @@ describe('maker signer selection', () => { expect( await recoverTransactionAddress({ serializedTransaction: transaction as `0x02${string}` }) ).toBe(maker) - expect(getPublicKey).toHaveBeenCalledWith('alias/market-maker', 'eu-west-1') + expect(getPublicKey).toHaveBeenCalledWith('alias/quoter', 'eu-west-1') expect(signDigest).toHaveBeenCalledWith( - 'alias/market-maker', + 'alias/quoter', 'eu-west-1', Uint8Array.from(Buffer.from(hashMessage(message).slice(2), 'hex')) ) diff --git a/bots/market-making/test/infrastructure/make/managed-maker-account.utils.test.ts b/bots/quoter-bot/test/infrastructure/make/managed-maker-account.utils.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/make/managed-maker-account.utils.test.ts rename to bots/quoter-bot/test/infrastructure/make/managed-maker-account.utils.test.ts diff --git a/bots/market-making/test/infrastructure/make/read-only-make.service.test.ts b/bots/quoter-bot/test/infrastructure/make/read-only-make.service.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/make/read-only-make.service.test.ts rename to bots/quoter-bot/test/infrastructure/make/read-only-make.service.test.ts diff --git a/bots/market-making/test/infrastructure/setup-state/viem-setup-state.service.test.ts b/bots/quoter-bot/test/infrastructure/setup-state/viem-setup-state.service.test.ts similarity index 100% rename from bots/market-making/test/infrastructure/setup-state/viem-setup-state.service.test.ts rename to bots/quoter-bot/test/infrastructure/setup-state/viem-setup-state.service.test.ts diff --git a/bots/market-making/test/playground/artifact.test.ts b/bots/quoter-bot/test/playground/artifact.test.ts similarity index 97% rename from bots/market-making/test/playground/artifact.test.ts rename to bots/quoter-bot/test/playground/artifact.test.ts index 2795949f..3879cdba 100644 --- a/bots/market-making/test/playground/artifact.test.ts +++ b/bots/quoter-bot/test/playground/artifact.test.ts @@ -28,7 +28,7 @@ const productionBuild = async () => { const record = stdout.split(/\r?\n/).flatMap(line => { try { const value = JSON.parse(line) - return value.kind === 'market-making-playground-build' ? [value] : [] + return value.kind === 'quoter-bot-playground-build' ? [value] : [] } catch { return [] } diff --git a/bots/market-making/test/playground/field-visibility.utils.test.ts b/bots/quoter-bot/test/playground/field-visibility.utils.test.ts similarity index 100% rename from bots/market-making/test/playground/field-visibility.utils.test.ts rename to bots/quoter-bot/test/playground/field-visibility.utils.test.ts diff --git a/bots/market-making/test/playground/model.test.ts b/bots/quoter-bot/test/playground/model.test.ts similarity index 100% rename from bots/market-making/test/playground/model.test.ts rename to bots/quoter-bot/test/playground/model.test.ts diff --git a/bots/market-making/test/playground/module-graph.test.ts b/bots/quoter-bot/test/playground/module-graph.test.ts similarity index 100% rename from bots/market-making/test/playground/module-graph.test.ts rename to bots/quoter-bot/test/playground/module-graph.test.ts diff --git a/bots/market-making/test/playground/pages-workflow.test.ts b/bots/quoter-bot/test/playground/pages-workflow.test.ts similarity index 90% rename from bots/market-making/test/playground/pages-workflow.test.ts rename to bots/quoter-bot/test/playground/pages-workflow.test.ts index a9bebacf..995c3c78 100644 --- a/bots/market-making/test/playground/pages-workflow.test.ts +++ b/bots/quoter-bot/test/playground/pages-workflow.test.ts @@ -3,7 +3,7 @@ import { describe, expect, test } from 'vitest' import { parse } from 'yaml' const workflowPath = new URL( - '../../../../.github/workflows/deploy-market-making-playground.yml', + '../../../../.github/workflows/deploy-quoter-bot-playground.yml', import.meta.url ) @@ -26,7 +26,7 @@ interface Job { ['timeout-minutes']?: number } -describe('market-making playground Pages workflow', () => { +describe('quoter-bot playground Pages workflow', () => { test('separates a read-only build from the code-free privileged deployment', async () => { const source = await readFile(workflowPath, 'utf8') const workflow = parse(source) @@ -39,7 +39,7 @@ describe('market-making playground Pages workflow', () => { expect(trigger.push.branches).toEqual(['main']) expect(trigger.push.paths).toEqual( expect.arrayContaining([ - 'bots/market-making/**', + 'bots/quoter-bot/**', 'packages/bot-kit/**', 'packages/logging/**', 'packages/monitoring/**', @@ -53,7 +53,7 @@ describe('market-making playground Pages workflow', () => { '.npmrc', '.nvmrc', '.github/actions/setup/action.yml', - '.github/workflows/deploy-market-making-playground.yml' + '.github/workflows/deploy-quoter-bot-playground.yml' ]) ) expect(workflow.permissions).toEqual({}) @@ -84,16 +84,16 @@ describe('market-making playground Pages workflow', () => { expect( build.steps.find(step => step.name === 'Test playground at the GitHub Pages subpath')?.run ).toBe( - 'PLAYGROUND_SMOKE_BASE_PATH=/morpho-bots/ pnpm --filter @morpho-org/market-making-bot run playground:smoke:test' + 'PLAYGROUND_SMOKE_BASE_PATH=/morpho-bots/ pnpm --filter @morpho-org/quoter-bot run playground:smoke:test' ) expect(build.steps.find(step => step.name === 'Build playground')?.run).toBe( - 'pnpm --filter @morpho-org/market-making-bot run playground:build' + 'pnpm --filter @morpho-org/quoter-bot run playground:build' ) expect(build.steps.find(step => step.name === 'Upload GitHub Pages artifact')).toMatchObject({ uses: 'actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9', with: { name: 'github-pages', - path: 'bots/market-making/playground/dist', + path: 'bots/quoter-bot/playground/dist', 'retention-days': 1 } }) diff --git a/bots/market-making/test/playground/playground-error.utils.test.ts b/bots/quoter-bot/test/playground/playground-error.utils.test.ts similarity index 100% rename from bots/market-making/test/playground/playground-error.utils.test.ts rename to bots/quoter-bot/test/playground/playground-error.utils.test.ts diff --git a/bots/market-making/test/playground/react-contract.test.ts b/bots/quoter-bot/test/playground/react-contract.test.ts similarity index 100% rename from bots/market-making/test/playground/react-contract.test.ts rename to bots/quoter-bot/test/playground/react-contract.test.ts diff --git a/bots/market-making/test/playground/shared-market-collections.test.ts b/bots/quoter-bot/test/playground/shared-market-collections.test.ts similarity index 100% rename from bots/market-making/test/playground/shared-market-collections.test.ts rename to bots/quoter-bot/test/playground/shared-market-collections.test.ts diff --git a/bots/market-making/test/playground/tsconfig-coverage.test.ts b/bots/quoter-bot/test/playground/tsconfig-coverage.test.ts similarity index 96% rename from bots/market-making/test/playground/tsconfig-coverage.test.ts rename to bots/quoter-bot/test/playground/tsconfig-coverage.test.ts index 3282385e..9e65c98a 100644 --- a/bots/market-making/test/playground/tsconfig-coverage.test.ts +++ b/bots/quoter-bot/test/playground/tsconfig-coverage.test.ts @@ -13,7 +13,7 @@ const parsePackageConfig = () => { return ts.parseJsonConfigFileContent(config, ts.sys, packageRoot, undefined, configPath) } -describe('market-making package TypeScript coverage', () => { +describe('quoter-bot package TypeScript coverage', () => { test('includes the playground TSX entrypoint and rejects a type-error mutation in it', () => { const parsed = parsePackageConfig() expect(parsed.errors).toEqual([]) diff --git a/bots/market-making/test/scripts/railway.utils.test.ts b/bots/quoter-bot/test/scripts/railway.utils.test.ts similarity index 94% rename from bots/market-making/test/scripts/railway.utils.test.ts rename to bots/quoter-bot/test/scripts/railway.utils.test.ts index 89e34694..479010f5 100644 --- a/bots/market-making/test/scripts/railway.utils.test.ts +++ b/bots/quoter-bot/test/scripts/railway.utils.test.ts @@ -32,15 +32,15 @@ describe('Railway CLI output parsing', () => { }) test('parses named services from array and wrapped response shapes', () => { - const array = JSON.stringify([{ id: 'service-id', name: 'market-making' }, { id: 'nameless' }]) + const array = JSON.stringify([{ id: 'service-id', name: 'quoter-bot' }, { id: 'nameless' }]) const wrapped = JSON.stringify({ - services: [{ id: 'service-id', serviceName: 'market-making' }] + services: [{ id: 'service-id', serviceName: 'quoter-bot' }] }) - const created = JSON.stringify({ id: 'service-id', name: 'market-making' }) + const created = JSON.stringify({ id: 'service-id', name: 'quoter-bot' }) - expect(parseRailwayServices(array)).toEqual([{ id: 'service-id', name: 'market-making' }]) - expect(parseRailwayServices(wrapped)).toEqual([{ id: 'service-id', name: 'market-making' }]) - expect(parseRailwayServices(created)).toEqual([{ id: 'service-id', name: 'market-making' }]) + expect(parseRailwayServices(array)).toEqual([{ id: 'service-id', name: 'quoter-bot' }]) + expect(parseRailwayServices(wrapped)).toEqual([{ id: 'service-id', name: 'quoter-bot' }]) + expect(parseRailwayServices(created)).toEqual([{ id: 'service-id', name: 'quoter-bot' }]) }) test('returns no services for malformed JSON', () => { @@ -54,10 +54,10 @@ describe('Railway CLI output parsing', () => { id: 'volume-id', isPendingDeletion: false, mountPath: '/state', - serviceName: 'market-making' + serviceName: 'quoter-bot' }, { id: 'unattached', isPendingDeletion: false, mountPath: '/other', serviceName: null }, - { id: 'incomplete', mountPath: '/other', serviceName: 'market-making' } + { id: 'incomplete', mountPath: '/other', serviceName: 'quoter-bot' } ] }) @@ -66,7 +66,7 @@ describe('Railway CLI output parsing', () => { id: 'volume-id', isPendingDeletion: false, mountPath: '/state', - serviceName: 'market-making' + serviceName: 'quoter-bot' } ]) expect(parseRailwayVolumes('not-json')).toEqual([]) diff --git a/bots/market-making/tsconfig.json b/bots/quoter-bot/tsconfig.json similarity index 100% rename from bots/market-making/tsconfig.json rename to bots/quoter-bot/tsconfig.json diff --git a/bots/market-making/typedoc.json b/bots/quoter-bot/typedoc.json similarity index 92% rename from bots/market-making/typedoc.json rename to bots/quoter-bot/typedoc.json index 7803bdd9..7d4c1341 100644 --- a/bots/market-making/typedoc.json +++ b/bots/quoter-bot/typedoc.json @@ -10,14 +10,14 @@ "src/application/invalidation/offer-invalidation-failed.error.ts", "src/application/invalidation/offer-invalidation.service.ts", "src/application/ladder/ladder-cycle-halted.error.ts", - "src/application/ladder/ladder-market-maker.service.ts", - "src/application/ladder/ladder-market-maker.utils.ts", + "src/application/ladder/ladder-quoter.service.ts", + "src/application/ladder/ladder-quoter.utils.ts", "src/application/ladder/ladder-monitor-halted.error.ts", "src/application/ladder/ladder-ownership-cleanup.error.ts", "src/application/ladder/ladder-verbose.ts", - "src/application/market-making/market-making-monitor-halted.error.ts", - "src/application/market-making/market-making-mutation.utils.ts", - "src/application/market-making/market-making.service.ts", + "src/application/quoter-bot/quoter-bot-monitor-halted.error.ts", + "src/application/quoter-bot/quoter-bot-mutation.utils.ts", + "src/application/quoter-bot/quoter-bot.service.ts", "src/application/setup/setup-check.service.ts", "src/application/setup/setup-check.utils.ts", "src/application/setup/safe-provider.error.ts", @@ -54,7 +54,7 @@ "src/infrastructure/bootstrap/production-bootstrap.ts", "src/infrastructure/cli/cli-usage.error.ts", "src/infrastructure/cli/cli.ts", - "src/infrastructure/cli/market-making-entrypoint.ts", + "src/infrastructure/cli/quoter-bot-entrypoint.ts", "src/infrastructure/cli/offer-invalidation-argument.utils.ts", "src/infrastructure/invalidation/offer-invalidation-adapter.error.ts", "src/infrastructure/invalidation/offer-invalidation-group.utils.ts", @@ -91,7 +91,7 @@ ], "tsconfig": "tsconfig.json", "out": "build/jsdoc", - "name": "Market-making setup-check API", + "name": "Quoter bot setup-check API", "readme": "none", "excludePrivate": true, "excludeProtected": true, diff --git a/bots/market-making/vitest.config.ts b/bots/quoter-bot/vitest.config.ts similarity index 97% rename from bots/market-making/vitest.config.ts rename to bots/quoter-bot/vitest.config.ts index eb7a4c1b..4d08f510 100644 --- a/bots/market-making/vitest.config.ts +++ b/bots/quoter-bot/vitest.config.ts @@ -6,7 +6,7 @@ const BOT_DIR = fileURLToPath(new URL('.', import.meta.url)) export default defineConfig({ test: { - name: 'market-making', + name: 'quoter-bot', // This bot is the one member with a test outside `test/`: scripts/check-jsdoc.test.ts. Without // `scripts/` in `include`, vitest's default glob silently collects one file fewer and the suite // still reports green — so both roots are listed explicitly. diff --git a/docs/CONVENTIONS.md b/docs/CONVENTIONS.md index 19fe12a5..bb5c9fc1 100644 --- a/docs/CONVENTIONS.md +++ b/docs/CONVENTIONS.md @@ -100,7 +100,7 @@ approximate matchers (e.g., floating-point arithmetic, time-dependent values) with a comment explaining why exact matching is not feasible. - **Test runners**: `pnpm test` drives every workspace project listed in the root - `vitest.config.ts` plus the market-making playground's Node `*.test.mjs` suites. TypeScript tests + `vitest.config.ts` plus the quoter-bot playground's Node `*.test.mjs` suites. TypeScript tests use Vitest; mocks and spies come from `vi` (`vi.fn`, `vi.spyOn`, `vi.restoreAllMocks`). ### Testing Anti-Patterns diff --git a/docs/INDEX.md b/docs/INDEX.md index 4068f1bf..af2f84ed 100644 --- a/docs/INDEX.md +++ b/docs/INDEX.md @@ -51,7 +51,7 @@ _None yet — copy [`templates/DATA-FLOW.md`](./templates/DATA-FLOW.md) into a b - [TIB-2026-07-14: Pared-down Slack CI notifications](./decisions/TIB-2026-07-14-slack-ci-notifications.md) — two `github-script` workflows posting basic PR notifications (store-free threading via a PR-body marker) and `release: published` notes to Slack, deliberately trimmed from `prime-monorepo`'s `@repo/ci-scripts` system — implemented - [TIB-2026-07-14: BetterStack log forwarding](./decisions/TIB-2026-07-14-betterstack-log-forwarding.md) — opt-in in-process log shipping: `@repo/bot-kit`'s loglayer logger ([packages/bot-kit/src/logger.ts](../packages/bot-kit/src/logger.ts)) ships structured logs to a per-bot BetterStack source when both `BETTERSTACK_SOURCE_TOKEN` and `BETTERSTACK_INGESTING_HOST` are set (partial config fails loud); inert otherwise — implemented. The addenda record dropping the earlier Vector side-car for this in-process transport - [TIB-2026-07-15: CI/CD deploy pipeline for Railway bots](./decisions/TIB-2026-07-15-ci-deploy-pipeline.md) — deploy-only GitHub Actions (`railway up`, secrets stay on Railway): `push:main` redeploys both bots to staging, `release-{bot}`-labelled merges ship to production + cut a CalVer tag; four scoped GitHub Environments, `push:main` chosen over `pull_request:closed` for the environment branch policy — implemented -- [TIB-2026-08-04: Extract market-making shared packages](./decisions/TIB-2026-08-04-extract-market-making-shared-packages.md) — four standalone workspace packages extracted from the market-making bot (`@repo/logging`, `@repo/observability`, `@repo/monitoring`, `@repo/offers`), deliberately not folded into `@repo/bot-kit`/`@repo/utils`; behavior-preserving, with the observability error-name projection now injected +- [TIB-2026-08-04: Extract quoter-bot shared packages](./decisions/TIB-2026-08-04-extract-quoter-bot-shared-packages.md) — four standalone workspace packages extracted from the quoter-bot bot (`@repo/logging`, `@repo/observability`, `@repo/monitoring`, `@repo/offers`), deliberately not folded into `@repo/bot-kit`/`@repo/utils`; behavior-preserving, with the observability error-name projection now injected ## TIBs (Bot-scoped) diff --git a/docs/decisions/TIB-2026-07-20-migrate-to-pnpm.md b/docs/decisions/TIB-2026-07-20-migrate-to-pnpm.md index 22b50d4a..36dec3b6 100644 --- a/docs/decisions/TIB-2026-07-20-migrate-to-pnpm.md +++ b/docs/decisions/TIB-2026-07-20-migrate-to-pnpm.md @@ -162,7 +162,7 @@ for two weeks and the repo moved ~190 commits underneath it. test runner, so it touches no test file and closes the install-time vector on its own. PR 2 removes bun. This mirrors the original branch's own commit split. -**Four workspaces did not exist when this TIB was drafted**: `bots/market-making`, +**Four workspaces did not exist when this TIB was drafted**: `bots/quoter-bot`, `bots/midnight-crossed-books`, `bots/kill-switch`, and `@repo/{offers,monitoring,logging,observability}`. Test files grew 79 -> 136 and `Bun.env` sites 42 -> 59. PR 2 must also port bun surfaces the original branch never encountered: `Bun.serve`, `Bun.which`, `Bun.file`, `Bun.argv`, `import.meta.main`, and diff --git a/docs/decisions/TIB-2026-07-27-midnight-market-making-bot.md b/docs/decisions/TIB-2026-07-27-midnight-quoter-bot.md similarity index 96% rename from docs/decisions/TIB-2026-07-27-midnight-market-making-bot.md rename to docs/decisions/TIB-2026-07-27-midnight-quoter-bot.md index df4b36c0..aee9e5a3 100644 --- a/docs/decisions/TIB-2026-07-27-midnight-market-making-bot.md +++ b/docs/decisions/TIB-2026-07-27-midnight-quoter-bot.md @@ -1,23 +1,23 @@ -# TIB-2026-07-27: Midnight ladder market-making bot — v0 +# TIB-2026-07-27: Midnight ladder quoter-bot bot — v0 -| Field | Value | -| ---------- | -------------------------- | -| **Status** | Proposed | -| **Date** | 2026-07-27 | -| **Author** | @devatom | -| **Scope** | App: midnight-market-maker | +| Field | Value | +| ---------- | -------------------- | +| **Status** | Proposed | +| **Date** | 2026-07-27 | +| **Author** | @devatom | +| **Scope** | App: midnight-quoter | --- ## Context Midnight needs durable two-sided liquidity through its bootstrap window. The current operational -fallback is the V-1 manual market-making UI: a human chooses the target rate, ladder shape, market +fallback is the V-1 manual quoter-bot UI: a human chooses the target rate, ladder shape, market set, credit top-ups, and cancellation action, while the UI constructs and executes the offers. That surface is useful for investigation and emergency operation, but it cannot run the reference strategy unattended. -V0 is deliberately a reference implementation rather than a competitive market maker. Its role is +V0 is deliberately a reference implementation rather than a competitive quoter. Its role is to: - keep allowlisted Midnight books quoted on both sides; @@ -62,7 +62,7 @@ boundaries. accrual-aware supply-share value over six hours using historical RPC reads; and - a static implementation for the rate at which the operator is willing to acquire credit. - Reject stale, incomplete, or out-of-bounds reference rates. The default hard range is 2%–8% APR, - configurable through environment variables or `market-making.yaml` / `market-making.yml` selected + configurable through environment variables or `quoter-bot.yaml` / `quoter-bot.yml` selected by working-directory discovery or `--config`. - Publish a temporary bootstrap offer with a negative premium until the credit target is met, while maintaining the ordinary bid and ask ladders from the first quote cycle. @@ -101,7 +101,7 @@ boundaries. - Slack alerting, dashboards, or automated daily reporting. Those are V2. - Cross-market hedging, debt-aware optimization, or more sophisticated inventory algorithms. Those are V3. -- The V-1 market-making UI. It remains the manual stopgap and operator escape hatch. +- The V-1 quoter-bot UI. It remains the manual stopgap and operator escape hatch. ## Current Solution @@ -126,7 +126,7 @@ protocol code belongs in an existing shared package only after a concrete second ### 1. One bot package, three concurrent workflows, one make queue -Create `bots/midnight-market-maker` as one long-running Bun program. The three product processes are +Create `bots/midnight-quoter` as one long-running Bun program. The three product processes are isolated application workflows inside that runtime, not independently deployed EOA writers: ```text @@ -194,12 +194,12 @@ domain -> language-level values and lightweight numeric/address types The intended layout is: ```text -bots/midnight-market-maker/ +bots/midnight-quoter/ src/ application/ setup-check.service.ts bootstrap.service.ts - ladder-market-maker.service.ts + ladder-quoter.service.ts make.service.ts domain/ inventory.ts @@ -234,7 +234,7 @@ The names are illustrative; ownership is the decision: Router clients, EIP-712/Merkle-root construction, provider DTO validation, and invalidation transport. - **Configuration** loads strategy settings from environment variables, discovered - `market-making.yaml` / `market-making.yml`, or a YAML path supplied by `--config`. Environment values + `quoter-bot.yaml` / `quoter-bot.yml`, or a YAML path supplied by `--config`. Environment values override corresponding YAML values. Secrets may use either source, but operators should prefer the deployment secret store/environment; any local YAML containing a key must be ignored and permission restricted. Business decisions do not read environment variables or YAML directly. @@ -335,7 +335,7 @@ analysis. ### 5. Process 2 — bootstrap -Bootstrap exists to acquire credit without removing the regular market-making ladder. +Bootstrap exists to acquire credit without removing the regular quoter-bot ladder. For each allowlisted market: @@ -376,7 +376,7 @@ Bootstrap does not proactively take standing offers. That avoids a separate take and supersedes the original 10,000 USDC active-take sketch. A later iteration may opportunistically take when a standing offer is available at a strictly better rate than the expected bootstrap rate. -### 6. Process 3 — ladder market maker +### 6. Process 3 — ladder quoter Ladder owns the long-running quote-set calculation and reconciliation workflow. It never mutates the book directly; all invalidation, signing, and publication goes through the shared blocking @@ -515,13 +515,13 @@ the pending nonce and on-chain invalidation state before accepting another job f ### 10. Configuration contract Strategy configuration may be supplied through environment variables, an explicit YAML file passed as -`--config `, or both. Without an explicit path, the CLI discovers `market-making.yaml` and then -`market-making.yml` in its invocation working directory; `.yaml` wins when both exist, and no file +`--config `, or both. Without an explicit path, the CLI discovers `quoter-bot.yaml` and then +`quoter-bot.yml` in its invocation working directory; `.yaml` wins when both exist, and no file preserves environment-only startup. Environment variables always override corresponding YAML values, including whole-list replacement for market and bootstrap arrays. Both sources map into one typed validation path and produce the same validated runtime configuration. -The public README, `.env.example`, and `market-making.example.yaml` document every currently implemented +The public README, `.env.example`, and `quoter-bot.example.yaml` document every currently implemented setting, unit, default, precedence rule, and safety interaction. The current YAML schema is limited to `chain`, `identity`, `contracts`, `apis`, `markets`, `setup`, and `bootstrap`. In that schema, `MORPHO_API_BASE_URL` serves book and cursor-paginated offer-group reads, while @@ -762,7 +762,7 @@ RPC credentials, API keys, or secret environment values. response validation, exact-root reconciliation, and fail-closed behavior reduce the impact; V0 does not claim Byzantine provider tolerance. - **V1 gate:** treasury multisig, delegated funding/cap/block contract, bounded on-chain - market-maker ratifier, and KMS-equivalent signing are required before a material capital ramp. + quoter ratifier, and KMS-equivalent signing are required before a material capital ramp. ## Open-source release requirements @@ -803,7 +803,7 @@ ever exposed is rotated before visibility changes. ### Bot documentation required at ship -`bots/midnight-market-maker` ships with: +`bots/midnight-quoter` ships with: - `README.md`: architecture, the three-workflow lifecycle, prerequisites, setup check, local run, Docker and deployment, upgrade, shutdown, recovery, invalidation, and troubleshooting; @@ -811,7 +811,7 @@ ever exposed is rotated before visibility changes. bounds, failure posture, known weaknesses, and non-competitive intent; - `.env.example`: placeholders only, with units/defaults and no real keys, RPC credentials, project IDs, or operator-specific addresses; -- `market-making.example.yaml`: the equivalent configuration schema, with documented `--config`, +- `quoter-bot.example.yaml`: the equivalent configuration schema, with documented `--config`, default discovery, and environment-over-YAML precedence behavior; - `Dockerfile`, `docker-compose.yml`, and environment-driven deployment tooling with no baked-in Morpho project; @@ -882,11 +882,11 @@ and the relevant fork/live checks. ## Future Considerations - **V1 — security and treasury:** treasury multisig; delegated funding contract with fund/cap/block - controls; custom market-maker ratifier enforcing price/spread bounds on-chain; AWS KMS or + controls; custom quoter ratifier enforcing price/spread bounds on-chain; AWS KMS or equivalent key custody. This phase gates any significant fund increase. - **V2 — monitoring:** inventory/loss/staleness alerting, automated reports to the agreed Market Services Slack channel, dashboards, and service-level objectives. -- **V3 — smarter market making:** position and algorithm optimization, cross-market hedging, and +- **V3 — smarter quoter-bot:** position and algorithm optimization, cross-market hedging, and debt-friendly inventory management. - Automatic rollover between maturities. - Per-book top-ups above the lowest shared multi-market cap. @@ -915,7 +915,7 @@ These must be resolved before the relevant implementation or public-release gate ## References - [MKT-1455: define TIB](https://linear.app/morpho-labs/issue/MKT-1455/define-tib) -- [Market-making bot Linear project](https://linear.app/morpho-labs/project/market-making-bot-628e80069e52/overview) +- [Quoter bot Linear project](https://linear.app/morpho-labs/project/market-making-bot-628e80069e52/overview) - [Initial Base Midnight market](https://markets.morpho.org/fixed/base/0x05959752fdeff325962b9d263edb421efc6e2186a49360dba6c32e86ebf6c84c?orderType=limit) - [`midnight-crossed-books` architecture](../../bots/midnight-crossed-books/README.md) - [TIB-2026-07-16: Revert to bots-as-programs](./TIB-2026-07-16-revert-to-bots-as-programs.md) diff --git a/docs/decisions/TIB-2026-08-04-extract-market-making-shared-packages.md b/docs/decisions/TIB-2026-08-04-extract-quoter-bot-shared-packages.md similarity index 90% rename from docs/decisions/TIB-2026-08-04-extract-market-making-shared-packages.md rename to docs/decisions/TIB-2026-08-04-extract-quoter-bot-shared-packages.md index 0de21f77..a0f514db 100644 --- a/docs/decisions/TIB-2026-08-04-extract-market-making-shared-packages.md +++ b/docs/decisions/TIB-2026-08-04-extract-quoter-bot-shared-packages.md @@ -1,4 +1,4 @@ -# TIB-2026-08-04: Extract market-making shared packages +# TIB-2026-08-04: Extract quoter-bot shared packages | Field | Value | | ---------- | ---------- | @@ -11,9 +11,9 @@ ## Context -The market-making bot -([TIB-2026-07-27](./TIB-2026-07-27-midnight-market-making-bot.md)) accumulated several -general-purpose concerns inside `bots/market-making`: a CLI output presenter buried in +The quoter-bot bot +([TIB-2026-07-27](./TIB-2026-07-27-midnight-quoter-bot.md)) accumulated several +general-purpose concerns inside `bots/quoter-bot`: a CLI output presenter buried in `infrastructure/cli`, an observability composer whose operator error-name projection forced an infrastructure→application import, three byte-identical `*CycleHasFailure` helpers, a prospective-spread assertion duplicated between the bootstrap and ladder adapters, and an O(n²) @@ -42,11 +42,11 @@ Maintainers explicitly required **standalone, focused packages per concern** rat ## Current Solution -Everything below lived inside `bots/market-making`: the CLI presenter in -`src/infrastructure/cli/market-making-logger.ts`, `createMarketMakingObservability` (which +Everything below lived inside `bots/quoter-bot`: the CLI presenter in +`src/infrastructure/cli/quoter-bot-logger.ts`, `createQuoterBotObservability` (which imported the application layer's operator error-name projection from infrastructure), three copies of the cycle-failure check (`bootstrapCycleHasFailure`, `ladderCycleHasFailure`, -`marketMakingCycleHasFailure`), per-adapter spread assertions +`quoterBotCycleHasFailure`), per-adapter spread assertions (`assertBootstrapProspectiveSpread` / `assertLadderProspectiveSpread`), and an O(n²) `invertedMarketIds` crossed-book scan. @@ -58,12 +58,12 @@ Four new workspace packages, each a single focused concern: `createCliLogger`: the CLI presenter — results to stdout, errors to stderr, human or JSON Lines output, bigint-safe serialization, caller-supplied error event name. Extracted verbatim from the -bot's `market-making-logger.ts`. Deliberately independent of `@repo/bot-kit`'s +bot's `quoter-bot-logger.ts`. Deliberately independent of `@repo/bot-kit`'s loglayer/BetterStack runtime logger: a CLI presenter does not need that dependency set. ### `@repo/observability` — depends on `@repo/bot-kit` -- `createBotObservability`: generalized from `createMarketMakingObservability`. Composes +- `createBotObservability`: generalized from `createQuoterBotObservability`. Composes `@repo/bot-kit`'s `createLogger` + `createHeartbeatMonitor` + `railwayContext` and ships the `bot.started` / `bot.stopped` / `bot.action` / `bot.unexpected-error` events. The operator error-name projection is now **injected** by the caller, which removes the old @@ -77,7 +77,7 @@ loglayer/BetterStack runtime logger: a CLI presenter does not need that dependen - `waitForMonitorInterval` — abortable interval wait. - `MonitorOperationQueue` / `createOperationQueue` — failure-tolerant serial queue. - `cycleHasFailure` — replaces the three byte-identical copies (`bootstrapCycleHasFailure`, - `ladderCycleHasFailure`, `marketMakingCycleHasFailure`). + `ladderCycleHasFailure`, `quoterBotCycleHasFailure`). ### `@repo/offers` — deps: viem (`Hex` type only) @@ -103,7 +103,7 @@ mind as a plausible second consumer. - **Adapters keep their typed errors**: pure rules move to `@repo/offers`, but each adapter still throws its own named error class, so operator-facing failure modes are unchanged. - **`BASE_CHAIN_ID` deduped** to a single export in - `bots/market-making/src/config/config.utils.ts`. + `bots/quoter-bot/src/config/config.utils.ts`. - **Audited report allowlist**: the entrypoint's 8-branch `instanceof` ladder is replaced by a single `REPORTED_ERRORS` constructor table iterated by `failureDetails`. A structural `'report' in error` guard was rejected because it would emit report payloads from unaudited @@ -160,7 +160,7 @@ widened this refactor well past its behavior-preservation budget. ## References -- [TIB-2026-07-27-midnight-market-making-bot](./TIB-2026-07-27-midnight-market-making-bot.md) — +- [TIB-2026-07-27-midnight-quoter-bot](./TIB-2026-07-27-midnight-quoter-bot.md) — the bot this refactor restructures. - [TIB-2026-07-16-revert-to-bots-as-programs](./TIB-2026-07-16-revert-to-bots-as-programs.md) — establishes bots assembling from shared packages rather than forking a monolith; this TIB adds diff --git a/knip.json b/knip.json index 0418b4b9..bf701d30 100644 --- a/knip.json +++ b/knip.json @@ -26,7 +26,7 @@ "bots/midnight-crossed-books": { "ignore": ["src/infrastructure/*/generated/**"] }, - "bots/market-making": { + "bots/quoter-bot": { "entry": ["src/index.ts", "playground/app.tsx"], "ignoreDependencies": ["@repo/bot-kit"] } diff --git a/package.json b/package.json index 5e52a2da..b6f04e0a 100644 --- a/package.json +++ b/package.json @@ -8,10 +8,10 @@ "knip": "knip", "lint": "oxlint --no-error-on-unmatched-pattern && pnpm run lint:playground-smoke", "lint:fix": "oxlint --fix --no-error-on-unmatched-pattern", - "lint:playground-smoke": "oxlint --config bots/market-making/scripts/playground-smoke.oxlintrc.json bots/market-making/scripts/playground-smoke*.mjs", - "market-making:playground": "pnpm --filter @morpho-org/market-making-bot run playground:serve", + "lint:playground-smoke": "oxlint --config bots/quoter-bot/scripts/playground-smoke.oxlintrc.json bots/quoter-bot/scripts/playground-smoke*.mjs", + "quoter-bot:playground": "pnpm --filter @morpho-org/quoter-bot run playground:serve", "prepare": "husky", - "test": "vitest run && pnpm --filter @morpho-org/market-making-bot run playground:test" + "test": "vitest run && pnpm --filter @morpho-org/quoter-bot run playground:test" }, "devDependencies": { "@repo/typescript-config": "workspace:*", diff --git a/packages/logging/test/cli-logger.utils.test.ts b/packages/logging/test/cli-logger.utils.test.ts index ad3d39f6..f11b5c89 100644 --- a/packages/logging/test/cli-logger.utils.test.ts +++ b/packages/logging/test/cli-logger.utils.test.ts @@ -40,7 +40,7 @@ describe('createCliLogger', () => { test('writes JSON errors with the caller-owned event name and optional details', () => { const { out, err, output } = capture() - const logger = createCliLogger(output, { json: true, errorEvent: 'market-making.error' }) + const logger = createCliLogger(output, { json: true, errorEvent: 'quoter-bot.error' }) logger.error('setup failed', { checks: 9n }) logger.error('usage') @@ -48,13 +48,13 @@ describe('createCliLogger', () => { expect(out).toEqual([]) expect(JSON.parse(err[0]!)).toEqual({ level: 'error', - event: 'market-making.error', + event: 'quoter-bot.error', message: 'setup failed', details: { checks: '9' } }) expect(JSON.parse(err[1]!)).toEqual({ level: 'error', - event: 'market-making.error', + event: 'quoter-bot.error', message: 'usage' }) }) diff --git a/packages/observability/test/bot-observability.utils.test.ts b/packages/observability/test/bot-observability.utils.test.ts index 94ef26ed..f77c6a8b 100644 --- a/packages/observability/test/bot-observability.utils.test.ts +++ b/packages/observability/test/bot-observability.utils.test.ts @@ -28,7 +28,7 @@ describe('createBotObservability', () => { const heartbeat = { start: vi.fn(async () => undefined), stop: vi.fn(() => undefined) } const observability = createBotObservability({ ...identity, logger, heartbeat }) const cycle = { - event: 'market-making.cycle', + event: 'quoter-bot.cycle', workflow: 'ladder', status: 'published', activePosition: { suppliedAssets: 12n }, @@ -47,7 +47,7 @@ describe('createBotObservability', () => { { level: 'info', event: 'bot.started', fields: {} }, { level: 'info', - event: 'market-making.cycle', + event: 'quoter-bot.cycle', fields: { workflow: 'ladder', status: 'published', @@ -59,7 +59,7 @@ describe('createBotObservability', () => { }, { level: 'info', event: 'bot.stopped', fields: { reason: 'completed' } } ]) - expect(cycle.event).toBe('market-making.cycle') + expect(cycle.event).toBe('quoter-bot.cycle') }) test('ships each array item as its own info-level record for every success status', () => { diff --git a/packages/observability/test/verbose-argv.utils.test.ts b/packages/observability/test/verbose-argv.utils.test.ts index ada0b4c9..0a241aed 100644 --- a/packages/observability/test/verbose-argv.utils.test.ts +++ b/packages/observability/test/verbose-argv.utils.test.ts @@ -30,8 +30,8 @@ describe('enhanceVerboseArgv', () => { enhanceVerboseArgv(['--config', 'start', 'setup-check'], { commands, env: full }) ).toEqual(['--config', 'start', 'setup-check']) expect( - enhanceVerboseArgv(['--config=market-making.yaml', 'ladder'], { commands, env: full }) - ).toEqual(['--config=market-making.yaml', 'ladder', '--verbose']) + enhanceVerboseArgv(['--config=quoter-bot.yaml', 'ladder'], { commands, env: full }) + ).toEqual(['--config=quoter-bot.yaml', 'ladder', '--verbose']) }) test.each([ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 52a53c7f..8ab8c5eb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -205,7 +205,7 @@ importers: specifier: 'catalog:' version: 4.1.2(@types/node@24.7.0)(vite@7.3.6(@types/node@24.7.0)(jiti@2.7.0)(tsx@4.21.0)(yaml@2.9.0)) - bots/market-making: + bots/quoter-bot: dependencies: '@aws-sdk/client-kms': specifier: 3.1101.0 diff --git a/vitest.config.ts b/vitest.config.ts index 425721ce..f2fc93e5 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -16,7 +16,7 @@ export default defineConfig({ 'bots/blue-liquidation', 'bots/midnight-liquidation', 'bots/midnight-crossed-books', - 'bots/market-making' + 'bots/quoter-bot' ] } }) From e21ac3ebab675f5efe46e37d05f32e785b1d3d40 Mon Sep 17 00:00:00 2001 From: "prd-carapulse[bot]" <264278285+prd-carapulse[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 07:51:30 +0000 Subject: [PATCH 2/4] fix: align quoter deployment target names Use the clarified GitHub Environment name in the production workflow and operator documentation. --- .github/workflows/deploy-quoter-bot-production.yml | 2 +- bots/quoter-bot/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-quoter-bot-production.yml b/.github/workflows/deploy-quoter-bot-production.yml index 06b4f220..c425f75a 100644 --- a/.github/workflows/deploy-quoter-bot-production.yml +++ b/.github/workflows/deploy-quoter-bot-production.yml @@ -22,7 +22,7 @@ jobs: Deploy: runs-on: ubuntu-latest timeout-minutes: 30 - environment: market-making-production + environment: quoter-bot-production steps: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 with: diff --git a/bots/quoter-bot/README.md b/bots/quoter-bot/README.md index ce70c64d..5fabd331 100644 --- a/bots/quoter-bot/README.md +++ b/bots/quoter-bot/README.md @@ -279,7 +279,7 @@ that cannot resolve its signer. replace a working strategy with an empty list. Every remaining optional value is synchronized: omitted timeouts return to their documented defaults, and omitted group IDs and BetterStack settings are disabled. `RAILWAY_ENVIRONMENT` defaults to `production`. CI uses `DEPLOY_ONLY=true` with the -`market-making-production` GitHub Environment, so it reads only `RAILWAY_PROJECT_ID` and +`quoter-bot-production` GitHub Environment, so it reads only `RAILWAY_PROJECT_ID` and `RAILWAY_TOKEN` and uses project-token deployment permissions to re-ship the service. Deploy-only runs rely on the Dockerfile path, runtime variables, and persistent volume established by a full run; they neither read nor mutate that provisioned configuration. From 85f59bcedf0e86061a84779e06aabbe41f475c44 Mon Sep 17 00:00:00 2001 From: "prd-carapulse[bot]" <264278285+prd-carapulse[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 07:55:24 +0000 Subject: [PATCH 3/4] fix: address quoter rename review findings Use a valid GitHub Actions job identifier and retain ignore protection for legacy secret-bearing config files. --- .github/workflows/deploy-production.yml | 4 ++-- .gitignore | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index dd265f45..d2df1bf6 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -101,7 +101,7 @@ jobs: github_environment: crossed-books-prod ref: ${{ github.sha }} - Quoter bot: + Quoter-bot: needs: Select if: ${{ needs.Select.outputs.quoter_bot == 'true' }} uses: ./.github/workflows/deploy-quoter-bot-production.yml @@ -195,7 +195,7 @@ jobs: ${prev:+--notes-start-tag "$prev"} Release-quoter-bot: - needs: Quoter bot + needs: Quoter-bot runs-on: ubuntu-latest permissions: contents: write diff --git a/.gitignore b/.gitignore index 750aba17..4ef03bcc 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,12 @@ node_modules !**/quoter-bot.example.yaml !**/quoter-bot.example.yml +# Legacy local configuration can still contain private keys after upgrading. +**/market-making.yaml +**/market-making.yml +!**/market-making.example.yaml +!**/market-making.example.yml + # Testing coverage From 14b7762b93b2e636cefcc2405458b08ce19b4f5c Mon Sep 17 00:00:00 2001 From: "prd-carapulse[bot]" <264278285+prd-carapulse[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 07:59:58 +0000 Subject: [PATCH 4/4] fix: prefix quoter deployment artifacts Apply the clarified quoter-bot- prefix to Pages artifacts, deployment metadata, and concurrency keys. --- .github/workflows/deploy-quoter-bot-playground.yml | 6 +++--- .github/workflows/deploy-quoter-bot-production.yml | 2 +- bots/quoter-bot/scripts/deploy-railway.ts | 2 +- bots/quoter-bot/test/playground/pages-workflow.test.ts | 9 ++++++--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy-quoter-bot-playground.yml b/.github/workflows/deploy-quoter-bot-playground.yml index 013901fb..8e867a29 100644 --- a/.github/workflows/deploy-quoter-bot-playground.yml +++ b/.github/workflows/deploy-quoter-bot-playground.yml @@ -24,7 +24,7 @@ on: permissions: {} concurrency: - group: pages + group: quoter-bot-pages cancel-in-progress: false jobs: @@ -55,7 +55,7 @@ jobs: - name: Upload GitHub Pages artifact uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 with: - name: github-pages + name: quoter-bot-github-pages path: bots/quoter-bot/playground/dist retention-days: 1 @@ -81,4 +81,4 @@ jobs: id: deployment uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0 with: - artifact_name: github-pages + artifact_name: quoter-bot-github-pages diff --git a/.github/workflows/deploy-quoter-bot-production.yml b/.github/workflows/deploy-quoter-bot-production.yml index c425f75a..c9efd07c 100644 --- a/.github/workflows/deploy-quoter-bot-production.yml +++ b/.github/workflows/deploy-quoter-bot-production.yml @@ -15,7 +15,7 @@ permissions: contents: read concurrency: - group: deploy-quoter-bot-production + group: quoter-bot-production cancel-in-progress: false jobs: diff --git a/bots/quoter-bot/scripts/deploy-railway.ts b/bots/quoter-bot/scripts/deploy-railway.ts index d29e913d..ffaa88d8 100644 --- a/bots/quoter-bot/scripts/deploy-railway.ts +++ b/bots/quoter-bot/scripts/deploy-railway.ts @@ -224,7 +224,7 @@ const latestDeploymentJson = async () => { } const startDeployment = async () => { - const message = `deploy quoter-bot ${ENVIRONMENT}` + const message = `quoter-bot-${ENVIRONMENT}` const { error } = await tryCatch( $({ cwd: REPO_ROOT diff --git a/bots/quoter-bot/test/playground/pages-workflow.test.ts b/bots/quoter-bot/test/playground/pages-workflow.test.ts index 995c3c78..f5e17e94 100644 --- a/bots/quoter-bot/test/playground/pages-workflow.test.ts +++ b/bots/quoter-bot/test/playground/pages-workflow.test.ts @@ -57,7 +57,10 @@ describe('quoter-bot playground Pages workflow', () => { ]) ) expect(workflow.permissions).toEqual({}) - expect(workflow.concurrency).toEqual({ group: 'pages', 'cancel-in-progress': false }) + expect(workflow.concurrency).toEqual({ + group: 'quoter-bot-pages', + 'cancel-in-progress': false + }) expect(Object.keys(workflow.jobs).toSorted()).toEqual(['build', 'deploy']) expect(build.if).toBe("github.ref == 'refs/heads/main'") @@ -92,7 +95,7 @@ describe('quoter-bot playground Pages workflow', () => { expect(build.steps.find(step => step.name === 'Upload GitHub Pages artifact')).toMatchObject({ uses: 'actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9', with: { - name: 'github-pages', + name: 'quoter-bot-github-pages', path: 'bots/quoter-bot/playground/dist', 'retention-days': 1 } @@ -109,7 +112,7 @@ describe('quoter-bot playground Pages workflow', () => { name: 'Deploy GitHub Pages', id: 'deployment', uses: 'actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128', - with: { artifact_name: 'github-pages' } + with: { artifact_name: 'quoter-bot-github-pages' } }) const actions = [...build.steps, ...deploy.steps]