Skip to content

chore: remove json tags from lnclient models#2375

Open
rolznz wants to merge 3 commits into
masterfrom
chore/lnclient-remove-json-tags
Open

chore: remove json tags from lnclient models#2375
rolznz wants to merge 3 commits into
masterfrom
chore/lnclient-remove-json-tags

Conversation

@rolznz
Copy link
Copy Markdown
Member

@rolznz rolznz commented May 23, 2026

lnclient models should not be passed through the API directly

Follow up from #2373

Summary by CodeRabbit

  • Refactor

    • Simplified API payloads and unified model shapes for node/peer/on-chain data.
    • Standardized balance reporting to millisatoshis for consistent balance values.
    • Streamlined channel-close behavior and simplified related responses.
    • Removed deprecated/duplicate balance fields for clearer, more predictable outputs.
  • Tests

    • Updated test mocks to align with the new API and response formats.

Review Change Stack

these should not be passed through the API directly
@rolznz rolznz requested a review from im-adithya May 23, 2026 08:03
@rolznz rolznz modified the milestones: v1.22.3, v1.23.0 May 23, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 222ea247-8cd7-4b26-bcf3-048a5cac20bb

📥 Commits

Reviewing files that changed from the base of the PR and between ae4d050 and 75f8964.

📒 Files selected for processing (3)
  • lnclient/cashu/cashu.go
  • lnclient/models.go
  • lnclient/phoenixd/phoenixd.go

📝 Walkthrough

Walkthrough

This PR decouples the API layer from internal lnclient types by introducing local API model definitions, removing the CloseChannelResponse type, standardizing balance field naming to msat/sat variants, and adding explicit type conversion functions. All endpoint implementations now translate between API and lnclient types explicitly.

Changes

API Abstraction and Type Conversion

Layer / File(s) Summary
API Model Type Definitions
api/models.go
Defines local API struct types (NodeConnectionInfo, NodeStatus, PeerDetails, OnchainTransaction, PendingBalanceDetails, balance response types) to replace lnclient aliases; removes lnclient import.
API Conversion Helpers
api/api.go
Adds nil-safe conversion helpers (toApiNodeStatus, toApiBalances, toApiPendingBalanceDetails) to map lnclient responses into API types.
API Endpoint Implementations with Type Translation
api/api.go
Endpoints now translate API request structs to lnclient requests and map lnclient responses to API responses for peers, connect/open/close/update channels, balances, onchain transactions, and health.
LNClient Models & Interface Contract
lnclient/models.go
Change LNClient.CloseChannel to return only error; remove CloseChannelResponse, drop deprecated aggregate balance fields, and remove JSON tags from several DTOs.
LNClient Service Implementations: CloseChannel and Balance Standardization
lnclient/* (cashu, cln, ldk, lnd, phoenixd)
Service implementations updated to the new CloseChannel error-only signature and to populate balance/pending-balance fields using sat/msat-specific fields only.
Consumer Updates & TLV handling
nip47/controllers/*, swaps/swaps_service.go
Consumers updated to use msat balance fields (TotalSpendableMsat); keysend TLV input now uses local hex-encoded value type and is converted into lnclient.TLVRecord before sending.
Test Mocks and Generated Mocks
tests/mock_ln_client.go, tests/mocks/LNClient.go
Mocks adjusted to match new CloseChannel error-only signature and balance fixture changes (remove deprecated fields).

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

  • getAlby/hub#2026: Overlaps with CloseChannel/CLN backend contract changes and endpoint handling.

Suggested Reviewers

  • im-adithya
  • reneaaron

Poem

🐰 Hops through types with tidy cheer,

models land and mappings clear,
Msat and sat find ordered tune,
CloseChannel now sings error-only croon,
A rabbit nods — the code feels light and dear.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective of the changeset—removing JSON tags from lnclient models as part of a larger effort to separate API models from internal lnclient models.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/lnclient-remove-json-tags

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
api/api.go (1)

842-844: ⚡ Quick win

Wrap the newly propagated LN client errors with endpoint context.

These adapters add a new API layer, so returning raw backend errors makes it harder to tell which call failed once the same lnclient error bubbles up through multiple handlers.

As per coding guidelines **/*.go: Wrap errors with fmt.Errorf("context: %w", err) for debugging.

Also applies to: 1143-1145, 1165-1167, 1867-1869

🤖 Prompt for 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.

In `@api/api.go` around lines 842 - 844, The lnclient calls (e.g.,
lnClient.GetNodeConnectionInfo(ctx)) are returning raw backend errors; update
each to wrap the error with endpoint context using
fmt.Errorf("GetNodeConnectionInfo: %w", err) (and analogous messages for the
other sites mentioned) before returning so callers can distinguish which API
adapter failed; ensure you import fmt if not present and apply the same wrapping
pattern at the other call sites referenced (the calls around the locations
noted: the GetNodeConnectionInfo invocation and the two other lnClient call
sites).
lnclient/ldk/ldk.go (1)

1096-1111: ⚡ Quick win

Wrap close failures with branch-specific context.

The new error-only contract makes bare return err harder to diagnose upstream. Wrap the cooperative and force-close failures separately so callers can tell which path failed.

As per coding guidelines, **/*.go: Wrap errors with fmt.Errorf("context: %w", err) for debugging.

🤖 Prompt for 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.

In `@lnclient/ldk/ldk.go` around lines 1096 - 1111, In LDKService.CloseChannel,
when calling ls.node.ForceCloseChannel and ls.node.CloseChannel, wrap returned
errors with fmt.Errorf to add branch-specific context before returning (e.g.,
use fmt.Errorf("force close failed: %w", err) when closeChannelRequest.Force is
true and fmt.Errorf("cooperative close failed: %w", err) for the other branch);
locate the error handling in CloseChannel, wrap the err from
ls.node.ForceCloseChannel and ls.node.CloseChannel accordingly, and return the
wrapped error so callers can distinguish which close path failed.
lnclient/lnd/lnd.go (1)

1172-1228: ⚡ Quick win

Add stage-specific context to CloseChannel errors.

This now returns bare errors from the list, parse, close-stream, receive, and txid-decoding steps. Once the response payload is gone, those failures are much harder to distinguish upstream unless each return is wrapped with the failing stage.

As per coding guidelines, **/*.go: Wrap errors with fmt.Errorf("context: %w", err) for debugging.

🤖 Prompt for 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.

In `@lnclient/lnd/lnd.go` around lines 1172 - 1228, In LNDService.CloseChannel,
wrap returned errors with stage-specific context using fmt.Errorf so callers can
distinguish where failures occurred: when calling svc.client.ListChannels (wrap
as "list channels: %w"), when parsing channel point via svc.parseChannelPoint
("parse channel point: %w"), when initiating close with svc.client.CloseChannel
("initiate close channel: %w"), when receiving from the stream (stream.Recv =>
"receive close update: %w"), and when decoding the closing txid via
chainhash.NewHash ("decode closing txid: %w"); update each return err to return
fmt.Errorf("<stage description>: %w", err) referencing the corresponding
function/variable names (LNDService.CloseChannel, svc.client.ListChannels,
svc.parseChannelPoint, svc.client.CloseChannel, stream.Recv, chainhash.NewHash).
🤖 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 `@api/api.go`:
- Around line 1181-1190: The ConnectPeer handler forwards unchecked user input
to lnclient; add validation at the API boundary in func ConnectPeer (and
similarly for the other handlers noted) to reject invalid requests before
calling lnClient: check api.svc.GetLNClient() as already done, then validate
connectPeerRequest.Pubkey is non-empty, Address is non-empty (and optionally
well-formed), and Port is >0; return a clear API error (e.g., ErrInvalidRequest
or a new validation error) if any check fails, and only then construct
lnclient.ConnectPeerRequest and call lnClient.ConnectPeer; repeat this pattern
for the other request structs (e.g., where ConnectPeerRequest-like types and
AmountSats/Port/Pubkey fields are passed into lnclient) so all user inputs are
validated at the API boundary.

In `@api/models.go`:
- Around line 395-398: The public API structs currently expose backend-specific
types via interface{} fields (e.g., NodeStatus.InternalNodeStatus,
InternalBalances, NetworkGraphResponse) which can leak lnclient serialization
details; replace each interface{} with a concrete, API-local DTO that models
only the fields the API should expose or, if truly dynamic, change the type to
map[string]any and document the shape; update any (un)marshalling and
constructors/transformers that populate these fields to convert from the
lnclient types into the new DTOs (or map) so the API boundary no longer depends
on lnclient concrete types.

In `@lnclient/cashu/cashu.go`:
- Around line 181-182: The CloseChannel implementation in CashuService currently
returns nil which incorrectly signals success; update the
CashuService.CloseChannel(ctx context.Context, closeChannelRequest
*lnclient.CloseChannelRequest) method to return the appropriate unsupported
error (return errors.ErrUnsupported) so callers receive a clear failure; ensure
the errors package that defines ErrUnsupported is imported and used in that
function.

In `@lnclient/models.go`:
- Around line 8-12: TLVRecord is missing json tags so marshaling produces
"Type"/"Value" fields and breaks consumers; add struct tags on
lnclient.TLVRecord (e.g., `Type uint64 `json:"type"``, `Value string
`json:"value"``) so when transactions/transactions_service.go places
[]lnclient.TLVRecord into metadata["tlv_records"] and json.Marshal is called,
the output uses the expected lower-case keys; ensure this change preserves
compatibility with LDK/LND producers and any code that unmarshals
transaction.Metadata in nip47/models/transactions.go.

In `@lnclient/phoenixd/phoenixd.go`:
- Around line 393-394: The CloseChannel method currently returns nil which
incorrectly signals success; update PhoenixService.CloseChannel(ctx,
closeChannelRequest *lnclient.CloseChannelRequest) to return a proper
"unsupported" error (e.g., errors.New or a wrapped fmt.Errorf) indicating that
Phoenixd does not implement channel closing so callers get a clear failure.
Ensure the error is returned directly from CloseChannel and include the function
name in the message for clarity.

---

Nitpick comments:
In `@api/api.go`:
- Around line 842-844: The lnclient calls (e.g.,
lnClient.GetNodeConnectionInfo(ctx)) are returning raw backend errors; update
each to wrap the error with endpoint context using
fmt.Errorf("GetNodeConnectionInfo: %w", err) (and analogous messages for the
other sites mentioned) before returning so callers can distinguish which API
adapter failed; ensure you import fmt if not present and apply the same wrapping
pattern at the other call sites referenced (the calls around the locations
noted: the GetNodeConnectionInfo invocation and the two other lnClient call
sites).

In `@lnclient/ldk/ldk.go`:
- Around line 1096-1111: In LDKService.CloseChannel, when calling
ls.node.ForceCloseChannel and ls.node.CloseChannel, wrap returned errors with
fmt.Errorf to add branch-specific context before returning (e.g., use
fmt.Errorf("force close failed: %w", err) when closeChannelRequest.Force is true
and fmt.Errorf("cooperative close failed: %w", err) for the other branch);
locate the error handling in CloseChannel, wrap the err from
ls.node.ForceCloseChannel and ls.node.CloseChannel accordingly, and return the
wrapped error so callers can distinguish which close path failed.

In `@lnclient/lnd/lnd.go`:
- Around line 1172-1228: In LNDService.CloseChannel, wrap returned errors with
stage-specific context using fmt.Errorf so callers can distinguish where
failures occurred: when calling svc.client.ListChannels (wrap as "list channels:
%w"), when parsing channel point via svc.parseChannelPoint ("parse channel
point: %w"), when initiating close with svc.client.CloseChannel ("initiate close
channel: %w"), when receiving from the stream (stream.Recv => "receive close
update: %w"), and when decoding the closing txid via chainhash.NewHash ("decode
closing txid: %w"); update each return err to return fmt.Errorf("<stage
description>: %w", err) referencing the corresponding function/variable names
(LNDService.CloseChannel, svc.client.ListChannels, svc.parseChannelPoint,
svc.client.CloseChannel, stream.Recv, chainhash.NewHash).
🪄 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

Run ID: 1dbbed8f-9602-45d5-98cf-8351e35b861e

📥 Commits

Reviewing files that changed from the base of the PR and between 12a3b11 and ae4d050.

📒 Files selected for processing (13)
  • api/api.go
  • api/models.go
  • lnclient/cashu/cashu.go
  • lnclient/cln/cln.go
  • lnclient/ldk/ldk.go
  • lnclient/lnd/lnd.go
  • lnclient/models.go
  • lnclient/phoenixd/phoenixd.go
  • nip47/controllers/get_balance_controller.go
  • nip47/controllers/pay_keysend_controller.go
  • swaps/swaps_service.go
  • tests/mock_ln_client.go
  • tests/mocks/LNClient.go

Comment thread api/api.go
Comment thread api/models.go
Comment thread lnclient/cashu/cashu.go Outdated
Comment thread lnclient/models.go
Comment thread lnclient/phoenixd/phoenixd.go Outdated
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.

1 participant