SPB Git

spb/os-vault Public

Self-custody, multi-chain crypto wallet for macOS. One recovery phrase, six chain families, zero API keys — nothing leaves your Mac.

Swift 96% Shell 3.4% Makefile 0.6%
2.3 KB · 73 lines swift
Raw Blame History
1import Foundation2import Task_retrying34class TransactionMonitor<SolanaAPIClient: SolanaSwift.SolanaAPIClient> {5    let signature: String6    let apiClient: SolanaAPIClient7    let timeout: Int8    let delay: Int9    var responseHandler: (PendingTransactionStatus) -> Void10    var timedOutHandler: () -> Void11    var task: Task<Void, Error>!12    var currentStatus: PendingTransactionStatus!1314    init(15        apiClient: SolanaAPIClient,16        signature: String,17        timeout: Int,18        delay: Int,19        responseHandler: @escaping (PendingTransactionStatus) -> Void,20        timedOutHandler: @escaping () -> Void21    ) {22        self.apiClient = apiClient23        self.signature = signature24        self.timeout = timeout25        self.delay = delay26        self.responseHandler = responseHandler27        self.timedOutHandler = timedOutHandler28    }2930    func startMonitoring() {31        setStatus(.sending)3233        task = Task.retrying(34            where: { [weak self] error in35                guard let self = self else { return false }36                if let error = error as? TaskRetryingError,37                   error.type == .timedOut38                {39                    self.timedOutHandler()40                    return false41                }42                return true43            },44            maxRetryCount: .max,45            retryDelay: TimeInterval(delay),46            timeoutInSeconds: timeout47        ) { [weak self] in48            guard let self = self else { return }49            try Task.checkCancellation()50            let status = try await self.apiClient.getSignatureStatus(signature: self.signature, configs: nil)5152            if let confirmations = status.confirmations, status.confirmationStatus == "confirmed" {53                self.setStatus(.confirmed(numberOfConfirmations: confirmations, slot: status.slot))54            }55            let finalized = status.confirmations == nil || status.confirmationStatus == "finalized"56            if finalized {57                self.setStatus(.finalized)58                return59            }60            throw TransactionConfirmationError.unconfirmed61        }62    }6364    func stopMonitoring() {65        task.cancel()66    }6768    func setStatus(_ transactionStatus: PendingTransactionStatus) {69        currentStatus = transactionStatus70        responseHandler(transactionStatus)71    }72}73