Skip to content
Merged
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
32 changes: 0 additions & 32 deletions Package.resolved

This file was deleted.

7 changes: 3 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ let package = Package(
.library(name: "IDKit", targets: ["IDKit"]),
],
dependencies: [
.package(url: "https://api.github.com/repos/worldcoin/idkit-swift/releases/assets/314157476.zip", from: "5.3.0"),
.package(url: "https://api.github.com/repos/worldcoin/idkit-swift/releases/assets/314157476.zip", from: "1.9.0"),
.package(url: "https://api.github.com/repos/worldcoin/idkit-swift/releases/assets/314157476.zip", "1.0.0"..<"4.0.0"),
.package(url: "https://github.com/attaswift/BigInt.git", from: "5.3.0"),
.package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", from: "1.9.0"),
.package(url: "https://github.com/apple/swift-crypto.git", "1.0.0"..<"4.0.0"),
],
targets: [
.target(
Expand All @@ -30,4 +30,3 @@ let package = Package(
)
]
)
// Release version: 3.0.2
140 changes: 51 additions & 89 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,117 +4,79 @@

# IDKit (Swift)

[![Swift Version](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fm1guelpf%2Fziggy-vapor%2Fbadge%3Ftype%3Dswift-versions&color=brightgreen)](http://swift.org)
[![docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://swiftpackageindex.com/worldcoin/idkit-swift)
This repository is the Swift Package Manager (SPM) mirror for the [IDKit](https://github.com/worldcoin/idkit) Rust SDK. The Swift sources are generated via [UniFFI](https://mozilla.github.io/uniffi-rs/), giving Swift clients the exact same surface area as the Rust core without any bespoke glue code.

The `IDKit` library provides a simple Swift interface for prompting users for World ID proofs. For other platforms, check out the following:
- [Kotlin](https://github.com/worldcoin/idkit-kotlin)
- [React and React Native](https://github.com/worldcoin/idkit-js)
## Package Layout

## Usage
There are three main ways to use `idkit-swift`:

1. To request proof of a minimum verification level. For example, if you ask for proof with a minimum level `document` proof, you may get a `document`, `secure_document` or `orb` proof, depending on the highest verification level that the user has.
```
Sources/
IDKit/
IDKit.swift // Version metadata
Generated/ // UniFFI-generated Swift + C headers
IDKitFFI.xcframework // (added during release automation)
```

For more on the concept of verification levels, see [this page](https://docs.world.org/world-id/concepts).
2. To request proof of verification with specific credential categories. For example, if you ask for a `secure_document` proof, you will only receive a proof if the user verified using a `secure_document` category of credential.
The `Generated/` directory is copied directly from the build artifacts produced in the main `idkit` repository. Release automation then builds the universal Rust library and publishes an `IDKitFFI.xcframework`, which this package references.

3. To request proof that the user is 18+ years of age. The World App only allows `document` or `secure_document` verifications if the user is 18+. Therefore, you can request proof of verification using one or both of these two categories as a proxy of proof that user is 18+ years of age.
## Installation

All of these require the creation of a `Session` with our hosted [Wallet Bridge service](https://github.com/worldcoin/wallet-bridge), then polling for an update from the World App instance that the user is using to respond to the request. Wallet Bridge acts as a secure relay between your app and World App.
Add the package to your project using SwiftPM:

> [!CAUTION]
> A `Session` instance is valid only for a single proof request, and should not be re-used or cached. It's reasonably inexpensive to create, though does make a network call during initialization. By design, re-using `Sessions` will lead to errors that are user-facing in both World App and your app.
```swift
.package(url: "https://github.com/worldcoin/idkit-swift", from: "3.0.0")
```

### Proof of Minimum Verification Level
Use the verification level API when you're interested in getting the strongest human assurance level of a user.
## Quick Start

```swift
import IDKit

// 1. Initialize your App ID configured in World Developer Portal.
let appID: AppID
do {
appID = try AppID("your_app_id")
} catch {
// Handle error
return
}

// 2. Create a session with Wallet Bridge. This requests that the user proves they're a human with an orb level verification.
let session = try await Session(appID, action: "your_action", verificationLevel: .orb)

// 3. Create a universal link compatible with World App.
let verificationURL = session.verificationURL

// 4. Launch World App with the verification level request.
UIApplication.shared.open(verificationURL)

// 5. Poll for the result of the request.
for try await status in session.status() {
switch status {
case .waitingForConnection:
print("Waiting for the user to scan the QR Code")
case .awaitingConfirmation:
print("Awaiting user confirmation")
case let .confirmed(proof):
print("Got proof: \(proof)")
case let .failed(error):
print("Got error: \(error)")
}
}
```
let signal = Signal.fromString(s: "user_action_12345")
let request = Request(credentialType: .orb, signal: signal)

### Proof of Specific Credential Categories
Use this API when you're interested in knowing if a user possesses a credential from one of the specific categories you specify. There are 3 supported categories:
let session = try Session.create(
appId: "app_staging_1234567890abcdef",
action: "vote",
requests: [request]
)

1. `document` - for credentials derived from NFC-enabled documents that can be cloned.
2. `secure_document` - for credentials derived from NFC-enabled documents that can't be cloned.
3. `personhood` - for credentials derived from the Orb.
print("Scan this QR code in World App: \(session.connectUrl())")

```swift
import IDKit
let proof = try session.waitForProofWithTimeout(timeoutSeconds: 900)
print("Verified! Nullifier: \(proof.nullifierHash)")
```

// 1. Initialize your AppID
let appID: AppID
do {
appID = try AppID("your_app_id")
} catch {
// Handle error
return
}
For manual status polling:

// 2. Create a session with Wallet Bridge. This session requests both a secure document and personhood proof.
let session = try await Session(appID, action: "your_action", credentialCategories: [.secure_document, .personhood])

// 3. Create a universal link that opens either World App Clip or World App. This approach significantly speeds up getting proofs from users who don't have a verified World ID.
let deferredOnboardingURL = try session.deferredOnboardingURL

// 4. Launch World App, or World App Clip, with the credential presentation request.
UIApplication.shared.open(deferredOnboardingURL)

// 5. Poll for the result of the request.
for try await status in session.status() {
switch status {
case .waitingForConnection:
print("Waiting for the user to scan the QR Code")
case .awaitingConfirmation:
print("Awaiting user confirmation")
case let .confirmed(proof):
print("Got proof: \(proof)")
case let .failed(error):
print("Got error: \(error)")
}
```swift
while true {
let status = try session.poll()
switch status {
case .waitingForConnection:
print("Waiting for the user to scan…")
case .awaitingConfirmation:
print("User is confirming…")
case .confirmed(let proof):
print("Proof ready: \(proof)")
break
case .failed(let error):
fatalError("Verification failed: \(error)")
}

Thread.sleep(forTimeInterval: 3)
}
```

Note: If `personhood` is requested along with `document` or `secure_document`, a proof of `personhood` will only be returned if the user also has `document` or `secure_document` credentials. Else, the user will be prompted to verify themselves using a `document` or `secure_document` credential first.
## Releasing New Builds

### Proof of Age of 18+ Years
Releases are automated from the main [`idkit`](https://github.com/worldcoin/idkit) repo. Merging a PR into `main` with the `release` label triggers the "Publish Swift Release" workflow, which:

The World App only accepts `document` or `secure_document` verifications if the user is 18+ as determined from the user's date of birth stored on the NFC chip of the document. Therefore, you can request proof of verification using these two categories as proof that user is 18+ years of age.
1. Builds the universal Rust library and regenerates the Swift bindings.
2. Produces `IDKitFFI.xcframework` and uploads it as a draft release asset here.
3. Syncs `Sources/IDKit`, updates `Package.swift` with the new asset URL and checksum, and tags the release.
4. Publishes the release so Swift Package Manager clients can pull the new binary target.

To do this, use credential categories API with the categories set to `[.document, .secure_document]`.
For local testing you can run `scripts/package-swift.sh` in the main repo and follow the same steps manually.

<!-- WORLD-ID-SHARED-README-TAG:START - Do not remove or modify this section directly -->
<!-- The contents of this file are inserted to all World ID repositories to provide general context on World ID. -->
Expand Down
Loading
Loading