-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Transfer activities #212
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
Closed
Closed
Changes from 17 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
38417b4
chore: add forceClose parameter
jvsena42 2c61e60
feat: force transfer sheet and action
jvsena42 d235f73
Merge branch 'master' into feat/force-close
jvsena42 0c61e10
fix: parameter name
jvsena42 a8a927f
chore: remove redundant variable
jvsena42 7a5c6cf
fix: agregate errors and throw an agregated list
jvsena42 9cc4ab8
chore: remove weak reference
jvsena42 ac75fd7
Merge branch 'master' into feat/force-close
jvsena42 5eaba87
Merge branch 'feat/force-close' of github.com:synonymdev/bitkit-ios i…
jvsena42 354976c
chore: remove log
jvsena42 120f986
Merge branch 'master' into feat/transfer-activities
jvsena42 a017499
feat: metadata model
jvsena42 386d12f
feat: create store class
jvsena42 f5846f3
feat: save metadata on send method
jvsena42 7cb329d
refactor: move metadata saving to LightningService
jvsena42 8881e51
chore: create updateActivityMetadata method
jvsena42 77c1905
feat: Update activities with saved metadata after syncing payments
jvsena42 2aea2f0
Merge branch 'master' into feat/transfer-activities
jvsena42 4c6c59e
Merge branch 'master' into feat/transfer-activities
jvsena42 4c15d11
chore: add logs
jvsena42 a69df2a
chore: log
jvsena42 878f35b
fix: update pbxproj
jvsena42 bfa4025
fix: prevent rewrite with old payment data
jvsena42 e27b069
feat: transfer fee estimation
jvsena42 46f8fed
feat: backup activities
jvsena42 b1f27b1
chore: update pbxproj
jvsena42 7c1df36
Merge branch 'master' into feat/transfer-activities
jvsena42 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import Foundation | ||
|
|
||
| /// Metadata for onchain transactions that needs to be temporarily stored | ||
| /// until it can be applied to activities during sync operations | ||
| struct TransactionMetadata: Codable, Identifiable { | ||
| /// Transaction ID (also serves as the unique identifier) | ||
| let txId: String | ||
|
|
||
| /// Fee rate in satoshis per vbyte | ||
| let feeRate: UInt64 | ||
|
|
||
| /// Destination address | ||
| let address: String | ||
|
|
||
| /// Whether this transaction is a transfer between wallets (e.g., channel funding) | ||
| let isTransfer: Bool | ||
|
|
||
| /// Associated channel ID for channel funding transactions | ||
| let channelId: String? | ||
|
|
||
| /// Timestamp when this metadata was created (for cleanup purposes) | ||
| let createdAt: UInt64 | ||
|
|
||
| var id: String { txId } | ||
|
|
||
| init( | ||
| txId: String, | ||
| feeRate: UInt64, | ||
| address: String, | ||
| isTransfer: Bool, | ||
| channelId: String? = nil, | ||
| createdAt: UInt64 | ||
| ) { | ||
| self.txId = txId | ||
| self.feeRate = feeRate | ||
| self.address = address | ||
| self.isTransfer = isTransfer | ||
| self.channelId = channelId | ||
| self.createdAt = createdAt | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| import Combine | ||
| import Foundation | ||
|
|
||
| /// Handles persistence of TransactionMetadata objects using UserDefaults | ||
| /// Metadata is temporarily stored until it can be applied to activities during sync | ||
| class TransactionMetadataStorage { | ||
| static let shared = TransactionMetadataStorage() | ||
|
|
||
| private let defaults: UserDefaults | ||
| private let metadataKey = "transactionMetadata" | ||
|
|
||
| private let metadataChangedSubject = PassthroughSubject<Void, Never>() | ||
jvsena42 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| var metadataChangedPublisher: AnyPublisher<Void, Never> { | ||
| metadataChangedSubject.eraseToAnyPublisher() | ||
| } | ||
|
|
||
| private init(suiteName: String? = nil) { | ||
| if let suiteName { | ||
| defaults = UserDefaults(suiteName: suiteName) ?? .standard | ||
| } else { | ||
| defaults = .standard | ||
| } | ||
| } | ||
|
|
||
| /// Insert a new transaction metadata entry | ||
| func insert(_ metadata: TransactionMetadata) throws { | ||
| var allMetadata = try getAll() | ||
|
|
||
| // Check if metadata for this txId already exists | ||
| if allMetadata.contains(where: { $0.txId == metadata.txId }) { | ||
| Logger.warn("Transaction metadata for \(metadata.txId) already exists, skipping insert", context: "TransactionMetadataStorage") | ||
| return | ||
| } | ||
|
|
||
| allMetadata.append(metadata) | ||
| try save(allMetadata) | ||
| Logger.info("Inserted transaction metadata: txId=\(metadata.txId)", context: "TransactionMetadataStorage") | ||
| metadataChangedSubject.send() | ||
| } | ||
|
|
||
| /// Insert a list of transaction metadata entries (for restore operations) | ||
| func insertList(_ metadataList: [TransactionMetadata]) throws { | ||
| var allMetadata = try getAll() | ||
| var hasChanges = false | ||
|
|
||
| for metadata in metadataList { | ||
| // Only insert if not already present | ||
| if !allMetadata.contains(where: { $0.txId == metadata.txId }) { | ||
| allMetadata.append(metadata) | ||
| hasChanges = true | ||
| } | ||
| } | ||
|
|
||
| if hasChanges { | ||
| try save(allMetadata) | ||
| Logger.info("Inserted \(metadataList.count) transaction metadata entries", context: "TransactionMetadataStorage") | ||
| metadataChangedSubject.send() | ||
| } | ||
| } | ||
|
|
||
| /// Get all stored transaction metadata | ||
| func getAll() throws -> [TransactionMetadata] { | ||
| guard let data = defaults.data(forKey: metadataKey) else { | ||
| return [] | ||
| } | ||
|
|
||
| let decoder = JSONDecoder() | ||
| return try decoder.decode([TransactionMetadata].self, from: data) | ||
| } | ||
|
|
||
| /// Remove metadata by transaction ID | ||
| func remove(txId: String) throws { | ||
| var allMetadata = try getAll() | ||
| let originalCount = allMetadata.count | ||
|
|
||
| allMetadata.removeAll { $0.txId == txId } | ||
|
|
||
| if allMetadata.count != originalCount { | ||
| try save(allMetadata) | ||
| Logger.info("Removed transaction metadata: txId=\(txId)", context: "TransactionMetadataStorage") | ||
| metadataChangedSubject.send() | ||
| } | ||
| } | ||
|
|
||
| /// Remove all transaction metadata (for testing or cleanup) | ||
| func removeAll() throws { | ||
| let allMetadata = try getAll() | ||
|
|
||
| if allMetadata.isEmpty { | ||
| return | ||
| } | ||
|
|
||
| defaults.removeObject(forKey: metadataKey) | ||
| Logger.info("Removed all transaction metadata (\(allMetadata.count) entries)", context: "TransactionMetadataStorage") | ||
| metadataChangedSubject.send() | ||
| } | ||
|
|
||
| /// Remove old metadata entries that are older than the specified timestamp | ||
| func removeOld(olderThan timestamp: UInt64) throws { | ||
| var allMetadata = try getAll() | ||
| let originalCount = allMetadata.count | ||
|
|
||
| allMetadata.removeAll { $0.createdAt < timestamp } | ||
|
|
||
| if allMetadata.count != originalCount { | ||
| try save(allMetadata) | ||
| Logger.info("Removed \(originalCount - allMetadata.count) old transaction metadata entries", context: "TransactionMetadataStorage") | ||
| metadataChangedSubject.send() | ||
| } | ||
| } | ||
|
|
||
| // MARK: - Private Helpers | ||
|
|
||
| private func save(_ metadata: [TransactionMetadata]) throws { | ||
| let encoder = JSONEncoder() | ||
| let data = try encoder.encode(metadata) | ||
| defaults.set(data, forKey: metadataKey) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.