Skip to content
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

feat: bip21 send receive #112

Merged
merged 1 commit into from
Aug 27, 2024
Merged

feat: bip21 send receive #112

merged 1 commit into from
Aug 27, 2024

Conversation

reez
Copy link
Owner

@reez reez commented Aug 27, 2024

Description

Notes to the reviewers

Changelog notice

Checklists

All Submissions:

  • I've signed all my commits
  • I have formatted my code with swift-format per .swift-format file

New Features:

  • I've added tests for the new feature
  • I've added docs for the new feature

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Summary by CodeRabbit

  • New Features

    • Introduced a new method for normalizing URL schemes to lowercase.
    • Enhanced "Unified" feature with new state variables for UI feedback in the BIP21 view.
    • Streamlined payment handling by consolidating multiple methods into a single function.
  • Bug Fixes

    • Updated the default network configuration from testnet to signet, impacting onboarding and payment processing.
  • Refactor

    • Removed several obsolete payment-related methods to simplify the service's functionality.

Copy link

coderabbitai bot commented Aug 27, 2024

Walkthrough

The recent changes in the project involve significant file deletions and modifications across various components. Key updates include the removal of several payment-related functionalities within the LightningNodeService and AmountViewModel, alongside a shift in default network settings from testnet to signet. New methods were introduced in extensions and view models to enhance functionality, particularly in handling URI payments and normalizing URL schemes.

Changes

File Path Change Summary
LDKNodeMonday.xcodeproj/project.pbxproj Removed references to several Swift files related to payment view models and invoices.
LDKNodeMonday/Extensions/String+Extensions.swift Added func lowercaseScheme() -> String to normalize URL schemes.
LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift Removed multiple payment-related methods; updated default network from testnet to signet.
LDKNodeMonday/View Model/Home/AmountViewModel.swift Replaced sendToOnchain method with send(uriStr: String) async throws -> QrPaymentResult.
LDKNodeMonday/View Model/Home/OnboardingViewModel.swift Changed default value of selectedNetwork from .testnet to .signet.
LDKNodeMonday/View Model/Home/Receive/BIP21ViewModel.swift Updated assignment of unified variable to utilize lowercaseScheme().
LDKNodeMonday/View/Home/Receive/BIP21View.swift Introduced new state variables unifiedIsCopied and unifiedShowCheckmark for UI feedback.
LDKNodeMonday/View/Home/Send/AmountView.swift Simplified payment handling logic in Button action with a direct call to viewModel.send(uriStr: address).

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AmountViewModel
    participant LightningNodeService

    User->>AmountViewModel: send(uriStr)
    AmountViewModel->>LightningNodeService: Process payment
    LightningNodeService-->>AmountViewModel: Payment result
    AmountViewModel-->>User: Display result
Loading

🐇 In the code, I hop with glee,
To see changes made so swiftly!
Old paths gone, new ways to play,
With payments smoother every day.
A network fresh, so bright and clear,
Hooray for updates, bring us cheer! 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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 resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

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.

@reez reez merged commit 08c391c into main Aug 27, 2024
1 check passed
@reez reez deleted the one branch August 27, 2024 17:15
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: 4

Outside diff range, codebase verification and nitpick comments (2)
LDKNodeMonday/View Model/Home/AmountViewModel.swift (2)

19-22: Improve error handling by using a more descriptive error message.

The error message can be more descriptive to help with debugging.

- let errorString = handleNodeError(error)
+ let errorString = handleNodeError(error) ?? "An unknown error occurred"

Line range hint 19-40: Break down the error handling into smaller functions.

The error handling can be broken down into smaller functions to improve readability.

- do {
-     let qrPaymentResult = try await LightningNodeService.shared.send(uriStr: uriStr)
-     return qrPaymentResult
- } catch let error as NodeError {
-     NotificationCenter.default.post(name: .ldkErrorReceived, object: error)
-     let errorString = handleNodeError(error)
-     DispatchQueue.main.async {
-         self.amountConfirmationViewError = .init(
-             title: errorString.title,
-             detail: errorString.detail
-         )
-     }
-     throw error
- } catch {
-     DispatchQueue.main.async {
-         self.amountConfirmationViewError = .init(
-             title: "Unexpected error",
-             detail: error.localizedDescription
-         )
-     }
-     throw error
- }

+ do {
+     let qrPaymentResult = try await LightningNodeService.shared.send(uriStr: uriStr)
+     return qrPaymentResult
+ } catch let error as NodeError {
+     handleNodeError(error)
+     throw error
+ } catch {
+     handleUnexpectedError(error)
+     throw error
+ }
+
+ private func handleNodeError(_ error: NodeError) {
+     NotificationCenter.default.post(name: .ldkErrorReceived, object: error)
+     let errorString = handleNodeError(error) ?? "An unknown error occurred"
+     DispatchQueue.main.async {
+         self.amountConfirmationViewError = .init(
+             title: errorString.title,
+             detail: errorString.detail
+         )
+     }
+ }
+
+ private func handleUnexpectedError(_ error: Error) {
+     DispatchQueue.main.async {
+         self.amountConfirmationViewError = .init(
+             title: "Unexpected error",
+             detail: error.localizedDescription
+         )
+     }
+ }
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 98951c2 and 05aaeb6.

Files selected for processing (8)
  • LDKNodeMonday.xcodeproj/project.pbxproj (12 hunks)
  • LDKNodeMonday/Extensions/String+Extensions.swift (1 hunks)
  • LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift (3 hunks)
  • LDKNodeMonday/View Model/Home/AmountViewModel.swift (3 hunks)
  • LDKNodeMonday/View Model/Home/OnboardingViewModel.swift (2 hunks)
  • LDKNodeMonday/View Model/Home/Receive/BIP21ViewModel.swift (1 hunks)
  • LDKNodeMonday/View/Home/Receive/BIP21View.swift (2 hunks)
  • LDKNodeMonday/View/Home/Send/AmountView.swift (2 hunks)
Files skipped from review due to trivial changes (1)
  • LDKNodeMonday.xcodeproj/project.pbxproj
Additional context used
SwiftLint
LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift

[Error] 24-24: Force tries should be avoided

(force_try)


[Error] 26-26: Force tries should be avoided

(force_try)

Additional comments not posted (5)
LDKNodeMonday/Service/Lightning Service/LightningNodeService.swift (1)

29-29: Verify the impact of removed payment-related methods.

The removal of several payment-related methods might affect other parts of the codebase. Ensure that all references to these methods are updated or removed.

Run the following script to verify the impact of removed methods:

Verification successful

No impact from removed payment-related methods found.

The search for references to the removed payment-related methods returned no results, indicating that their removal does not impact other parts of the codebase. If there is any uncertainty, consider manual verification to ensure completeness.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the impact of removed payment-related methods.

# Test: Search for references to removed methods. Expect: No occurrences.
rg --type swift -A 5 $'sendToAddress\(|send\(bolt11Invoice:|send\(bolt12Invoice:|sendUsingAmount\(bolt11Invoice:amountMsat:|sendUsingAmount\(bolt12Invoice:amountMsat:|receive\(amountMsat:description:expirySecs:|receive\(amountMsat:description:|receiveVariableAmount\(description:expirySecs:|receiveVariableAmount\(description:'

Length of output: 328

LDKNodeMonday/View/Home/Send/AmountView.swift (2)

185-187: LGTM!

The change standardizes the address format before further processing.

The code changes are approved.


135-135: Verify the correctness of viewModel.send(uriStr:).

The change simplifies the payment handling logic. Ensure that viewModel.send(uriStr:) handles all payment types correctly.

Run the following script to verify the implementation of viewModel.send(uriStr:):

LDKNodeMonday/View/Home/Receive/BIP21View.swift (2)

20-21: LGTM!

The new state variables unifiedIsCopied and unifiedShowCheckmark are correctly introduced to manage the copy state and visual feedback for the unified string.

The code changes are approved.


84-127: LGTM!

The new section displaying the unified string and the copy button is well-implemented. The use of state variables to manage the copy state and show a checkmark animation provides a good user experience.

The code changes are approved.

Comment on lines +26 to +29
let unifiedLowercase = unified.lowercaseScheme()

DispatchQueue.main.async {
self.unified = unified
self.unified = unifiedLowercase
Copy link

Choose a reason for hiding this comment

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

Break down the error handling into smaller functions.

The error handling can be broken down into smaller functions to improve readability.

- do {
-     let unified = try await LightningNodeService.shared.receive(
-         amountSat: amountSat,
-         message: message,
-         expirySec: expirySecs
-     )
-     let unifiedLowercase = unified.lowercaseScheme()
-     DispatchQueue.main.async {
-         self.unified = unifiedLowercase
-     }
- } catch let error as NodeError {
-     let errorString = handleNodeError(error)
-     DispatchQueue.main.async {
-         self.receiveViewError = .init(title: errorString.title, detail: errorString.detail)
-     }
- } catch {
-     DispatchQueue.main.async {
-         self.receiveViewError = .init(
-             title: "Unexpected error",
-             detail: error.localizedDescription
-         )
-     }
- }

+ do {
+     let unified = try await LightningNodeService.shared.receive(
+         amountSat: amountSat,
+         message: message,
+         expirySec: expirySecs
+     )
+     let unifiedLowercase = unified.lowercaseScheme()
+     DispatchQueue.main.async {
+         self.unified = unifiedLowercase
+     }
+ } catch let error as NodeError {
+     handleNodeError(error)
+ } catch {
+     handleUnexpectedError(error)
+ }
+
+ private func handleNodeError(_ error: NodeError) {
+     let errorString = handleNodeError(error)
+     DispatchQueue.main.async {
+         self.receiveViewError = .init(title: errorString.title, detail: errorString.detail)
+     }
+ }
+
+ private func handleUnexpectedError(_ error: Error) {
+     DispatchQueue.main.async {
+         self.receiveViewError = .init(
+             title: "Unexpected error",
+             detail: error.localizedDescription
+         )
+     }
+ }

Committable suggestion was skipped due to low confidence.

Comment on lines +82 to +84
self.selectedNetwork = Network(stringValue: networkString) ?? .signet
} else {
self.selectedNetwork = .testnet
self.selectedNetwork = .signet
Copy link

Choose a reason for hiding this comment

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

Break down the error handling into smaller functions.

The error handling can be broken down into smaller functions to improve readability.

- do {
-     if let networkString = try KeyClient.live.getNetwork() {
-         self.selectedNetwork = Network(stringValue: networkString) ?? .signet
-     } else {
-         self.selectedNetwork = .signet
-     }
-     if let esploraURL = try KeyClient.live.getEsploraURL() {
-         self.selectedURL = esploraURL
-     } else {
-         self.selectedURL = availableURLs.first ?? ""
-     }
- } catch {
-     DispatchQueue.main.async {
-         self.onboardingViewError = .init(
-             title: "Error Getting Network/Esplora",
-             detail: error.localizedDescription
-         )
-     }
- }

+ do {
+     if let networkString = try KeyClient.live.getNetwork() {
+         self.selectedNetwork = Network(stringValue: networkString) ?? .signet
+     } else {
+         self.selectedNetwork = .signet
+     }
+     if let esploraURL = try KeyClient.live.getEsploraURL() {
+         self.selectedURL = esploraURL
+     } else {
+         self.selectedURL = availableURLs.first ?? ""
+     }
+ } catch {
+     handleOnboardingError(error)
+ }
+
+ private func handleOnboardingError(_ error: Error) {
+     DispatchQueue.main.async {
+         self.onboardingViewError = .init(
+             title: "Error Getting Network/Esplora",
+             detail: error.localizedDescription
+         )
+     }
+ }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
self.selectedNetwork = Network(stringValue: networkString) ?? .signet
} else {
self.selectedNetwork = .testnet
self.selectedNetwork = .signet
self.selectedNetwork = Network(stringValue: networkString) ?? .signet
} else {
self.selectedNetwork = .signet
}
} catch {
handleOnboardingError(error)
}
private func handleOnboardingError(_ error: Error) {
DispatchQueue.main.async {
self.onboardingViewError = .init(
title: "Error Getting Network/Esplora",
detail: error.localizedDescription
)
}
}

Comment on lines +229 to +235
func lowercaseScheme() -> String {
guard let colonIndex = self.firstIndex(of: ":") else {
return self
}
let scheme = self[..<colonIndex].lowercased()
return scheme + self[colonIndex...]
}
Copy link

Choose a reason for hiding this comment

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

Add a test case for lowercaseScheme.

The function is correctly implemented. However, adding a test case will help verify its behavior and ensure it works as expected.

Add a test case in the relevant test file to verify the behavior of lowercaseScheme.

Comment on lines +24 to +27
let storedNetworkString = try! keyService.getNetwork() ?? Network.signet.description
let storedEsploraURL =
try! keyService.getEsploraURL()
?? Constants.Config.EsploraServerURLNetwork.Testnet.mempoolspace
?? Constants.Config.EsploraServerURLNetwork.Signet.mutiny
Copy link

Choose a reason for hiding this comment

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

Avoid force tries.

Force tries should be avoided to handle potential errors gracefully. Use try with proper error handling instead.

Apply this diff to avoid force tries:

- let storedNetworkString = try! keyService.getNetwork() ?? Network.signet.description
- let storedEsploraURL = try! keyService.getEsploraURL() ?? Constants.Config.EsploraServerURLNetwork.Signet.mutiny
+ do {
+     let storedNetworkString = try keyService.getNetwork() ?? Network.signet.description
+     let storedEsploraURL = try keyService.getEsploraURL() ?? Constants.Config.EsploraServerURLNetwork.Signet.mutiny
+ } catch {
+     // Handle error appropriately
+ }
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let storedNetworkString = try! keyService.getNetwork() ?? Network.signet.description
let storedEsploraURL =
try! keyService.getEsploraURL()
?? Constants.Config.EsploraServerURLNetwork.Testnet.mempoolspace
?? Constants.Config.EsploraServerURLNetwork.Signet.mutiny
do {
let storedNetworkString = try keyService.getNetwork() ?? Network.signet.description
let storedEsploraURL = try keyService.getEsploraURL() ?? Constants.Config.EsploraServerURLNetwork.Signet.mutiny
} catch {
// Handle error appropriately
}
Tools
SwiftLint

[Error] 24-24: Force tries should be avoided

(force_try)


[Error] 26-26: Force tries should be avoided

(force_try)

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