LedgeKitDocs
Advanced
Developer documentation

Provide a custom trace transport

Inject delivery for tests or another durable destination.

The built-in HTTP transport is automatic. To use another destination, implement LedgeTransport.upload(_:) and inject it when creating the client.

import Foundation
import LedgeKit

actor MemoryTransport: LedgeTransport {
    private(set) var payloads: [Data] = []
    func upload(_ upload: LedgeUpload) async throws {
        payloads.append(try Data(contentsOf: upload.payloadURL))
    }
}

func makeTestClient(directory: URL, transport: MemoryTransport) throws -> LedgeClient {
    try LedgeClient(serviceName: "test-app", transport: transport, localDirectory: directory)
}

LedgeUpload exposes id: UUID and payloadURL: URL. The file contains the complete encoded envelope. Read its bytes before returning: successful upload permits the outbox to delete it. Serialization and wire-model types are internal to the SDK.

In-memory acceptance is useful in a test. A production transport must return only after its destination durably accepts the payload. Preserve the upload ID when forwarding to an idempotent receiver.

Implement LedgeTransportFailure.isRetryable on errors that distinguish permanent rejection from temporary failure. Unclassified errors remain retryable. The built-in transport sends a bearer write key, content type, and trace ID idempotency header; schemaVersion lives only in the JSON body.