Skip to content

Get Balance #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 27, 2025
Merged

Get Balance #6

merged 4 commits into from
Mar 27, 2025

Conversation

ntheile
Copy link
Contributor

@ntheile ntheile commented Mar 27, 2025

Summary by CodeRabbit

  • New Features
    • Enhanced node information now includes detailed balance metrics (send, receive, fee credit, pending, and inactive amounts) for a more complete financial overview.
    • Integrated real-time balance retrieval provides improved visibility into node and channel statuses.
    • Expanded data responses now offer comprehensive channel details, delivering a more robust and informative view of network operations.
    • New structures for balance responses and channel information enhance data handling capabilities related to financial states.
    • Additional fields in the NodeInfo interface and data structures support tracking of various financial states associated with the node.

Copy link

coderabbitai bot commented Mar 27, 2025

Walkthrough

This update enhances the balance handling and node information retrieval across multiple API implementations. The CLN and LND modules have introduced new structures for handling channel and balance information. The Phoenixd module implements a new balance retrieval flow—fetching data from a /getbalance endpoint, updating response handling, and integrating additional balance-related fields. Concurrently, related data structures have been extended to support channel and balance data.

Changes

Files Change Summary
crates/lni/cln/api.rs
crates/lni/lnd/api.rs
Added new types ChannelWrapper and BalancesResponse, updated get_info functions to retrieve and parse balance information, and enhanced NodeInfo struct with new balance fields.
crates/lni/phoenixd/api.rs Introduced a new GET request flow for the /getbalance endpoint, updated response handling with explicit type annotations, and imported GetBalanceResponse.
crates/lni/phoenixd/types.rs
crates/lni/types.rs
Added new data structures: Channel and GetBalanceResponse in Phoenixd types; extended InfoResponse to include channels and NodeInfo with six new balance fields and a Default implementation.
crates/lni/lnd/types.rs Introduced new structures: BalancesResponse and Amount to handle balance-related information.
bindings/lni_uniffi/src/lni.udl Expanded NodeInfo dictionary with new fields for various balance metrics, including send and receive balances.
bindings/lni_nodejs/index.d.ts Added new properties to the NodeInfo interface for additional balance metrics.
bindings/lni_nodejs/main.mjs Modified the main function to execute the cln function while commenting out the test function, altering the control flow.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant PhoenixdAPI as Phoenixd API
    participant NodeEndpoint as Node Info Endpoint
    participant BalanceEndpoint as Balance Endpoint

    Client->>PhoenixdAPI: Call get_info()
    PhoenixdAPI->>NodeEndpoint: GET request to info_url
    NodeEndpoint-->>PhoenixdAPI: Return node info
    PhoenixdAPI->>BalanceEndpoint: GET request to balance_url
    BalanceEndpoint-->>PhoenixdAPI: Return balance info
    PhoenixdAPI->>Client: Return combined NodeInfo
Loading

Poem

I’m just a rabbit, hopping with glee,
Code now sings with clarity for me.
New endpoints and defaults, clean and bright—
My balance hops high in pure delight.
With each comment, my heart does skip,
A joyful sprint on this coding trip!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 3

🔭 Outside diff range comments (1)
crates/lni/phoenixd/api.rs (1)

6-43: 💡 Verification agent

🧩 Analysis chain

Update TypeScript interface to include new balance fields

The NodeInfo struct has been updated with balance fields, but the corresponding TypeScript interface in bindings/lni_nodejs/index.d.ts needs to be updated to include these new fields.

Run this script to verify the TypeScript interface:


🏁 Script executed:

#!/bin/bash
# Check if the TypeScript interface includes the new balance fields
cat bindings/lni_nodejs/index.d.ts | grep -A 10 "export interface NodeInfo"

Length of output: 280


Action Required: Update the TypeScript NodeInfo Interface

The Rust implementation of NodeInfo now includes additional balance fields (send_balance_msat, receive_balance_msat, fee_credit_balance_msat, pending_balance_msat, and inactive_balance_msat), but these are missing from the TypeScript interface in bindings/lni_nodejs/index.d.ts. Please update the interface to include these new balance properties. For example, consider adding the following fields (using the camelCase convention to match existing properties):

  • sendBalanceMsat: number;
  • receiveBalanceMsat: number;
  • feeCreditBalanceMsat: number;
  • pendingBalanceMsat: number;
  • inactiveBalanceMsat: number;

Ensure that the updated interface aligns with how the Rust backend populates these values.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 794dae2 and f457aab.

📒 Files selected for processing (5)
  • crates/lni/cln/api.rs (1 hunks)
  • crates/lni/lnd/api.rs (1 hunks)
  • crates/lni/phoenixd/api.rs (2 hunks)
  • crates/lni/phoenixd/types.rs (1 hunks)
  • crates/lni/types.rs (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
crates/lni/phoenixd/types.rs (1)
bindings/lni_nodejs/index.d.ts (1)
  • Channel (78-96)
crates/lni/phoenixd/api.rs (2)
bindings/lni_nodejs/index.d.ts (3)
  • NodeInfo (50-57)
  • PayInvoiceParams (199-210)
  • PayInvoiceResponse (157-161)
crates/lni/phoenixd/lib.rs (1)
  • new (24-29)
🔇 Additional comments (12)
crates/lni/cln/api.rs (2)

27-29: Informative comments for future implementation

These comments provide valuable context for understanding how balance information could be retrieved using the /v1/listfunds endpoint. The link to the Zeus implementation is particularly helpful as a reference.


38-38: Good use of default initialization

Using ..Default::default() ensures that any unspecified fields in the NodeInfo struct (including the newly added balance fields in types.rs) will be initialized with their default values. This is a good practice for maintaining robustness as the struct evolves.

crates/lni/phoenixd/types.rs (3)

11-11: Appropriate addition of channels to InfoResponse

Adding the channels field to InfoResponse properly extends the struct to include channel information returned by the API.


14-28: Well-structured Channel implementation

The new Channel struct appropriately models lightning channel data with proper field naming and serialization mappings. The fields align well with the Channel interface defined in the Node.js bindings.


30-36: Good GetBalanceResponse implementation

This new struct provides a clear structure for parsing responses from the balance endpoint, with appropriately named fields and correct serialization attributes.

crates/lni/lnd/api.rs (2)

41-45: Informative comments for future implementation

These comments provide valuable context about how balance information can be retrieved using the /v1/balance/channels endpoint, with a helpful link to the LND API documentation.


53-53: Good use of default initialization

Using ..Default::default() ensures that any unspecified fields in the NodeInfo struct (including the newly added balance fields in types.rs) will be initialized with their default values. This is a good practice for maintaining robustness as the struct evolves.

crates/lni/types.rs (2)

29-33: Well-designed balance fields for NodeInfo

The addition of these balance-related fields to the NodeInfo struct provides a comprehensive representation of different balance types. This aligns with the PR objective of enhancing balance handling.


35-50: Appropriate Default implementation

The implementation of Default for NodeInfo is well-structured and ensures all fields are properly initialized with sensible default values. This complements the use of ..Default::default() in the API implementations.

crates/lni/phoenixd/api.rs (3)

6-6: Good addition of GetBalanceResponse import

Adding the import for GetBalanceResponse aligns with the implementation of the balance retrieval functionality mentioned in the TODO at line 12.


17-17: Good refactoring: Creating a dedicated info_url variable

Creating a new variable for the info URL instead of reusing the url parameter improves clarity and maintainability.


12-12: Good job implementing the get_balance TODO

The implementation now fetches balance information from the /getbalance endpoint, addressing this TODO comment.

Copy link

@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: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f457aab and 32e7c03.

📒 Files selected for processing (5)
  • bindings/lni_uniffi/src/lni.udl (1 hunks)
  • crates/lni/lnd/api.rs (2 hunks)
  • crates/lni/lnd/types.rs (1 hunks)
  • crates/lni/phoenixd/api.rs (2 hunks)
  • crates/lni/types.rs (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/lni/phoenixd/api.rs
🧰 Additional context used
🧬 Code Definitions (2)
crates/lni/lnd/types.rs (1)
bindings/lni_nodejs/index.d.ts (1)
  • BalancesResponse (165-168)
crates/lni/types.rs (2)
bindings/lni_nodejs/index.d.ts (1)
  • NodeInfo (50-57)
crates/lni/database.rs (1)
  • new (38-56)
🔇 Additional comments (9)
bindings/lni_uniffi/src/lni.udl (1)

171-177: Fields added match new functionality for retrieving balance data.

These new fields in the NodeInfo dictionary align with the corresponding Rust struct changes in crates/lni/types.rs. They provide comprehensive balance information, including send/receive capacities, unsettled balances, and pending operations.

crates/lni/lnd/types.rs (2)

224-235: Well-structured new BalancesResponse type for LND data.

The structure correctly maps to the LND API response format and includes all necessary fields for parsing channel balance data. The fields follow the same pattern as other response structures in this file.


237-241: Good use of optional fields for Amount structure.

Using Option<String> for the sat and msat fields is appropriate since these values may not always be present in the API response.

crates/lni/lnd/api.rs (2)

2-4: Added import for the new BalancesResponse type.

The import is correctly placed with other related types.


41-49: API call for retrieving balance information.

Good documentation of the endpoint that's being used, with clear comments explaining the purpose.

crates/lni/types.rs (4)

29-36: Good documentation for new balance fields.

The comments clearly explain each field's purpose, making it easy for developers to understand how these values should be used. The Phoenix-specific comment about fee credits is especially helpful.


37-54: Appropriate implementation of Default for NodeInfo.

Adding the Default implementation is a good practice, ensuring all fields have sensible initial values. This makes it easier to initialize NodeInfo instances and use the spread operator pattern (..Default::default()) for partial updates.


287-288: Comment formatting improvement for fee_limit_msat.

The comment now clarifies that fee_limit_msat and fee_limit_percentage are mutually exclusive options.


304-305: Comment formatting improvement for timeout_seconds.

Small formatting adjustment to the comment aligns with the codebase style.

Copy link

@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: 0

🔭 Outside diff range comments (1)
crates/lni/cln/api.rs (1)

14-82: 🛠️ Refactor suggestion

Add error handling for API calls

The get_info function uses unwrap() at multiple points, which could cause the program to panic if an API call fails. Consider implementing proper error handling.

-    let response = client
-        .post(&req_url)
-        .header("Content-Type", "application/json")
-        .send()
-        .unwrap();
-    let response_text = response.text().unwrap();
+    let response = client
+        .post(&req_url)
+        .header("Content-Type", "application/json")
+        .send()
+        .map_err(|e| ApiError::Api { 
+            reason: format!("Failed to send getinfo request: {}", e) 
+        })?;
+    let response_text = response.text()
+        .map_err(|e| ApiError::Api { 
+            reason: format!("Failed to read getinfo response: {}", e) 
+        })?;

// Similar changes needed for the funds API call (lines 29-35)

Similarly, implement proper error handling for the listfunds API call.

🧹 Nitpick comments (1)
crates/lni/cln/api.rs (1)

45-64: Consider using match statement for channel state handling

The current implementation uses multiple if-else statements to categorize channels based on their state. Consider refactoring to use a match statement for better maintainability.

-    for channel in channels.channels.iter() {
-        if channel.state == "CHANNELD_NORMAL" && channel.connected {
-            // Active channels
-            local_balance += channel.our_amount_msat;
-            remote_balance += channel.amount_msat - channel.our_amount_msat;
-        } else if channel.state == "CHANNELD_NORMAL" && !channel.connected {
-            // Unsettled channels (previously inactive)
-            unsettled_send_balance_msat += channel.our_amount_msat;
-            unsettled_receive_balance_msat += channel.amount_msat - channel.our_amount_msat;
-        } else if channel.state == "CHANNELD_AWAITING_LOCKIN" 
-            || channel.state == "DUALOPEND_AWAITING_LOCKIN"
-            || channel.state == "DUALOPEND_OPEN_INIT"
-            || channel.state == "DUALOPEND_OPEN_COMMITTED"
-            || channel.state == "DUALOPEND_OPEN_COMMIT_READY"
-            || channel.state == "OPENINGD" {
-            // Pending open channels
-            pending_open_send_balance += channel.our_amount_msat;
-            pending_open_receive_balance += channel.amount_msat - channel.our_amount_msat;
-        }
-    }
+    for channel in channels.channels.iter() {
+        let remote_amount = channel.amount_msat - channel.our_amount_msat;
+        
+        match (channel.state.as_str(), channel.connected) {
+            ("CHANNELD_NORMAL", true) => {
+                // Active channels
+                local_balance += channel.our_amount_msat;
+                remote_balance += remote_amount;
+            },
+            ("CHANNELD_NORMAL", false) => {
+                // Unsettled channels (previously inactive)
+                unsettled_send_balance_msat += channel.our_amount_msat;
+                unsettled_receive_balance_msat += remote_amount;
+            },
+            ("CHANNELD_AWAITING_LOCKIN", _) | 
+            ("DUALOPEND_AWAITING_LOCKIN", _) |
+            ("DUALOPEND_OPEN_INIT", _) |
+            ("DUALOPEND_OPEN_COMMITTED", _) |
+            ("DUALOPEND_OPEN_COMMIT_READY", _) |
+            ("OPENINGD", _) => {
+                // Pending open channels
+                pending_open_send_balance += channel.our_amount_msat;
+                pending_open_receive_balance += remote_amount;
+            },
+            _ => {} // Ignoring other channel states
+        }
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32e7c03 and 7967e71.

📒 Files selected for processing (2)
  • crates/lni/cln/api.rs (2 hunks)
  • crates/lni/cln/types.rs (1 hunks)
🔇 Additional comments (7)
crates/lni/cln/types.rs (2)

91-97: Well-structured wrapper for channel data

The ChannelWrapper struct is correctly designed to deserialize the API response from the listfunds endpoint. The #[serde(skip)] attribute on the outputs field ensures that only relevant channel data is processed.


99-110: Channel struct models channel data appropriately

The Channel struct contains all the necessary fields to represent a Lightning Network channel, including connection status, state, balances, and funding information. The field types match the expected data formats.

crates/lni/cln/api.rs (5)

2-2: Appropriate import of the new type

The import has been correctly updated to include the new ChannelWrapper type.


27-36: Good implementation of balance retrieval

The code correctly implements a new API call to the listfunds endpoint to retrieve channel data, following the same pattern as the existing getinfo call.


38-43: Well-structured balance tracking

The code initializes separate variables to track different types of balances, making the accounting logic clear and maintainable.


73-79: Correctly updates NodeInfo with balance information

The code properly updates the NodeInfo struct with the calculated balances and uses the ..Default::default() syntax to handle any fields not explicitly set.


36-36:

❓ Verification inconclusive

Validate JSON response before parsing

The code parses the funds response directly without validating if it's a valid JSON or contains error messages from the API.


🏁 Script executed:

#!/bin/bash
# Check the structure of listfunds response
curl -s https://api.github.com/repos/ElementsProject/lightning/contents/doc/schemas/listfunds.schema.json | jq -r '.content' | base64 -d | jq

Length of output: 238


Attention: Validate JSON Response Before Parsing

The current implementation in crates/lni/cln/api.rs on line 36 directly parses the API response using serde_json::from_str(&funds_response_text)? without explicit validation. This approach doesn’t check whether the response is valid JSON or if it contains error messages from the API.

  • The initial check using the GitHub API for the JSON schema did not produce output because the environment lacks the base64 command.
  • Without a valid automated check, it’s unclear if the API response might return error messages or malformed JSON that could cause runtime errors.

Please manually verify that the JSON response from the funds API is always valid or add additional validation/error-handling logic to gracefully manage unexpected responses.

Copy link

@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: 0

🧹 Nitpick comments (1)
bindings/lni_nodejs/index.d.ts (1)

57-63: Good addition of balance fields to NodeInfo

The new balance fields provide comprehensive tracking of funds in different states, which aligns with the PR objective of enhancing balance handling. This will give users better visibility into their node's financial state.

I notice that while most fields use "Msat" suffix to indicate millsatoshi units, the pendingOpenSendBalance and pendingOpenReceiveBalance properties don't follow this naming convention.

Consider renaming these fields to maintain consistency:

  sendBalanceMsat: number
  receiveBalanceMsat: number
  feeCreditBalanceMsat: number
  unsettledSendBalanceMsat: number
  unsettledReceiveBalanceMsat: number
- pendingOpenSendBalance: number
- pendingOpenReceiveBalance: number
+ pendingOpenSendBalanceMsat: number
+ pendingOpenReceiveBalanceMsat: number
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7967e71 and 1612dc6.

📒 Files selected for processing (2)
  • bindings/lni_nodejs/index.d.ts (1 hunks)
  • bindings/lni_nodejs/main.mjs (1 hunks)
🔇 Additional comments (1)
bindings/lni_nodejs/main.mjs (1)

145-147: Test configuration update

This change enables the CLN implementation test while disabling the general test function. This aligns with the PR focus on enhancing balance handling, as it allows for testing the newly added balance fields in the NodeInfo object returned by the CLN implementation.

@ntheile ntheile merged commit 7e2ea72 into master Mar 27, 2025
1 check passed
@coderabbitai coderabbitai bot mentioned this pull request Mar 28, 2025
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