feat: expose generator hash in REST /api/orders/by-owner response (COW-993)#82
Conversation
…W-993) hash = keccak256(abi.encode(handler, salt, staticInput)) is the on-chain canonical identifier used by ComposableCow.singleOrders() and remove(). It was already indexed in the schema but missing from the REST response, forcing integrators to use GraphQL to look up an order by hash. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
The change looks correct — One small wording note on the description string: "On-chain canonical identifier: keccak256(abi.encode(handler, salt, staticInput)). Used by ComposableCow.singleOrders(owner, hash) and remove(owner, hash)."The ABI encoding isn't quite right. The ConditionalOrder library computes the hash as
Minor, but since this is a public API surface the description is what consumers will rely on. Otherwise the PR is fine. |
|
Review: Expose generator hash (COW-993) Hash description accuracy The Zod Response type consistency The DB column is No test changes The PR correctly notes that the DB query correctness
Minor nit on the description wording aside, this PR is clean. |
…COW-993) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| it("fails parse when hash is missing", () => { | ||
| const { hash: _omitted, ...withoutHash } = validGenerator; | ||
| const result = GeneratorSummary.safeParse(withoutHash); | ||
| expect(result.success).toBe(false); | ||
| if (!result.success) { | ||
| const paths = result.error.issues.map((i) => i.path.join(".")); | ||
| expect(paths).toContain("hash"); | ||
| } | ||
| }); |
There was a problem hiding this comment.
is it possible has be missing? isn't it required on the schema?
| } | ||
| }); | ||
|
|
||
| it("fails parse when hash is not a string (number supplied)", () => { |
There was a problem hiding this comment.
do we need test for it? why ts compiler wouldn't catch it
| } | ||
| }); | ||
|
|
||
| it("hash field carries the correct describe() text", () => { |
There was a problem hiding this comment.
why do you think this test is useful? If we change the description on the future we would need to update this test as well. Not sure how it would help this app to be easier to maintain
| it("ownerAddressType accepts null (regression guard for unchanged field)", () => { | ||
| const result = GeneratorSummary.safeParse({ ...validGenerator, ownerAddressType: null }); | ||
| expect(result.success).toBe(true); | ||
| if (result.success) { | ||
| expect(result.data.ownerAddressType).toBeNull(); | ||
| } | ||
| }); | ||
|
|
||
| it("ownerAddressType accepts the enum value 'cowshed_proxy'", () => { | ||
| const result = GeneratorSummary.safeParse({ | ||
| ...validGenerator, | ||
| ownerAddressType: "cowshed_proxy", | ||
| }); | ||
| expect(result.success).toBe(true); | ||
| if (result.success) { | ||
| expect(result.data.ownerAddressType).toBe("cowshed_proxy"); | ||
| } | ||
| }); | ||
|
|
||
| it("ownerAddressType accepts the enum value 'flash_loan_helper'", () => { |
There was a problem hiding this comment.
This three tests are also things that TS types should catch and we shouldn't need tests for it
Summary
Adds the
hashfield to thegeneratorobject in the/api/orders/by-owner/{owner}REST response.hash = keccak256(abi.encode(handler, salt, staticInput))is the on-chain canonical identifier used byComposableCow.singleOrders(owner, hash)andremove(owner, hash). Without it, integrators who have a hash from an on-chain transaction were forced to use GraphQL to look it up.The field is already stored and indexed in the DB (
hashIdxonschema/tables.ts:84) — this is a response-shape addition only, no schema migration required.Changes
src/api/schemas/orders-by-owner.ts— addhash: z.string()toGeneratorSummarywith an OpenAPI descriptionsrc/api/endpoints/orders-by-owner.ts— includehashin the generator.select()projectionHow to Test
pnpm typecheck— no errorspnpm test— all tests pass.todo("includes hash in generator object (COW-993)")test intests/api/orders-by-owner.test.tscan be promoted to an active assertionChecklist
Breaking Changes
None — additive field to an existing response object.
Related Issues
Closes COW-993