Skip to content

feat(tokens): add HTLC lock, claim and reclaim REST endpoints - #30

Merged
adecaro merged 3 commits into
hyperledger:mainfrom
atharrva01:feature/issue-66-week4-htlc-rest
Sep 22, 2026
Merged

adecaro merged 3 commits into
hyperledger:mainfrom
atharrva01:feature/issue-66-week4-htlc-rest

Conversation

@atharrva01

Copy link
Copy Markdown
Contributor

Summary

Week 4 of issue #66's deliverable 3 (HTLC locks), following the service layer merged in #29. Exposes lock, claim and reclaim over the owner REST API, adds e2e coverage, and documents them.

  • POST /owner/accounts/{id}/lock, /claim and /reclaim in swagger.yaml, with routes.gen.go regenerated (oapi-codegen v2.5.1) and the handlers added to owner/routes/routes.go.
  • Hashes and pre-images are standard base64 strings and deadline is in seconds from now. Lock returns a node-generated pre-image with its SHA-256 hash, unless the caller supplies a hash, in which case no pre-image is returned.
  • All three requests take an optional tmsId (omitted means the node's default TMS), so FabricSmartClient.Lock/Claim/Reclaim now take the TMS as a parameter.
  • This app has no request validation middleware, so the handlers return a 400 for locally detectable input errors: a deadline below one second (zero would silently mean the SDK's one hour default), a hash that is not a 32 byte SHA-256 digest (Panurus does not check it, so a wrong-length hash would lock funds until expiry), and an empty pre-image or hash. Everything else keeps the existing convention of returning the error as a 500.
  • scripts/test.sh gets run_htlc_test, run after the existing flow: (1) generated pre-image with an explicit tmsId, lock then claim; (2) caller-supplied hash, short deadline, reclaim after expiry, and a late claim that must be rejected. Balances are asserted relative to the start of each scenario and polled, since finality on the non-initiating node is asynchronous.
  • cleanup() in test.sh now only tears down the network from the main shell. Command substitutions inherit the ERR trap, so a failure inside one of the new $(...) helpers ran the teardown twice.
  • README: a new "Example: HTLC lock, claim and reclaim" section, and the three stale links to hyperledger-labs/fabric-token-sdk now point at LFDT-Panurus/panurus.

Stays on Panurus and Fabric Smart Client v0.18.0. Bumping to v0.22.0 is a separate follow-up.

Notes for review

  • The HTLC e2e block runs on fabric3 by default; set HTLC_TEST=1 to run it on other platforms. HTLC has only been verified on fabric3.
  • curl_with_retry in test.sh never returns a non-zero status (local exit_code=$? after an if with no true branch is always 0). In the last green main run the fabricx job's POST /endorser/init returned 500 on all 30 attempts and the job still passed, so a green fabricx job says little. I left the helper alone here because fixing it would turn that job red for reasons unrelated to HTLC. Happy to fix it in a follow-up once fabricx is healthy.
  • The committed routes.gen.go was already out of date with the spec, so its diff also contains two lines unrelated to HTLC: the generator version header (v2.5.0 to v2.5.1) and one RedeemRequest.Message comment.

Test plan

  • go build and go vet clean on both the default and fabricx build tags
  • Live on fabric3, by curl: deadline 0 or missing, a wrong-length hash, an empty claim and an empty reclaim all return 400 and leave balances unchanged; lock debits the sender immediately; claim credits the recipient; a second claim of the same pre-image and a wrong tmsId both return 500
  • Full clean PLATFORM=fabric3 ./scripts/test.sh passes: the existing issue/transfer/redeem flow, then every HTLC assertion
  • With the cleanup() guard a failure inside $(...) tears the network down once; without it, twice
  • Not run on fabricx or xdev

Exposes the HTLC service layer added in the previous change over the
owner REST API:

- POST /owner/accounts/{id}/lock
- POST /owner/accounts/{id}/claim
- POST /owner/accounts/{id}/reclaim

Hashes and pre-images are standard base64 strings. `deadline` is in
seconds from now. Lock generates a random pre-image and returns it with
its SHA-256 hash unless the caller supplies a hash, in which case no
pre-image is returned. All three requests take an optional `tmsId`; when
omitted the node's default TMS is used, so FabricSmartClient.Lock/Claim/
Reclaim now take the TMS as a parameter.

There is no request validation middleware in this app, so the handlers
reject locally detectable input errors with a 400: a deadline below one
second (zero would silently select the Token SDK's one hour default), a
hash that is not a 32 byte SHA-256 digest (Panurus does not check it, so
a wrong-length hash would lock funds until expiry), and an empty
pre-image or hash. Everything else keeps the existing convention of
returning the error as a 500.

routes.gen.go is regenerated with oapi-codegen v2.5.1 from the updated
swagger.yaml. Its diff includes two lines unrelated to HTLC that were
already out of date with the spec: the generator version header and the
RedeemRequest.Message comment.

Signed-off-by: atharrva01 <atharvaborade568@gmail.com>
Adds run_htlc_test to scripts/test.sh, run after the existing
issue/transfer/redeem flow:

1. Node generated pre-image with an explicit tmsId: alice locks 20 TOK
   for dan, the returned hash is checked against the SHA-256 of the
   returned pre-image, dan claims, and both balances are verified.
2. Caller supplied hash with the default TMS and a short deadline: the
   response must echo the hash and carry no pre-image; after the deadline
   alice reclaims and her balance is restored, and dan's late claim must
   be rejected without changing his balance.

Assertions use balances relative to the start of each scenario and poll
for them, since finality on the non-initiating node is asynchronous. The
rejected claim is only asserted to fail with HTTP >= 400: after a reclaim
the lock is both spent and expired, and the SDK's message differs.

The block runs on fabric3 by default. Set HTLC_TEST=1 to run it on other
platforms; HTLC has only been verified on fabric3 so far. HTLC_DEADLINE
overrides the 10 second lock deadline of the second scenario.

Also guard cleanup() so only the main shell tears the network down. Command
substitutions inherit the ERR trap, so a failure inside one of the new
$(...) helpers previously ran the teardown twice.

Signed-off-by: atharrva01 <atharvaborade568@gmail.com>
Adds an "Example: HTLC lock, claim and reclaim" section to the README
covering the three flows: a node generated pre-image, reclaiming after
the deadline, and locking against a hash the caller already holds. It
also states the encoding (base64), the unit of `deadline` (seconds), and
the optional `tmsId`, and updates the intro and table of contents.

The three links to the Token SDK pointed at the old hyperledger-labs
repository; they now point at LFDT-Panurus/panurus.

Signed-off-by: atharrva01 <atharvaborade568@gmail.com>
@adecaro
adecaro self-requested a review September 22, 2026 04:41
@adecaro adecaro self-assigned this Sep 22, 2026
@adecaro
adecaro merged commit efab824 into hyperledger:main Sep 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants