{"id":18519171,"url":"https://github.com/blockchaincommons/bcswifttor","last_synced_at":"2025-07-24T20:35:20.988Z","repository":{"id":44875575,"uuid":"445123489","full_name":"BlockchainCommons/BCSwiftTor","owner":"BlockchainCommons","description":"Opinionated pure Swift controller for Tor, including full support for Swift 5.5 and Swift Concurrency.","archived":false,"fork":false,"pushed_at":"2022-05-19T06:45:22.000Z","size":34844,"stargazers_count":8,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T04:04:05.411Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BlockchainCommons.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-01-06T10:07:03.000Z","updated_at":"2024-11-18T13:14:12.000Z","dependencies_parsed_at":"2022-09-06T01:11:15.214Z","dependency_job_id":null,"html_url":"https://github.com/BlockchainCommons/BCSwiftTor","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlockchainCommons%2FBCSwiftTor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlockchainCommons%2FBCSwiftTor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlockchainCommons%2FBCSwiftTor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlockchainCommons%2FBCSwiftTor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BlockchainCommons","download_url":"https://codeload.github.com/BlockchainCommons/BCSwiftTor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248003258,"owners_count":21031757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T17:15:34.712Z","updated_at":"2025-04-09T08:32:03.003Z","avatar_url":"https://github.com/BlockchainCommons.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BCSwiftTor\n\nOpinionated pure Swift controller for [Tor](https://github.com/torproject/tor), including full support for Swift 5.5 and Swift Concurrency.\n\nInspired by [Tor.framework](https://github.com/iCepa/Tor.framework) but designed to be used seamlessly with [Blockchain Commons]() projects and technologies.\n\n# Dependencies\n\nDepends on [BCSwiftTorBase](https://github.com/BlockchainCommons/BCSwiftTorBase), which is a thin wrapper around Tor that has a new build system for building a universal XCFramework for use with MacOSX, Mac Catalyst, iOS devices, and the iOS simulator across Intel and Apple Silicon (ARM).\n\n# Building\n\nAdd to your project like any other Swift Package.\n\n# Usage\n\n```swift\nimport XCTest\nimport Tor\n\nclass ReadMeTests: XCTestCase {\n    var controller: TorController!\n\n    // Configure the controller. Socket files have length limitations, so find a file system path\n    // that's short enough to accomodate the socket file we use to communicate with the Tor thread.\n    static let configuration: TorConfiguration = {\n        var homeDirectory: URL!\n        #if targetEnvironment(simulator)\n        for variable in [\"IPHONE_SIMULATOR_HOST_HOME\", \"SIMULATOR_HOST_HOME\"] {\n            if let p = getenv(variable) {\n                homeDirectory = URL(fileURLWithPath: String(cString: p))\n                break\n            }\n        }\n        #else\n        homeDirectory = URL(fileURLWithPath: NSHomeDirectory())\n        #endif\n        precondition(homeDirectory != nil)\n\n        let fileManager = FileManager.default\n\n        let dataDirectory = fileManager.temporaryDirectory\n        let socketDirectory = homeDirectory.appendingPathComponent(\".tor\")\n        try! fileManager.createDirectory(at: socketDirectory, withIntermediateDirectories: true)\n        let socketFile = socketDirectory.appendingPathComponent(\"control_port\")\n\n        return TorConfiguration(\n            dataDirectory: dataDirectory,\n            controlSocket: socketFile,\n            options: [.ignoreMissingTorrc, .cookieAuthentication]\n        )\n    }()\n\n    // Run once for every all tests in this suite. Start the Tor thread with logging back to the app.\n    static override func setUp() {\n        super.setUp()\n\n        let runner = TorRunner(configuration: Self.configuration)\n        runner.setLogging(minLogSeverity: .notice) { severity, domain, msg in\n            print(\"🔵 [\\(severity)]: \\(domain): \\(msg)\")\n        }\n        runner.run()\n    }\n\n    // Run once for each test this suite. Create a new Tor controller object.\n    override func setUp() async throws {\n        try await super.setUp()\n\n        controller = try await TorController(socket: Self.configuration.controlSocket)\n    }\n\n    // Authenticate to the Tor process using the cookie that it writes to the file system.\n    func authenticate() async throws {\n        guard let cookie = Self.configuration.cookie else {\n            XCTFail(\"No cookie file found.\")\n            return\n        }\n        try await controller.authenticate(with: cookie)\n    }\n\n    func testRetrieveURL() async throws {\n        // Authenticate and then wait until a circuit is established\n        try await authenticate()\n        try await controller.untilCircuitEstablished()\n\n        // Create a URL session that communicates using the socket that's been set up.\n        let sessionConfiguration = try await controller.getSessionConfiguration()\n        let session = URLSession(configuration: sessionConfiguration)\n\n        // Use the URLSession to retrieve data from an Onion address URL via Tor.\n\n        // Blockchain Commons SpotBit instance.\n        // https://github.com/blockchaincommons/spotbit#test-server\n        let url = URL(string: \"http://h6zwwkcivy2hjys6xpinlnz2f74dsmvltzsd4xb42vinhlcaoe7fdeqd.onion/status\")!\n        let (data, resp) = try await session.data(from: url)\n        let response = resp as! HTTPURLResponse\n        XCTAssertEqual(response.statusCode, 200)\n        XCTAssertEqual(data.utf8, \"server is running\")\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockchaincommons%2Fbcswifttor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblockchaincommons%2Fbcswifttor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblockchaincommons%2Fbcswifttor/lists"}