Skip to content

Conversation

ericholguin
Copy link
Collaborator

@ericholguin ericholguin commented Apr 26, 2025

Summary

This PR adds the fiat price to user's wallet balance. Using Coinbase API to get BTC current price and the user's locale (region) to determine their currency.

Changelog-Added: Added fiat pricing to wallet balance

Checklist

  • I have read (or I am familiar with) the Contribution Guidelines
  • I have tested the changes in this PR
  • I have opened or referred to an existing github issue related to this change.
  • My PR is either small, or I have split it into smaller logical commits that are easier to review
  • I have added the signoff line to all my commits. See Signing off your work
  • I have added appropriate changelog entries for the changes in this PR. See Adding changelog entries
    • I do not need to add a changelog entry. Reason: [Please provide a reason]
  • I have added appropriate Closes: or Fixes: tags in the commit messages wherever applicable, or made sure those are not needed. See Submitting patches

Test report

Please provide a test report for the changes in this PR. You can use the template below, but feel free to modify it as needed.

Device: [Please specify the device you used for testing]
iPhone 16 Pro

iOS: [Please specify the iOS version you used for testing]
18.3.2

Damus: [Please specify the Damus version or commit hash you used for testing]
1.14 (1) 54d6161

Setup: [Please provide a brief description of the setup you used for testing, if applicable]

XCode Simulator / Local Device

Steps: [Please provide a list of steps you took to test the changes in this PR]

Open Wallet Balance verify there is a fiat price below the wallet balance and verify it is in your regional currency.

Results:

  • PASS
  • Partial PASS
    • Details: [Please provide details of the partial pass]

Other notes

[Please provide any other information that you think is relevant to this PR.]

@jb55
Copy link
Collaborator

jb55 commented Apr 26, 2025 via email

@jb55
Copy link
Collaborator

jb55 commented Apr 26, 2025 via email

@jb55 jb55 requested a review from Copilot April 26, 2025 00:37
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds fiat pricing to the wallet balance by integrating Coinbase API pricing data and displaying the converted value in the wallet UI. Key changes include:

  • Adjusting the vertical spacing in WalletView for enhanced layout consistency.
  • Updating BalanceView to instantiate and display fiat pricing from a new CoinbaseModel.
  • Introducing CoinbaseModel to handle BTC price fetching, caching, and conversion.

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

File Description
damus/Views/Wallet/WalletView.swift Increased VStack spacing to improve UI layout
damus/Views/Wallet/BalanceView.swift Added CoinbaseModel instantiation and fiat price display
damus/Models/CoinbaseModel.swift New model to fetch, cache, and convert BTC to fiat pricing
Files not reviewed (1)
  • damus.xcodeproj/project.pbxproj: Language not supported

Copy link
Collaborator

@jb55 jb55 left a comment

Choose a reason for hiding this comment

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

potential crash

This PR adds the fiat price to user's wallet balance.
Using Coinbase API to get BTC current price and the user's locale (region)
to determine their currency.

Changelog-Added: Added fiat pricing to wallet balance

Signed-off-by: ericholguin <[email protected]>
Copy link
Collaborator

@danieldaquino danieldaquino left a comment

Choose a reason for hiding this comment

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

Thanks @ericholguin! I added some comments regarding a few concerns I have with the changes.

if symbol.isEmpty || symbol == currency {
return amount + " " + currency
}
return symbol + amount + " " + currency
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems to be making some assumptions about currency value formatting that might not be true for some locales.

I believe Apple provides a way to format currencies in a simpler and localization-friendly way, by using numberStyle = .currency instead of numberStyle = .decimal:


struct CoinbasePrice: Codable {
let amount: Double
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

nitpick tip: The structs CoinbasePrice and CoinbaseResponse exist in the context of CoinbaseModel, so we can move them inside CoinbaseModel to make namespace semantics more explicit and avoid having too many names in the global namespace:

struct CoinbaseModel {
    ...
    struct Response: Codable {
        let data: Price
        
        struct Price: Codable {
            let amount: Double
        }
    }
}


func satsToFiat(input: Int64) -> String {
guard let btcPrice = btcPrice, input > 0 else {
return ""
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should use more expressive semantics of the result, and let the view choose how to handle failures.

Instead of defaulting to an empty string or value when something fails, we should:

  • throw errors if something unexpected happened, and then let the view choose whether to show or suppress those errors.
  • Return nil if there is no value available.

self.btcPrice = decoded.data.amount
}
} catch {
print("Failed to fetch BTC price from Coinbase: \(error)")
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am a bit worried about how this error is being handled. If something is broken or the API stops working, the interface will just keep displaying the last known value forever, which might be misleading and hard to notice.

@ericholguin ericholguin requested a review from danieldaquino May 21, 2025 00:05
@danieldaquino danieldaquino requested a review from Copilot May 26, 2025 23:47
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds fiat pricing to the user's wallet balance by fetching BTC spot prices from Coinbase and displaying converted values in the Wallet UI.

  • Increased spacing in the wallet view to make room for the new fiat price line
  • Introduced a CoinbaseModel to fetch, cache, and convert sats to local fiat
  • Integrated the fiat conversion into BalanceView with on-appear load and fetch calls

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
damus/Views/Wallet/WalletView.swift Adjusted VStack spacing to accommodate the added fiat line
damus/Views/Wallet/BalanceView.swift Added @StateObject for CoinbaseModel and fiat price display
damus/Models/CoinbaseModel.swift New model for fetching/caching BTC price and converting sats
damus.xcodeproj/project.pbxproj Registered CoinbaseModel.swift in build settings
Comments suppressed due to low confidence (2)

damus/Views/Wallet/BalanceView.swift:12

  • [nitpick] The variable name coinbase is a bit ambiguous; consider renaming it to something like coinbaseViewModel or priceModel to clarify its role.
@StateObject private var coinbase = CoinbaseModel()

damus/Models/CoinbaseModel.swift:1

  • New logic for price fetching, caching, and conversion lacks unit tests. Consider adding tests for satsToFiat, caching behavior, and fetchFromCoinbase error handling.
//

Comment on lines +21 to +23
Text(coinbase.satsToFiat(input: balance))
.fontWeight(.medium)
.foregroundStyle(DamusColors.neutral6)
Copy link

Copilot AI May 26, 2025

Choose a reason for hiding this comment

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

If satsToFiat returns an empty string (e.g., zero balance or missing price), this Text will render blank space. Consider conditionally showing the view only when the string is non-empty.

Suggested change
Text(coinbase.satsToFiat(input: balance))
.fontWeight(.medium)
.foregroundStyle(DamusColors.neutral6)
let fiatValue = coinbase.satsToFiat(input: balance)
if !fiatValue.isEmpty {
Text(fiatValue)
.fontWeight(.medium)
.foregroundStyle(DamusColors.neutral6)
}

Copilot uses AI. Check for mistakes.

@damus-io damus-io deleted a comment from Copilot AI May 26, 2025
@damus-io damus-io deleted a comment from Copilot AI May 26, 2025
@damus-io damus-io deleted a comment from Copilot AI May 26, 2025
@damus-io damus-io deleted a comment from Copilot AI May 26, 2025
Copy link
Collaborator

@danieldaquino danieldaquino left a comment

Choose a reason for hiding this comment

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

Some items still need addressing. Please let me know if there are any questions on the comments placed.

Copy link
Collaborator

@tyiu tyiu left a comment

Choose a reason for hiding this comment

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

Decimal should be used instead of Double to avoid precision issues.


class CoinbaseModel: ObservableObject {

@Published var btcPrice: Double? = nil {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
@Published var btcPrice: Double? = nil {
@Published var btcPrice: Decimal? = nil {

guard let btcPrice = btcPrice, input > 0 else {
return ""
}
let fiat = (Double(input) / 100_000_000) * btcPrice
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let fiat = (Double(input) / 100_000_000) * btcPrice
let fiat = (Decimal(input) / 100_000_000) * btcPrice

}
}

private func cachePrice(_ price: Double) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
private func cachePrice(_ price: Double) {
private func cachePrice(_ price: Decimal) {

}

struct CoinbasePrice: Codable {
let amount: Double
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let amount: Double
let amount: Decimal

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.

4 participants