-
Notifications
You must be signed in to change notification settings - Fork 50
feat(swift-sdk): add ZK sync, local Docker support, and account management (part 1) #3393
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
Changes from all commits
09c8aef
d2fdce3
5ebd4bc
93205ff
55008db
3212d87
822cc24
2cfe1e8
ac65440
033c509
f1ef279
0bd1341
c8d9d86
a6671ff
13c6e19
c38b5a0
87320a2
53adb35
b367564
e032548
870a0cd
ab5a56a
2c27c01
7fa5afe
f2d9088
7487f45
808c5f1
3d47fac
b224aff
5b1c28f
c3c9c7b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,6 +44,9 @@ class SPVClient: @unchecked Sendable { | |
| return dash_spv_ffi_config_mainnet() | ||
| case 1: | ||
| return dash_spv_ffi_config_testnet() | ||
| case 2: | ||
| // Regtest (local Docker) | ||
| return dash_spv_ffi_config_new(FFINetwork(rawValue: 2)) | ||
| case 3: | ||
|
Comment on lines
44
to
50
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Suggestion: Borrowed wallet-manager FFI handle can outlive the owning SPV client The wallet-manager handle obtained from the FFI is a borrowed pointer whose lifetime is tied to the SPV client. If the SPV client is deallocated while the wallet manager is still in use (e.g., during async transaction operations), the handle becomes a dangling pointer. Consider either copying the handle or ensuring the SPV client's lifetime encompasses all wallet manager usage. source: ['codex'] 🤖 Fix this with AI agents
Comment on lines
44
to
50
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Suggestion: Core→Platform top-up accepts first InstantSend lock without SPV validation The top-up flow accepts the first InstantSend lock notification for a transaction without verifying that SPV has actually validated it against the chain. An attacker on the local network could inject a fake IS notification. The code should verify the transaction's confirmation status via SPV before crediting the platform account. source: ['codex'] 🤖 Fix this with AI agents |
||
| // Map devnet to custom FFINetwork value 3 | ||
| return dash_spv_ffi_config_new(FFINetwork(rawValue: 3)) | ||
|
|
@@ -58,13 +61,16 @@ class SPVClient: @unchecked Sendable { | |
|
|
||
| // If requested, prefer local core peers (defaults to 127.0.0.1 with network default port) | ||
| let useLocalCore = UserDefaults.standard.bool(forKey: "useLocalhostCore") | ||
| || UserDefaults.standard.bool(forKey: "useDockerSetup") | ||
| // Only restrict to configured peers when using local core, if not, allow DNS discovery | ||
| let restrictToConfiguredPeers = useLocalCore | ||
| if useLocalCore { | ||
| let peers = SPVClient.readLocalCorePeers() | ||
| if swiftLoggingEnabled { | ||
| print("[SPV][Config] Use Local Core enabled; peers=\(peers.joined(separator: ", "))") | ||
| } | ||
| // Clear default peers before adding custom Docker peers | ||
| dash_spv_ffi_config_clear_peers(configPtr) | ||
| // Add peers via FFI (supports "ip:port" or bare IP for network-default port) | ||
| for addr in peers { | ||
| addr.withCString { cstr in | ||
|
|
@@ -135,9 +141,9 @@ class SPVClient: @unchecked Sendable { | |
| } | ||
|
|
||
| private static func readLocalCorePeers() -> [String] { | ||
| // If no override is set, default to 127.0.0.1 and let FFI pick port by network | ||
| // If no override is set, default to dashmate Docker Core P2P port | ||
| let raw = UserDefaults.standard.string(forKey: "corePeerAddresses")?.trimmingCharacters(in: .whitespacesAndNewlines) | ||
| let list = (raw?.isEmpty == false ? raw! : "127.0.0.1") | ||
| let list = (raw?.isEmpty == false ? raw! : "127.0.0.1:20001") | ||
| return list | ||
| .split(separator: ",") | ||
| .map { $0.trimmingCharacters(in: .whitespaces) } | ||
|
|
@@ -190,6 +196,25 @@ class SPVClient: @unchecked Sendable { | |
| config = nil | ||
| } | ||
|
|
||
| // MARK: - Broadcast Transactions | ||
|
|
||
| func broadcastTransaction(_ transactionData: Data) throws { | ||
| try transactionData.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) in | ||
| guard let txBytes = ptr.bindMemory(to: UInt8.self).baseAddress else { | ||
| throw SPVError.transactionBroadcastFailed("Invalid transaction data pointer") | ||
| } | ||
| let result = dash_spv_ffi_client_broadcast_transaction( | ||
| client, | ||
| txBytes, | ||
| UInt(transactionData.count) | ||
| ) | ||
|
|
||
| if result != 0 { | ||
| throw SPVError.transactionBroadcastFailed(SPVClient.getLastDashFFIError()) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // MARK: - Synchronization | ||
|
|
||
| func startSync() async throws { | ||
|
|
@@ -235,6 +260,7 @@ public enum SPVError: LocalizedError { | |
| case alreadySyncing | ||
| case syncFailed(String) | ||
| case storageOperationFailed(String) | ||
| case transactionBroadcastFailed(String) | ||
|
|
||
| public var errorDescription: String? { | ||
| switch self { | ||
|
|
@@ -254,6 +280,8 @@ public enum SPVError: LocalizedError { | |
| return "Sync failed: \(reason)" | ||
| case let .storageOperationFailed(reason): | ||
| return reason | ||
| case let .transactionBroadcastFailed(reason): | ||
| return "Transaction broadcast failed: \(reason)" | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.