From c7d1805bbe6a6ad67319d87afcbd37e4eb058701 Mon Sep 17 00:00:00 2001 From: Nic-dorman Date: Tue, 5 May 2026 10:28:34 +0100 Subject: [PATCH] feat(antd-swift): expose new HealthStatus diagnostic fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors antd-go v0.5.0 / antd-py: HealthStatus now carries version, evmNetwork, uptimeSeconds, buildCommit, paymentTokenAddress, and paymentVaultAddress. The init has positional default values (empty strings / 0) so the 2-arg call HealthStatus(ok:, network:) still compiles for older callers and pre-0.4.0 daemon responses parse cleanly. REST routes through HealthResponseDTO.toHealthStatus() — the DTO gains six matching optional snake_case fields so JSONDecoder tolerates either old or new daemons. The gRPC client is currently a stub (throws notImplemented for everything) so health() there is unchanged. Note: swift toolchain isn't available on the orchestrator's Windows host, so `swift test` was not run locally. The diff is mechanical and follows the pattern from the antd-go and antd-py reference implementations. Part of #37. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Sources/AntdSdk/AntdRestClient.swift | 21 +++++++++++++- antd-swift/Sources/AntdSdk/Models.swift | 28 ++++++++++++++++++- .../Tests/AntdSdkTests/SmokeTests.swift | 20 +++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/antd-swift/Sources/AntdSdk/AntdRestClient.swift b/antd-swift/Sources/AntdSdk/AntdRestClient.swift index 43115bf..ed24372 100644 --- a/antd-swift/Sources/AntdSdk/AntdRestClient.swift +++ b/antd-swift/Sources/AntdSdk/AntdRestClient.swift @@ -67,7 +67,7 @@ public final class AntdRestClient: AntdClientProtocol, @unchecked Sendable { public func health() async throws -> HealthStatus { do { let resp: HealthResponseDTO = try await getJSON("/health") - return HealthStatus(ok: resp.status == "ok", network: resp.network ?? "unknown") + return resp.toHealthStatus() } catch { return HealthStatus(ok: false, network: "unknown") } @@ -251,6 +251,25 @@ public final class AntdRestClient: AntdClientProtocol, @unchecked Sendable { private struct HealthResponseDTO: Decodable { let status: String? let network: String? + let version: String? + let evm_network: String? + let uptime_seconds: UInt64? + let build_commit: String? + let payment_token_address: String? + let payment_vault_address: String? + + func toHealthStatus() -> HealthStatus { + HealthStatus( + ok: status == "ok", + network: network ?? "unknown", + version: version ?? "", + evmNetwork: evm_network ?? "", + uptimeSeconds: uptime_seconds ?? 0, + buildCommit: build_commit ?? "", + paymentTokenAddress: payment_token_address ?? "", + paymentVaultAddress: payment_vault_address ?? "" + ) + } } private struct CostAddressDTO: Decodable { diff --git a/antd-swift/Sources/AntdSdk/Models.swift b/antd-swift/Sources/AntdSdk/Models.swift index 5aa8026..7f24db6 100644 --- a/antd-swift/Sources/AntdSdk/Models.swift +++ b/antd-swift/Sources/AntdSdk/Models.swift @@ -1,13 +1,39 @@ import Foundation /// Health check result from the antd daemon. +/// +/// The diagnostic fields (`version`, `evmNetwork`, `uptimeSeconds`, +/// `buildCommit`, `paymentTokenAddress`, `paymentVaultAddress`) were added in +/// antd 0.4.0. They default to `""` / `0` so the struct stays usable when +/// talking to a pre-0.4.0 daemon that doesn't report them. public struct HealthStatus: Sendable, Equatable { public let ok: Bool public let network: String + public let version: String + public let evmNetwork: String + public let uptimeSeconds: UInt64 + public let buildCommit: String + public let paymentTokenAddress: String + public let paymentVaultAddress: String - public init(ok: Bool, network: String) { + public init( + ok: Bool, + network: String, + version: String = "", + evmNetwork: String = "", + uptimeSeconds: UInt64 = 0, + buildCommit: String = "", + paymentTokenAddress: String = "", + paymentVaultAddress: String = "" + ) { self.ok = ok self.network = network + self.version = version + self.evmNetwork = evmNetwork + self.uptimeSeconds = uptimeSeconds + self.buildCommit = buildCommit + self.paymentTokenAddress = paymentTokenAddress + self.paymentVaultAddress = paymentVaultAddress } } diff --git a/antd-swift/Tests/AntdSdkTests/SmokeTests.swift b/antd-swift/Tests/AntdSdkTests/SmokeTests.swift index f25dce6..ee3a41e 100644 --- a/antd-swift/Tests/AntdSdkTests/SmokeTests.swift +++ b/antd-swift/Tests/AntdSdkTests/SmokeTests.swift @@ -25,6 +25,26 @@ final class SmokeTests: XCTestCase { let health = HealthStatus(ok: true, network: "local") XCTAssertTrue(health.ok) XCTAssertEqual(health.network, "local") + // Diagnostic fields default to empty / 0 for the 2-arg init, + // so callers + pre-0.4.0 daemon responses both still work. + XCTAssertEqual(health.version, "") + XCTAssertEqual(health.evmNetwork, "") + XCTAssertEqual(health.uptimeSeconds, 0) + XCTAssertEqual(health.buildCommit, "") + + let fullHealth = HealthStatus( + ok: true, + network: "default", + version: "0.4.0", + evmNetwork: "arbitrum-one", + uptimeSeconds: 42, + buildCommit: "abcdef123456", + paymentTokenAddress: "0xtoken", + paymentVaultAddress: "0xvault" + ) + XCTAssertEqual(fullHealth.version, "0.4.0") + XCTAssertEqual(fullHealth.evmNetwork, "arbitrum-one") + XCTAssertEqual(fullHealth.uptimeSeconds, 42) let put = PutResult(cost: "100", address: "abc123") XCTAssertEqual(put.cost, "100")