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
3 changes: 2 additions & 1 deletion scripts/build-swift.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ echo ""
echo "🔧 Step 2/3: Generating Swift bindings..."
mkdir -p "$GENERATED_DIR"

uniffi-bindgen generate \
cargo run -p uniffi-bindgen generate \
--library target/release/libidkit.dylib \
--language swift \
--no-format \
--out-dir "$GENERATED_DIR"

echo "✅ Generated Swift bindings to: $GENERATED_DIR"
Expand Down
14 changes: 12 additions & 2 deletions swift/Examples/IDKitSampleApp/IDKitSampleApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum SampleLegacyPreset: String, CaseIterable, Identifiable {
case document
case device
case selfieCheck = "selfie check"
case identityCheckWithProofOfHumanity = "identity check with proof of humanity"

var id: String { rawValue }

Expand All @@ -36,6 +37,15 @@ enum SampleLegacyPreset: String, CaseIterable, Identifiable {
deviceLegacy(signal: signal)
case .selfieCheck:
selfieCheckLegacy(signal: signal)
case .identityCheckWithProofOfHumanity:
identityCheck(
attributes: [
.minimumAge(21),
.nationality("JPN"),
.documentType(.passport),
],
requireProofOfHumanity: true
)
}
}
}
Expand Down Expand Up @@ -76,7 +86,7 @@ struct ContentView: View {
}
.pickerStyle(.segmented)

Picker("Legacy preset", selection: $model.legacyPreset) {
Picker("Preset", selection: $model.legacyPreset) {
ForEach(SampleLegacyPreset.allCases) { preset in
Text(preset.rawValue).tag(preset)
}
Expand Down Expand Up @@ -201,7 +211,7 @@ final class SampleModel: ObservableObject {
deepLinkReceivedForPendingRequest = false

print("IDKit connector URL: \(request.connectorURL.absoluteString)")
log("Using legacy preset: \(legacyPreset.rawValue)")
log("Using preset: \(legacyPreset.rawValue)")
log("Generated request ID: \(request.requestID.uuidString)")
log("Configured return_to callback: \(returnToURL)")
startPollingForRequest(request: request, reason: "request generation")
Expand Down
17 changes: 17 additions & 0 deletions swift/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ let request = try IDKit
.preset(selfieCheckLegacy(signal: "user-123"))
```

For document-based identity attestation, use:

```swift
let request = try IDKit
.request(config: config)
.preset(
identityCheck(
attributes: [
.minimumAge(21),
.nationality("JPN"),
.documentType(.passport),
],
requireProofOfHumanity: true
)
)
```

## Canonical Swift API

- Entry points:
Expand Down
13 changes: 13 additions & 0 deletions swift/Sources/IDKit/IDKit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,19 @@ public func selfieCheckLegacy(signal: String? = nil) -> Preset {
.selfieCheckLegacy(signal: signal)
}

/// Returns the identity check preset.
///
/// This preset requires World ID 4.0-compatible clients.
public func identityCheck(
attributes: [IdentityAttribute],
requireProofOfHumanity: Bool = false
) -> Preset {
.identityCheck(
attributes: attributes,
requireProofOfHumanity: requireProofOfHumanity
)
}

// TODO: Re-enable when World ID 4.0 is live
// private struct CredentialRequestJSON: Encodable {
// let type: String
Expand Down
21 changes: 21 additions & 0 deletions swift/Tests/IDKitTests/IDKitTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ func legacyPresetHelpers() {
let doc = documentLegacy(signal: "z")
let device = deviceLegacy(signal: "d")
let face = selfieCheckLegacy(signal: "f")
let identity = identityCheck(
attributes: [
.minimumAge(21),
.nationality("JPN"),
.documentType(.passport)
],
requireProofOfHumanity: true
)

switch orb {
case .orbLegacy(let signal):
Expand Down Expand Up @@ -276,6 +284,19 @@ func legacyPresetHelpers() {
case .orbLegacy, .secureDocumentLegacy, .documentLegacy, .deviceLegacy, .identityCheck:
Issue.record("Expected selfieCheckLegacy preset")
}

switch identity {
case let .identityCheck(attributes, requireProofOfHumanity):
let expected: [IdentityAttribute] = [
.minimumAge(21),
.nationality("JPN"),
.documentType(.passport)
]
#expect(attributes == expected)
#expect(requireProofOfHumanity)
case .orbLegacy, .secureDocumentLegacy, .documentLegacy, .deviceLegacy, .selfieCheckLegacy:
Issue.record("Expected identityCheck preset")
}
}

// TODO: Re-enable when World ID 4.0 is live
Expand Down
Loading