π Description
AnchorService.registerBulk validates an entire batch before persisting any of it, so a single bad entry never leaves a partial batch registered. LiquidityService has no equivalent for withdrawals: an operator needing to withdraw liquidity across many anchor/asset pairs at once (e.g. season-end reconciliation) must issue one POST /api/v1/liquidity/withdraw call per pair today, with no all-or-nothing guarantee across the batch.
π§© Requirements and context
- Add
LiquidityService.withdrawBulk(entries: unknown) that validates every { anchor, asset, amount } entry (existence of balance, sufficient amount) before applying any withdrawal, mirroring registerBulk's validate-then-apply-all structure.
- Add
POST /api/v1/liquidity/withdraw/bulk in routes/liquidity.ts calling the new service method.
- A single invalid or insufficient-balance entry anywhere in the batch must cause the entire batch to be rejected with no partial withdrawals applied.
π οΈ Suggested execution
- Add
withdrawBulk to src/services/liquidityService.ts, reusing requireString/normalizeAsset/requirePositiveNumber and validating sufficiency for every entry before calling this.repo.upsert/remove for any of them.
- Add the route in
src/routes/liquidity.ts.
- Update
src/openapi.ts with the new path.
- Add tests in
src/services/liquidityService.test.ts and src/routes/liquidity.test.ts, including a batch with one invalid entry asserting no withdrawals from valid entries in the same batch were applied.
β
Acceptance criteria
π Security notes
Atomicity of the batch prevents a partially-applied bulk operation from leaving liquidity accounting in an inconsistent intermediate state.
π Guidelines
- Minimum 95% test coverage
- Clear documentation
- Timeframe: 96 hours
π Description
AnchorService.registerBulkvalidates an entire batch before persisting any of it, so a single bad entry never leaves a partial batch registered.LiquidityServicehas no equivalent for withdrawals: an operator needing to withdraw liquidity across many anchor/asset pairs at once (e.g. season-end reconciliation) must issue onePOST /api/v1/liquidity/withdrawcall per pair today, with no all-or-nothing guarantee across the batch.π§© Requirements and context
LiquidityService.withdrawBulk(entries: unknown)that validates every{ anchor, asset, amount }entry (existence of balance, sufficient amount) before applying any withdrawal, mirroringregisterBulk's validate-then-apply-all structure.POST /api/v1/liquidity/withdraw/bulkinroutes/liquidity.tscalling the new service method.π οΈ Suggested execution
withdrawBulktosrc/services/liquidityService.ts, reusingrequireString/normalizeAsset/requirePositiveNumberand validating sufficiency for every entry before callingthis.repo.upsert/removefor any of them.src/routes/liquidity.ts.src/openapi.tswith the new path.src/services/liquidityService.test.tsandsrc/routes/liquidity.test.ts, including a batch with one invalid entry asserting no withdrawals from valid entries in the same batch were applied.β Acceptance criteria
POST /api/v1/liquidity/withdraw/bulkwithdraws every valid entry in a batch atomically.openapi.ts.π Security notes
Atomicity of the batch prevents a partially-applied bulk operation from leaving liquidity accounting in an inconsistent intermediate state.
π Guidelines