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

(ios) Display swap-in grace period & timeouts #454

Merged
merged 3 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions phoenix-ios/phoenix-ios.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@
DC81B79F25BF2AA200F5A52C /* MVI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC81B79E25BF2AA200F5A52C /* MVI.swift */; };
DC82EED629789853007A5853 /* TxHistoryExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC82EED529789853007A5853 /* TxHistoryExporter.swift */; };
DC89857F25914747007B253F /* UIApplicationState+Phoenix.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC89857E25914747007B253F /* UIApplicationState+Phoenix.swift */; };
DC9130A02AE045FA00F9B8C6 /* Sequence+Sum.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC59377027516296003B4B53 /* Sequence+Sum.swift */; };
DC9473FA261270B4008D7242 /* MVI+Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9473F9261270B4008D7242 /* MVI+Mock.swift */; };
DC9545C429490321008FCEF4 /* NotificationContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9545C329490321008FCEF4 /* NotificationContent.swift */; };
DC9545C5294905FB008FCEF4 /* NotificationContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9545C329490321008FCEF4 /* NotificationContent.swift */; };
Expand Down Expand Up @@ -275,6 +276,7 @@
DCFAEFC92A72F48700330088 /* SwapInWalletDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFAEFC82A72F48700330088 /* SwapInWalletDetails.swift */; };
DCFB8DF72A94066100947698 /* Task+Sleep.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFB8DF62A94066100947698 /* Task+Sleep.swift */; };
DCFB8DF92A94112A00947698 /* Dictionary+MapKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFB8DF82A94112A00947698 /* Dictionary+MapKeys.swift */; };
DCFBC5592AE2CFEF00E3A418 /* BizNotificationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFBC5582AE2CFEF00E3A418 /* BizNotificationCell.swift */; };
DCFC72042862237400D6B293 /* Asserts.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFC72032862237400D6B293 /* Asserts.swift */; };
DCFD079126D84A380020DD8E /* HorizontalActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFD079026D84A380020DD8E /* HorizontalActivity.swift */; };
F4AED298257A50CD009485C1 /* LogsConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4AED296257A50CD009485C1 /* LogsConfigurationView.swift */; };
Expand Down Expand Up @@ -593,6 +595,7 @@
DCFAEFC82A72F48700330088 /* SwapInWalletDetails.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwapInWalletDetails.swift; sourceTree = "<group>"; };
DCFB8DF62A94066100947698 /* Task+Sleep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Task+Sleep.swift"; sourceTree = "<group>"; };
DCFB8DF82A94112A00947698 /* Dictionary+MapKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+MapKeys.swift"; sourceTree = "<group>"; };
DCFBC5582AE2CFEF00E3A418 /* BizNotificationCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BizNotificationCell.swift; sourceTree = "<group>"; };
DCFC72032862237400D6B293 /* Asserts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Asserts.swift; sourceTree = "<group>"; };
DCFD079026D84A380020DD8E /* HorizontalActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HorizontalActivity.swift; sourceTree = "<group>"; };
F4AED296257A50CD009485C1 /* LogsConfigurationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogsConfigurationView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1015,6 +1018,7 @@
DC355E242A45FDD3008E8A8E /* NoticeMonitor.swift */,
DC355E1E2A44A235008E8A8E /* NotificationCell.swift */,
DC355E202A44D838008E8A8E /* NotificationsView.swift */,
DCFBC5582AE2CFEF00E3A418 /* BizNotificationCell.swift */,
);
path = notifications;
sourceTree = "<group>";
Expand Down Expand Up @@ -1753,6 +1757,7 @@
DC27E4C42791C58C00C777CC /* PaymentsBackupView.swift in Sources */,
DC59377127516297003B4B53 /* Sequence+Sum.swift in Sources */,
DCA125752A27EDDB00DA2F7F /* MempoolRecommendedResponse.swift in Sources */,
DCFBC5592AE2CFEF00E3A418 /* BizNotificationCell.swift in Sources */,
DC46CB1228D9AAB000C4EAC7 /* LockState.swift in Sources */,
DC2F431427B6972C0006FCC4 /* SwapInView.swift in Sources */,
DC71E7352728A5720063613D /* KotlinIdentifiable.swift in Sources */,
Expand Down Expand Up @@ -1786,6 +1791,7 @@
DC641C7328208B7F00862DCD /* UserDefaults+Codable.swift in Sources */,
DCA6DED1282ABA930073C658 /* KeychainConstants.swift in Sources */,
DCEB2796282D7AAB0096B87E /* KotlinTypes.swift in Sources */,
DC9130A02AE045FA00F9B8C6 /* Sequence+Sum.swift in Sources */,
DCB511CA281AED58001BC525 /* NotificationService.swift in Sources */,
DCA6DEC82829C3150073C658 /* GenericPasswordStore.swift in Sources */,
DCA6DECD282AB10C0073C658 /* SharedSecurity.swift in Sources */,
Expand Down
49 changes: 49 additions & 0 deletions phoenix-ios/phoenix-ios/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1985,6 +1985,9 @@
}
}
}
},
"A deposit will expire soon." : {

},
"A fee of %@ (≈ %@) may be needed to receive this payment." : {
"localizations" : {
Expand Down Expand Up @@ -2858,6 +2861,7 @@
}
},
"An on-chain wallet derived from your seed.\n\nThe swap-in wallet is a bridge to Lightning. Funds on this wallet will automatically be moved to Lightning according to your liquidity policy setting." : {
"extractionState" : "stale",
"localizations" : {
"es" : {
"stringUnit" : {
Expand Down Expand Up @@ -3388,8 +3392,12 @@
}
}
}
},
"Background payments disabled." : {

},
"Background payments disabled. " : {
"extractionState" : "stale",
"localizations" : {
"es" : {
"stringUnit" : {
Expand Down Expand Up @@ -4184,6 +4192,9 @@
}
}
}
},
"Cancelled Funds" : {

},
"capacity" : {
"localizations" : {
Expand Down Expand Up @@ -4466,6 +4477,7 @@
}
},
"Check it " : {
"extractionState" : "stale",
"localizations" : {
"es" : {
"stringUnit" : {
Expand Down Expand Up @@ -7730,6 +7742,7 @@
}
},
"Error: invalid hash" : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -8489,6 +8502,7 @@
}
},
"Fix " : {
"extractionState" : "stale",
"localizations" : {
"es" : {
"stringUnit" : {
Expand Down Expand Up @@ -8839,6 +8853,9 @@
}
}
}
},
"Funds not swapped **after 4 months** are recoverable on-chain" : {

},
"Funds sent" : {
"localizations" : {
Expand Down Expand Up @@ -10618,6 +10635,7 @@
}
},
"Last Attempt" : {
"extractionState" : "stale",
"localizations" : {
"es" : {
"stringUnit" : {
Expand All @@ -10632,6 +10650,9 @@
}
}
}
},
"Last attempt failed" : {

},
"layer 1 -> 2" : {
"comment" : "Transaction Info: Explanation",
Expand Down Expand Up @@ -10752,6 +10773,7 @@
}
},
"Let's go " : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -12045,6 +12067,7 @@
}
},
"More info " : {
"extractionState" : "stale",
"localizations" : {
"es" : {
"stringUnit" : {
Expand Down Expand Up @@ -15720,6 +15743,7 @@
}
},
"See how Phoenix is affected" : {
"extractionState" : "stale",
"localizations" : {
"ar" : {
"stringUnit" : {
Expand Down Expand Up @@ -18405,6 +18429,9 @@
}
}
}
},
"The swap-in wallet is a bridge to Lightning. Funds on this wallet will automatically be moved to Lightning according to your liquidity policy setting." : {

},
"The transaction may take 30 minutes or more to confirm on the bitcoin blockchain" : {
"localizations" : {
Expand Down Expand Up @@ -18475,6 +18502,15 @@
}
}
}
},
"These funds were not swapped in time. Use the wallet's descriptor to access them." : {

},
"These funds will be available from %lld days onwards." : {

},
"These funds will be available from 1 day onwards." : {

},
"This address is derived from your seed and belongs to you." : {
"localizations" : {
Expand Down Expand Up @@ -18823,6 +18859,12 @@
}
}
}
},
"This swap will expire in %lld days" : {

},
"This swap will expire in 1 day" : {

},
"This will reset the app, as if you had just installed it." : {
"localizations" : {
Expand Down Expand Up @@ -18883,6 +18925,9 @@
}
}
}
},
"Timed-Out Funds" : {

},
"timestamp" : {
"comment" : "Label in DetailsView_IncomingPayment",
Expand Down Expand Up @@ -20777,8 +20822,12 @@
}
}
}
},
"Watchtower disabled." : {

},
"Watchtower disabled. " : {
"extractionState" : "stale",
"localizations" : {
"es" : {
"stringUnit" : {
Expand Down
2 changes: 1 addition & 1 deletion phoenix-ios/phoenix-ios/extensions/Sequence+Sum.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation

extension Sequence where Element: AdditiveArithmetic {
func sum() -> Element { reduce(.zero, +) }
func sum() -> Element { reduce(.zero, +) }
}
67 changes: 62 additions & 5 deletions phoenix-ios/phoenix-ios/kotlin/KotlinExtensions+Lightning.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,89 @@ extension Lightning_kmpConnection {
extension Lightning_kmpWalletState.WalletWithConfirmations {

var unconfirmedBalance: Bitcoin_kmpSatoshi {
let balance = unconfirmed.map { $0.amount }.reduce(Int64(0)) { $0 + $1.toLong() }
let balance = unconfirmed.map { $0.amount.toLong() }.sum()
return Bitcoin_kmpSatoshi(sat: balance)
}

var weaklyConfirmedBalance: Bitcoin_kmpSatoshi {
let balance = weaklyConfirmed.map { $0.amount }.reduce(Int64(0)) { $0 + $1.toLong() }
let balance = weaklyConfirmed.map { $0.amount.toLong() }.sum()
return Bitcoin_kmpSatoshi(sat: balance)
}

var deeplyConfirmedBalance: Bitcoin_kmpSatoshi {
let balance = deeplyConfirmed.map { $0.amount }.reduce(Int64(0)) { $0 + $1.toLong() }
let balance = deeplyConfirmed.map { $0.amount.toLong() }.sum()
return Bitcoin_kmpSatoshi(sat: balance)
}

var lockedUntilRefundBalance: Bitcoin_kmpSatoshi {
let balance = lockedUntilRefund.map { $0.amount.toLong() }.sum()
return Bitcoin_kmpSatoshi(sat: balance)
}

var readyForRefundBalance: Bitcoin_kmpSatoshi {
let balance = readyForRefund.map { $0.amount.toLong() }.sum()
return Bitcoin_kmpSatoshi(sat: balance)
}

var anyConfirmedBalance: Bitcoin_kmpSatoshi {
let anyConfirmedTx = weaklyConfirmed + deeplyConfirmed
let balance = anyConfirmedTx.map { $0.amount }.reduce(Int64(0)) { $0 + $1.toLong() }
let balance = anyConfirmedTx.map { $0.amount.toLong() }.sum()
return Bitcoin_kmpSatoshi(sat: balance)
}

var totalBalance: Bitcoin_kmpSatoshi {
let allTx = unconfirmed + weaklyConfirmed + deeplyConfirmed
let balance = allTx.map { $0.amount }.reduce(Int64(0)) { $0 + $1.toLong() }
let balance = allTx.map { $0.amount.toLong() }.sum()
return Bitcoin_kmpSatoshi(sat: balance)
}

/// The `deeplyConfirmed` property contains UTXO's that are also represented in
/// `lockedUntilRefund` & `readyForRefund`. This property is a subset of
/// `deeplyConfirmed` that excludes those 2 categories.
///
var readyForSwap: [Lightning_kmpWalletState.Utxo] {
let timedOut = Set(self.lockedUntilRefund + self.readyForRefund)
return deeplyConfirmed.filter {
!timedOut.contains($0)
}
}

var readyForSwapBalance: Bitcoin_kmpSatoshi {
let balance = readyForSwap.map { $0.amount.toLong() }.sum()
return Bitcoin_kmpSatoshi(sat: balance)
}

/// Returns non-nil if any "ready for swap" UTXO's have an expiration date that
/// is less than 30 days away.
func expirationWarningInDays() -> Int? {

let maxConfirmations = swapInParams.maxConfirmations
let remainingConfirmationsList = readyForSwap.map {
maxConfirmations - confirmations(utxo: $0)
}

if let minRemainingConfirmations = remainingConfirmationsList.min() {
let days: Double = Double(minRemainingConfirmations) / 144.0
let result = Int(days.rounded(.awayFromZero))
if result < 30 {
return result
}
}

return nil
}

#if DEBUG
func fakeBlockHeight(plus diff: Int32) -> Lightning_kmpWalletState.WalletWithConfirmations {

return Lightning_kmpWalletState.WalletWithConfirmations(
swapInParams: self.swapInParams,
currentBlockHeight: self.currentBlockHeight + diff,
all: self.all
)
}
#endif

static func empty() -> Lightning_kmpWalletState.WalletWithConfirmations {
return Lightning_kmpWalletState.WalletWithConfirmations(
swapInParams: LightningExposureKt.defaultSwapInParams(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ fileprivate struct ConfigurationList: View {
case .backgroundPayments : newNavLinkTag = .PaymentOptions ; delay *= 2
case .liquiditySettings : newNavLinkTag = .ChannelManagement ; delay *= 1
case .forceCloseChannels : newNavLinkTag = .ForceCloseChannels ; delay *= 1
case .swapInWallet : newNavLinkTag = .WalletInfo ; delay *= 2
}

if let newNavLinkTag = newNavLinkTag {
Expand Down
Loading