feat: Layer 2 agent swap facade (swap_quote/status/execute/cancel)#7
Conversation
…idation + invariant guard + flow order (review)
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThis PR adds a complete swap trading facade to the HashLock MCP server, introducing four new MCP tools— ChangesSwap Quoting and Execution Facade
Sequence Diagram(s)sequenceDiagram
participant Client
participant MCP_Tool as MCP Tool (swap_*)
participant SwapHandler as runSwap* handler
participant SwapClient as SwapClient (createRFQ/getQuotes/acceptQuote/cancelRFQ/getRFQ)
Client->>MCP_Tool: submit swap_quote / swap_execute / swap_status / swap_cancel
MCP_Tool->>SwapHandler: invoke runSwapQuote|runSwapExecute|runSwapStatus|runSwapCancel
SwapHandler->>SwapClient: createRFQ (for quote) / getRFQ (status/execute) / getQuotes (poll) / cancelRFQ (cancel)
SwapClient-->>SwapHandler: RFQ / quotes / accept result / cancel result
SwapHandler-->>MCP_Tool: ToolContent result (best_bid / acceptance / status / cancel)
MCP_Tool-->>Client: response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/lib/swap.ts`:
- Around line 175-177: Reject calls to swap_execute when both args.quote_id and
args.limit_price are supplied: detect the ambiguous case (args.quote_id &&
args.limit_price !== undefined) and return an explicit error (rather than
silently preferring quote_id) explaining the conflict and instructing the caller
to supply only one confirmation method; apply the same check in the other
similar branch that currently handles real-funds confirmation (the branch that
returns CONFIRMATION_REQUIRED/okContent) so both places consistently reject
ambiguous inputs.
- Line 138: The code computes still_open using the original rfq (created by
createRFQ) which is stale; change the computation to use the post-poll RFQ state
(the RFQ returned by the polling function, e.g., the variable assigned from
pollRFQ or rfqAfterPoll) instead of the initial rfq so RFQ_OPEN_STATES.has(...)
checks the latest status; update the object that sets still_open to reference
that polled RFQ's .status.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 03047406-06b5-4084-9eae-108fc9dad08b
📒 Files selected for processing (6)
package.jsonserver.jsonsrc/__tests__/swap.test.tssrc/__tests__/tools.test.tssrc/index.tssrc/lib/swap.ts
…rate still_open post-poll (CodeRabbit PR#7)
Summary
Layer 2 of the agent-friendly MCP work: a single-call swap facade over the existing sealed-bid RFQ primitives, so an AI agent can run a full OTC swap end-to-end via MCP (previously impossible — there was no
accept_quote/list_quotestool).swap_quote(open sealed-bid RFQ + brief bounded wait for first bids →swap_handle+ best bid),swap_status(stateless re-poll / context recovery),swap_execute(directional-limit-protected accept → trade),swap_cancel(clean abort).limit_price(SELL=floor, BUY=ceiling) is never sent to makers and never persisted (correct commit-reveal); re-supplied at execute.private(Ghost Auction) defaults ON for the automated channel; overridable.@hashlock-tech/sdkstays pinned^0.1.4).create_rfqis byte-untouched (its intent-compiler + pin tests are load-bearing).src/lib/swap.ts(decimal compare, directional limit gate, fail-closed price validation, best-bid selection, bounded poll, the 4run*flows);index.tsadds thinwrapTool+idempotency-scoped registrations.Security hardening (from adversarial review)
forbidden/non-participant RFQ collapses to the sameSWAP_NOT_FOUNDas an unknown handle acrossswap_execute/swap_status/swap_cancel(closes an RFQ-existence/participant oracle).swap_quoteopens a new RFQ so has no such surface.isPositiveDecimalgates maker price/amount and the agentlimit_price, so price safety does not silently depend on backend input sanitization.accepted_price/accepted_amounttaken from the selected quote (the SDKacceptQuotereturn carries no price). Idempotency-wrapped writes. Agent-facing warning thataccepted_amountmay exceed the requested amount under full-fill v1.Test Plan
pnpm install --frozen-lockfile --ignore-workspace(nested-clone standalone parity)pnpm test— 119/119 pass, 6 files (TDD per task; money path adversarially tested both BUY/SELL × both bound directions, all outcome branches, forbidden-collapse parity, fail-closed price)pnpm lint(tsc --noEmit) cleanpnpm build(tsup) clean —dist/index.js~40 KBcreate_rfqintent-compiler pin (byte-stability guard)npm publish0.4.0 + MCP-registry publish (server.json manifest-rev 1.4.0 > live 1.3.0; npm 0.4.0 in packages[].version)Notes
hashlock-marketsmonorepo (docs/superpowers/), shipped separately;web/public/llms*.txtupdated there too.swap.tstypes have only internal consumers (library API surface);getQuotesruns before thelimit_pricegrammar check on the malformed path (no money moves — test-proven).versionbumped to0.4.0(npm) —0.3.0is already published, so the fix must ship as0.4.0.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Chores
Tests