Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Bitkit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,7 @@
repositoryURL = "https://github.com/pubky/paykit-rs";
requirement = {
kind = exactVersion;
version = "0.1.0-rc39";
version = "0.1.0-rc41";
};
};
18D65DFE2EB9649F00252335 /* XCRemoteSwiftPackageReference "vss-rust-client-ffi" */ = {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Bitkit/Constants/Env.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ enum Env {
(infoPlistValue("E2E_BACKEND") ?? "local").lowercased()
}

private static var isLocalE2EBackend: Bool {
static var isLocalE2EBackend: Bool {
isE2E && e2eBackend == "local"
}

Expand Down
2 changes: 2 additions & 0 deletions Bitkit/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
</array>
<key>E2E_BACKEND</key>
<string>$(E2E_BACKEND)</string>
<key>E2E_HOMEGATE_URL</key>
<string>$(E2E_HOMEGATE_URL)</string>
<key>E2E_NETWORK</key>
<string>$(E2E_NETWORK)</string>
Comment thread
ben-kaufman marked this conversation as resolved.
<key>TREZOR_BRIDGE</key>
Expand Down
12 changes: 9 additions & 3 deletions Bitkit/Models/PubkyAuthRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ enum PubkyAuthClaim: String, Equatable {
case watchOnlyAccountV1 = "watch-only-account-v1"

static let queryParameter = "x-bitkit-claim"
static let watchOnlyAccountCapabilities = "/pub/paykit/v0/bitkit/server/:rw"
static let watchOnlyAccountCapabilities = "/pub/paykit/v0/bitkit/server/:rw,/pub/paykit/v0/private/bitkit/server/:rw"
private static let watchOnlyAccountCapabilitySet = Set(watchOnlyAccountCapabilities.split(separator: ",").map(String.init))

static func matchesWatchOnlyAccountCapabilities(_ capabilities: String) -> Bool {
let requestedCapabilitySet = Set(capabilities.split(separator: ",").map(String.init))
return requestedCapabilitySet == watchOnlyAccountCapabilitySet
}
}

enum PubkyAuthRequestError: Error, Equatable {
Expand Down Expand Up @@ -79,15 +85,15 @@ struct PubkyAuthRequest {
throw PubkyAuthRequestError.duplicateBitkitClaim
}
guard let claimValue = claimValues.first else {
if capabilities == PubkyAuthClaim.watchOnlyAccountCapabilities {
if PubkyAuthClaim.matchesWatchOnlyAccountCapabilities(capabilities) {
throw PubkyAuthRequestError.missingBitkitClaim
}
return nil
}
guard let claim = PubkyAuthClaim(rawValue: claimValue) else {
throw PubkyAuthRequestError.unsupportedBitkitClaim(claimValue)
}
guard capabilities == PubkyAuthClaim.watchOnlyAccountCapabilities else {
guard PubkyAuthClaim.matchesWatchOnlyAccountCapabilities(capabilities) else {
throw PubkyAuthRequestError.invalidBitkitClaimCapabilities
}

Expand Down
15 changes: 12 additions & 3 deletions Bitkit/Services/PubkyService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -789,11 +789,12 @@ actor PaykitSdkService {
return sdk
}

let created = try PaykitSdk.withPaymentAdapter(
let created = try PaykitSdk.withPaymentAdapterAndPubkyClientConfig(
stateStore: stateStore,
sessionProvider: sessionProvider,
paymentAdapter: paymentAdapter,
config: Self.config()
config: Self.config(),
pubkyClient: Self.pubkyClientConfig()
)
sdk = created
return created
Expand Down Expand Up @@ -925,7 +926,15 @@ actor PaykitSdkService {
}

private func bootstrap() throws -> PubkySessionBootstrap {
try PubkySessionBootstrap()
try PubkySessionBootstrap.withPubkyClientConfig(pubkyClient: Self.pubkyClientConfig())
}

nonisolated static func pubkyClientConfig(isLocalE2EBackend: Bool = Env.isLocalE2EBackend) -> PubkyClientConfig {
var config = Paykit.defaultPubkyClientConfig()
if isLocalE2EBackend {
config.environment = .localTestnet
}
return config
}

private nonisolated static func config() throws -> PaykitSdkConfig {
Expand Down
19 changes: 19 additions & 0 deletions BitkitTests/PaykitSdkClientConfigTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@testable import Bitkit
import Paykit
import XCTest

final class PaykitSdkClientConfigTests: XCTestCase {
func testProductionUsesDefaultPubkyClient() {
let config = PaykitSdkService.pubkyClientConfig(isLocalE2EBackend: false)

XCTAssertEqual(config.environment, .production)
XCTAssertNil(config.testnetHost)
}

func testLocalE2EUsesLocalPubkyTestnet() {
let config = PaykitSdkService.pubkyClientConfig(isLocalE2EBackend: true)

XCTAssertEqual(config.environment, .localTestnet)
XCTAssertNil(config.testnetHost)
}
}
21 changes: 21 additions & 0 deletions BitkitTests/PubkyAuthRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ final class PubkyAuthRequestTests: XCTestCase {
XCTAssertEqual(request.bitkitClaim, .watchOnlyAccountV1)
}

func testParseUrlRecognizesWatchOnlyAccountClaimWithReorderedCapabilities() throws {
let capabilities = PubkyAuthClaim.watchOnlyAccountCapabilities
.split(separator: ",")
.reversed()
.joined(separator: ",")
let url = authUrl(capabilities: capabilities, claimValues: [PubkyAuthClaim.watchOnlyAccountV1.rawValue])

let request = try PubkyAuthRequest.parse(url: url)

XCTAssertEqual(request.bitkitClaim, .watchOnlyAccountV1)
}

func testParseUrlWithoutBitkitClaimPreservesNormalAuth() throws {
let request = try PubkyAuthRequest.parse(url: authUrl(capabilities: "/pub/bitkit.to/:rw"))

Expand Down Expand Up @@ -74,6 +86,15 @@ final class PubkyAuthRequestTests: XCTestCase {
}
}

func testParseUrlRejectsWatchOnlyClaimWithoutPrivateCapability() {
let capabilities = "/pub/paykit/v0/bitkit/server/:rw"
let url = authUrl(capabilities: capabilities, claimValues: [PubkyAuthClaim.watchOnlyAccountV1.rawValue])

XCTAssertThrowsError(try PubkyAuthRequest.parse(url: url)) {
XCTAssertEqual($0 as? PubkyAuthRequestError, .invalidBitkitClaimCapabilities)
}
}

// MARK: - parseCapabilities

func testParseCapabilitiesSingleEntry() {
Expand Down
1 change: 1 addition & 0 deletions changelog.d/next/653.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed Paykit Server authorization to require both public and private payment capabilities.
Loading