@candypoets/nipworker 0.96.3 → 0.96.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +206 -73
- package/crates/native-ffi/README.md +14 -151
- package/crates/native-ffi/ios/README.md +4 -50
- package/crates/native-ffi/react-native/README.md +8 -7
- package/crates/native-ffi/react-native/android/build.gradle +1 -0
- package/crates/native-ffi/react-native/android/src/main/cpp/NipworkerByteRuntime.cpp +348 -0
- package/crates/native-ffi/react-native/android/src/main/java/com/candypoets/nipworker/reactnative/NipworkerHooks.kt +292 -0
- package/crates/native-ffi/react-native/android/src/main/java/com/candypoets/nipworker/reactnative/NipworkerReactNativeModule.kt +283 -89
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/AddressPointer.java +75 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleBlock.java +102 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleBlockType.java +23 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleEntity.java +80 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleInline.java +85 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ArticleInlineType.java +24 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/BadgeAwardRecipient.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/BufferFull.java +52 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CacheInput.java +16 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CacheInputMessage.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CacheRequest.java +84 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CacheResponse.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CashuData.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ChatLimiterPipeConfig.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CodeData.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ConnectionStatus.java +68 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Contact.java +70 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ContentBlock.java +70 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ContentData.java +23 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Coordinate.java +75 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CountResponse.java +60 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/CounterPipeConfig.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/DLEQProof.java +69 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Emoji.java +62 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/EmojiData.java +68 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Eoce.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/EventPointer.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/GetPublicKey.java +43 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/HTLCWitness.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/HashtagData.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/HistoryTag.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ImageData.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ImetaTag.java +100 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind0Parsed.java +168 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind10002Parsed.java +59 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind10019Parsed.java +73 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1018Parsed.java +79 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1068Parsed.java +107 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1111Parsed.java +159 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1311Parsed.java +91 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind17375Parsed.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind17Parsed.java +81 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind1Parsed.java +109 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind20Parsed.java +107 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind22Parsed.java +111 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind30023Parsed.java +113 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind3Parsed.java +59 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind4Parsed.java +78 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind6Parsed.java +53 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind7374Parsed.java +66 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind7375Parsed.java +79 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind7376Parsed.java +100 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind7Parsed.java +81 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind8Parsed.java +78 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind9321Parsed.java +117 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Kind9735Parsed.java +119 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/KindFilterPipeConfig.java +60 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/LinkPreviewData.java +73 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ListParsed.java +123 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/LiveActivityRef.java +72 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/LiveChatParticipant.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/LiveChatThreadRef.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MainContent.java +20 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MainMessage.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MediaGroupData.java +58 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MediaItem.java +58 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Message.java +24 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MessageType.java +19 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MintInfo.java +65 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MintProofs.java +66 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/MuteFilterPipeConfig.java +84 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Nip07.java +43 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Nip46Bunker.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Nip46QR.java +61 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/NostrData.java +81 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/NostrEvent.java +95 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/NpubLimiterKey.java +15 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/NpubLimiterPipeConfig.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/P2PKWitness.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ParsePipeConfig.java +43 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ParsedData.java +39 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ParsedDataUnion.java +35 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ParsedEvent.java +108 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Pipe.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PipeConfig.java +23 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PipelineConfig.java +59 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PollOption.java +62 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PollType.java +15 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PreGenericParsed.java +213 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PreParticipant.java +73 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PreRefEvent.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/PrivateKey.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ProfilePointer.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Proof.java +90 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ProofVerificationPipeConfig.java +52 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Pubkey.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Publish.java +80 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Raw.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ReactionType.java +17 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/RelayInfo.java +63 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Request.java +134 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SaveToDbPipeConfig.java +43 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SerializeEventsPipeConfig.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SetSigner.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignEvent.java +54 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignedEvent.java +54 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignerOp.java +19 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignerRequest.java +80 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignerResponse.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SignerType.java +18 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/StringVec.java +57 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Subscribe.java +72 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SubscribeKind.java +19 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/SubscriptionConfig.java +95 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Tag.java +64 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Template.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Unsubscribe.java +55 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ValidProofs.java +59 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/VideoData.java +67 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/VideoVariant.java +102 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/Witness.java +17 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/WitnessString.java +54 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/WorkerMessage.java +74 -0
- package/crates/native-ffi/react-native/android/src/main/java/nostr/fb/ZapRequest.java +83 -0
- package/crates/native-ffi/react-native/ios/NipworkerReactNativeModule.h +18 -0
- package/crates/native-ffi/react-native/ios/NipworkerReactNativeModule.mm +263 -8
- package/dist/EngineManager.d.ts +1 -0
- package/dist/EngineManager.d.ts.map +1 -1
- package/dist/EngineManager.js +143 -137
- package/dist/NostrManager.d.ts +1 -0
- package/dist/NostrManager.d.ts.map +1 -1
- package/dist/NostrManager.js +49 -44
- package/dist/connections/index.js +87 -87
- package/dist/engine/index.js +119 -119
- package/dist/engine.d.ts.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +27 -26
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/legacy.d.ts.map +1 -1
- package/dist/lib/ArrayBufferReader.d.ts +2 -1
- package/dist/lib/ArrayBufferReader.d.ts.map +1 -1
- package/dist/lib/BaseBackend.d.ts +5 -3
- package/dist/lib/BaseBackend.d.ts.map +1 -1
- package/dist/manager.d.ts +2 -6
- package/dist/manager.d.ts.map +1 -1
- package/dist/manager.js +10 -28
- package/dist/react-native.d.ts +33 -4
- package/dist/react-native.d.ts.map +1 -1
- package/dist/react-native.js +400 -122
- package/dist/scheduleMicrotask.js +58 -50
- package/package.json +13 -11
- package/swift/Package.swift +36 -0
- package/swift/README.md +438 -0
- package/swift/Sources/NipworkerSwift/ArrayBufferReader.swift +136 -0
- package/swift/Sources/NipworkerSwift/AuthSession.swift +24 -0
- package/swift/Sources/NipworkerSwift/FFI.swift +94 -0
- package/swift/Sources/NipworkerSwift/FlatBufferHelpers.swift +273 -0
- package/swift/Sources/NipworkerSwift/Generated/message_generated.swift +6530 -0
- package/swift/Sources/NipworkerSwift/Hooks.swift +300 -0
- package/swift/Sources/NipworkerSwift/Models.swift +156 -0
- package/swift/Sources/NipworkerSwift/NostrManager.swift +594 -0
- package/swift/Sources/NipworkerSwift/PublishTracker.swift +40 -0
- package/swift/Sources/NipworkerSwift/Subscription.swift +44 -0
- package/swift/Sources/NipworkerSwift/WorkerMessageView.swift +145 -0
- package/dist/NativeBackend.d.ts +0 -53
- package/dist/NativeBackend.d.ts.map +0 -1
- package/dist/NativeBackend.js +0 -464
- package/dist/native.d.ts +0 -29
- package/dist/native.d.ts.map +0 -1
- package/dist/native.js +0 -273
package/swift/README.md
ADDED
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
# NipworkerSwift
|
|
2
|
+
|
|
3
|
+
Swift bindings for NIPWorker — a high-performance Nostr client library powered by Rust WebAssembly and FlatBuffers. This package wraps the Rust native FFI layer to provide an async-first, actor-safe Swift API for subscribing to relays, publishing events, and managing cryptographic signers.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
- **iOS 14+** / **macOS 13+**
|
|
8
|
+
- **Swift 5.9+**
|
|
9
|
+
- **Xcode 15+** (recommended)
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
### Xcode — Local Package (recommended while iterating)
|
|
14
|
+
|
|
15
|
+
1. Open your iOS/macOS project in Xcode.
|
|
16
|
+
2. Go to **File → Add Package Dependencies…**
|
|
17
|
+
3. Click **Add Local…** and select the `swift/` folder inside this repository.
|
|
18
|
+
4. Add `NipworkerSwift` to your app target.
|
|
19
|
+
|
|
20
|
+
> **Note on the XCFramework path**: `Package.swift` references the XCFramework via a relative path (`../crates/native-ffi/ios/`). Some Xcode/SPM versions reject binary targets that live outside the package root. If you hit this, copy or symlink the framework into the package:
|
|
21
|
+
>
|
|
22
|
+
> ```bash
|
|
23
|
+
> mkdir -p swift/Frameworks
|
|
24
|
+
> cp -R crates/native-ffi/ios/NipworkerNativeFFI.xcframework swift/Frameworks/
|
|
25
|
+
> ```
|
|
26
|
+
>
|
|
27
|
+
> Then change the `binaryTarget` path in `swift/Package.swift` to `"Frameworks/NipworkerNativeFFI.xcframework"`.
|
|
28
|
+
|
|
29
|
+
### Swift Package Manager
|
|
30
|
+
|
|
31
|
+
Add the following to your `Package.swift`:
|
|
32
|
+
|
|
33
|
+
```swift
|
|
34
|
+
// swift-tools-version:5.9
|
|
35
|
+
import PackageDescription
|
|
36
|
+
|
|
37
|
+
let package = Package(
|
|
38
|
+
name: "YourApp",
|
|
39
|
+
platforms: [.iOS(.v14), .macOS(.v13)],
|
|
40
|
+
dependencies: [
|
|
41
|
+
.package(name: "NipworkerSwift", path: "../path-to-nipworker-repo/swift")
|
|
42
|
+
],
|
|
43
|
+
targets: [
|
|
44
|
+
.executableTarget(
|
|
45
|
+
name: "YourApp",
|
|
46
|
+
dependencies: ["NipworkerSwift"]
|
|
47
|
+
)
|
|
48
|
+
]
|
|
49
|
+
)
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
```swift
|
|
55
|
+
import NipworkerSwift
|
|
56
|
+
|
|
57
|
+
let manager = NostrManager()
|
|
58
|
+
|
|
59
|
+
let request = RequestObject(
|
|
60
|
+
filters: [.init(kinds: [1], limit: 10)],
|
|
61
|
+
relays: ["wss://relay.damus.io"]
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
let buffer = await manager.subscribe(
|
|
65
|
+
subscriptionId: "feed",
|
|
66
|
+
requests: [request]
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
let unsub = useSubscription(
|
|
70
|
+
manager: manager,
|
|
71
|
+
subscriptionId: "feed",
|
|
72
|
+
requests: [request]
|
|
73
|
+
) { events in
|
|
74
|
+
for event in events {
|
|
75
|
+
print("Event:", event.id, event.content)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## API Reference
|
|
81
|
+
|
|
82
|
+
### `NostrManager`
|
|
83
|
+
|
|
84
|
+
The core actor that owns the Rust engine handle. All methods are `async` or return values synchronously from the actor's isolated state.
|
|
85
|
+
|
|
86
|
+
```swift
|
|
87
|
+
public actor NostrManager {
|
|
88
|
+
public init(config: NostrManagerConfig = NostrManagerConfig())
|
|
89
|
+
|
|
90
|
+
// Subscription
|
|
91
|
+
public func subscribe(
|
|
92
|
+
subscriptionId: String,
|
|
93
|
+
requests: [RequestObject],
|
|
94
|
+
options: SubscriptionConfig = SubscriptionConfig()
|
|
95
|
+
) -> SubscriptionBuffer
|
|
96
|
+
|
|
97
|
+
public func unsubscribe(subscriptionId: String)
|
|
98
|
+
|
|
99
|
+
// Publish
|
|
100
|
+
public func publish(
|
|
101
|
+
publishId: String,
|
|
102
|
+
event: NostrEvent,
|
|
103
|
+
defaultRelays: [String] = [],
|
|
104
|
+
optimisticSubIds: [String] = []
|
|
105
|
+
) -> SubscriptionBuffer
|
|
106
|
+
|
|
107
|
+
// Signer
|
|
108
|
+
public func setSigner(_ signer: SignerTypeName)
|
|
109
|
+
public func getPublicKey() async throws -> String
|
|
110
|
+
public func signEvent(_ template: EventTemplate) async throws -> NostrEvent
|
|
111
|
+
public func logout()
|
|
112
|
+
|
|
113
|
+
// Read helpers
|
|
114
|
+
public func readEvents(for subId: String, from position: Int) -> (events: [NostrEvent], newPosition: Int)
|
|
115
|
+
public func readPublishStatuses(for publishId: String, from position: Int) -> (statuses: [String: PublishStatus], newPosition: Int)
|
|
116
|
+
public func getRelayStatuses() -> [String: RelayStatus]
|
|
117
|
+
public func getActivePubkey() -> String?
|
|
118
|
+
|
|
119
|
+
public func cleanup()
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Models
|
|
124
|
+
|
|
125
|
+
#### `RequestObject`
|
|
126
|
+
|
|
127
|
+
Defines a Nostr filter + relay set.
|
|
128
|
+
|
|
129
|
+
```swift
|
|
130
|
+
public struct RequestObject {
|
|
131
|
+
public var ids: [String]?
|
|
132
|
+
public var authors: [String]?
|
|
133
|
+
public var kinds: [UInt16]?
|
|
134
|
+
public var tags: [String: [String]]?
|
|
135
|
+
public var since: Int?
|
|
136
|
+
public var until: Int?
|
|
137
|
+
public var limit: Int?
|
|
138
|
+
public var search: String?
|
|
139
|
+
public var relays: [String]
|
|
140
|
+
public var closeOnEOSE: Bool?
|
|
141
|
+
public var cacheFirst: Bool?
|
|
142
|
+
public var noCache: Bool?
|
|
143
|
+
public var maxRelays: UInt16?
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### `SubscriptionConfig`
|
|
148
|
+
|
|
149
|
+
Controls subscription behavior.
|
|
150
|
+
|
|
151
|
+
```swift
|
|
152
|
+
public struct SubscriptionConfig {
|
|
153
|
+
public var pipeline: [PipeConfig]?
|
|
154
|
+
public var closeOnEose: Bool
|
|
155
|
+
public var cacheFirst: Bool
|
|
156
|
+
public var timeoutMs: UInt64?
|
|
157
|
+
public var maxEvents: UInt32?
|
|
158
|
+
public var skipCache: Bool
|
|
159
|
+
public var force: Bool
|
|
160
|
+
public var bytesPerEvent: UInt32
|
|
161
|
+
public var isSlow: Bool
|
|
162
|
+
public var pagination: String?
|
|
163
|
+
public var cacheOnly: Bool
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### `NostrEvent`
|
|
168
|
+
|
|
169
|
+
```swift
|
|
170
|
+
public struct NostrEvent: Identifiable, Equatable, Sendable {
|
|
171
|
+
public var id: String
|
|
172
|
+
public var pubkey: String
|
|
173
|
+
public var kind: UInt16
|
|
174
|
+
public var content: String
|
|
175
|
+
public var tags: [[String]]
|
|
176
|
+
public var createdAt: Int
|
|
177
|
+
public var sig: String
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### `EventTemplate`
|
|
182
|
+
|
|
183
|
+
Used when signing a new event.
|
|
184
|
+
|
|
185
|
+
```swift
|
|
186
|
+
public struct EventTemplate {
|
|
187
|
+
public var kind: UInt16
|
|
188
|
+
public var content: String
|
|
189
|
+
public var tags: [[String]]
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### `SignerTypeName`
|
|
194
|
+
|
|
195
|
+
```swift
|
|
196
|
+
public enum SignerTypeName: Sendable {
|
|
197
|
+
case pubkey(String)
|
|
198
|
+
case privkey(String)
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### `RelayStatus`
|
|
203
|
+
|
|
204
|
+
```swift
|
|
205
|
+
public enum RelayStatus: Equatable, Sendable {
|
|
206
|
+
case connected
|
|
207
|
+
case failed
|
|
208
|
+
case closed(String?)
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
#### `PublishStatus`
|
|
213
|
+
|
|
214
|
+
```swift
|
|
215
|
+
public enum PublishStatus: Equatable, Sendable {
|
|
216
|
+
case pending
|
|
217
|
+
case success(String)
|
|
218
|
+
case failed(String)
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Hooks
|
|
223
|
+
|
|
224
|
+
Callback-based helpers that mirror the JS `useSubscription` / `usePublish` / `useRelayStatus` hooks. They return an unsubscribe function.
|
|
225
|
+
|
|
226
|
+
```swift
|
|
227
|
+
public func useSubscription(
|
|
228
|
+
manager: NostrManager,
|
|
229
|
+
subscriptionId: String,
|
|
230
|
+
requests: [RequestObject],
|
|
231
|
+
callback: @escaping ([NostrEvent]) -> Void,
|
|
232
|
+
options: SubscriptionConfig = SubscriptionConfig()
|
|
233
|
+
) -> () -> Void
|
|
234
|
+
|
|
235
|
+
public func usePublish(
|
|
236
|
+
manager: NostrManager,
|
|
237
|
+
publishId: String,
|
|
238
|
+
event: NostrEvent,
|
|
239
|
+
callback: @escaping ([String: PublishStatus]) -> Void,
|
|
240
|
+
defaultRelays: [String] = [],
|
|
241
|
+
optimisticSubIds: [String] = []
|
|
242
|
+
) -> () -> Void
|
|
243
|
+
|
|
244
|
+
public func useRelayStatus(
|
|
245
|
+
manager: NostrManager,
|
|
246
|
+
onStatus: @escaping (String, RelayStatus) -> Void
|
|
247
|
+
) -> () -> Void
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### SwiftUI Helpers
|
|
251
|
+
|
|
252
|
+
#### `Subscription`
|
|
253
|
+
|
|
254
|
+
An `@MainActor ObservableObject` that wraps a subscription and exposes `@Published` events.
|
|
255
|
+
|
|
256
|
+
```swift
|
|
257
|
+
@MainActor
|
|
258
|
+
public final class Subscription: ObservableObject {
|
|
259
|
+
@Published public private(set) var events: [NostrEvent] = []
|
|
260
|
+
@Published public private(set) var isComplete: Bool = false
|
|
261
|
+
public let id: String
|
|
262
|
+
|
|
263
|
+
public init(id: String, manager: NostrManager)
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
#### `PublishTracker`
|
|
268
|
+
|
|
269
|
+
An `@MainActor ObservableObject` that tracks publish statuses.
|
|
270
|
+
|
|
271
|
+
```swift
|
|
272
|
+
@MainActor
|
|
273
|
+
public final class PublishTracker: ObservableObject {
|
|
274
|
+
@Published public private(set) var statuses: [String: PublishStatus] = [:]
|
|
275
|
+
public let publishId: String
|
|
276
|
+
|
|
277
|
+
public init(publishId: String, manager: NostrManager)
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Examples
|
|
282
|
+
|
|
283
|
+
### Subscribe & display events in SwiftUI
|
|
284
|
+
|
|
285
|
+
```swift
|
|
286
|
+
import SwiftUI
|
|
287
|
+
import NipworkerSwift
|
|
288
|
+
|
|
289
|
+
@MainActor
|
|
290
|
+
class FeedViewModel: ObservableObject {
|
|
291
|
+
let manager = NostrManager()
|
|
292
|
+
let sub: Subscription
|
|
293
|
+
|
|
294
|
+
init() {
|
|
295
|
+
sub = Subscription(id: "feed", manager: manager)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
func start() async {
|
|
299
|
+
let request = RequestObject(
|
|
300
|
+
filters: [.init(kinds: [1], limit: 50)],
|
|
301
|
+
relays: ["wss://relay.damus.io"]
|
|
302
|
+
)
|
|
303
|
+
_ = await manager.subscribe(
|
|
304
|
+
subscriptionId: "feed",
|
|
305
|
+
requests: [request]
|
|
306
|
+
)
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
struct FeedView: View {
|
|
311
|
+
@StateObject var vm = FeedViewModel()
|
|
312
|
+
|
|
313
|
+
var body: some View {
|
|
314
|
+
List(vm.sub.events) { event in
|
|
315
|
+
VStack(alignment: .leading) {
|
|
316
|
+
Text(event.content)
|
|
317
|
+
.lineLimit(3)
|
|
318
|
+
Text("Kind \(event.kind)")
|
|
319
|
+
.font(.caption)
|
|
320
|
+
.foregroundColor(.secondary)
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
.task {
|
|
324
|
+
await vm.start()
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Native login and signer restore
|
|
331
|
+
|
|
332
|
+
`NostrManager` keeps the active signer in memory only. It does not persist private
|
|
333
|
+
keys, NIP-46 session data, or login state. Native apps should own that policy with
|
|
334
|
+
their own secure storage, typically Keychain on iOS/macOS.
|
|
335
|
+
|
|
336
|
+
On first login, validate the key by installing it as the signer and asking the
|
|
337
|
+
native engine for the public key:
|
|
338
|
+
|
|
339
|
+
```swift
|
|
340
|
+
let secret = "your-hex-private-key"
|
|
341
|
+
manager.setSigner(.privkey(secret))
|
|
342
|
+
let pubkey = try await manager.getPublicKey()
|
|
343
|
+
|
|
344
|
+
let session = AuthSession(
|
|
345
|
+
pubkey: pubkey,
|
|
346
|
+
signer: .privateKey(secret)
|
|
347
|
+
)
|
|
348
|
+
|
|
349
|
+
// App-owned persistence. Store this in Keychain, not UserDefaults.
|
|
350
|
+
let data = try JSONEncoder().encode(session)
|
|
351
|
+
try await keychain.save(data, account: "nostr-auth")
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
On app restart, load the saved session and restore the native signer explicitly:
|
|
355
|
+
|
|
356
|
+
```swift
|
|
357
|
+
if let data = try await keychain.load(account: "nostr-auth") {
|
|
358
|
+
let session = try JSONDecoder().decode(AuthSession.self, from: data)
|
|
359
|
+
|
|
360
|
+
switch session.signer {
|
|
361
|
+
case .privateKey(let secret):
|
|
362
|
+
manager.setSigner(.privkey(secret))
|
|
363
|
+
_ = try await manager.getPublicKey()
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
The library exposes `AuthSession` as a small `Codable` value so app code can use
|
|
369
|
+
one stable storage format. The actual storage backend is intentionally outside
|
|
370
|
+
`NostrManager`; the host app decides whether to persist, when to restore, whether
|
|
371
|
+
to use biometric gates, and how logout deletes credentials.
|
|
372
|
+
|
|
373
|
+
`logout()` clears Swift-side auth state for the manager. If the app persisted an
|
|
374
|
+
`AuthSession`, it must also delete that saved session from its own secure store.
|
|
375
|
+
|
|
376
|
+
### Publish a signed event
|
|
377
|
+
|
|
378
|
+
```swift
|
|
379
|
+
manager.setSigner(.privkey("your-hex-private-key"))
|
|
380
|
+
_ = try await manager.getPublicKey()
|
|
381
|
+
|
|
382
|
+
let template = EventTemplate(
|
|
383
|
+
kind: 1,
|
|
384
|
+
content: "Hello from Swift!",
|
|
385
|
+
tags: []
|
|
386
|
+
)
|
|
387
|
+
let event = try await manager.signEvent(template)
|
|
388
|
+
|
|
389
|
+
let tracker = PublishTracker(publishId: "pub-1", manager: manager)
|
|
390
|
+
|
|
391
|
+
_ = await manager.publish(
|
|
392
|
+
publishId: "pub-1",
|
|
393
|
+
event: event,
|
|
394
|
+
defaultRelays: ["wss://relay.damus.io"]
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
// tracker.statuses will update automatically via @Published
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Monitor relay status
|
|
401
|
+
|
|
402
|
+
```swift
|
|
403
|
+
let unsub = useRelayStatus(manager: manager) { relay, status in
|
|
404
|
+
print("Relay \(relay): \(status)")
|
|
405
|
+
}
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Architecture
|
|
409
|
+
|
|
410
|
+
- **Rust FFI** — A static library (`libnipworker_native_ffi.a`) compiled from the `native-ffi` crate and bundled as an `XCFramework`.
|
|
411
|
+
- **FlatBuffers** — All messages crossing the Swift/Rust boundary are serialized with FlatBuffers for zero-allocation parsing on the Rust side.
|
|
412
|
+
- **Actor Isolation** — `NostrManager` is a Swift `actor` so all state mutation is serialized and safe to call from any concurrency context.
|
|
413
|
+
- **Subscription Buffers** — Events arrive from Rust into a shared `SubscriptionBuffer` (a raw pointer with a 4-byte header). Swift reads length-prefixed messages out of the buffer.
|
|
414
|
+
|
|
415
|
+
## Testing
|
|
416
|
+
|
|
417
|
+
Run the test suite from the `swift/` directory:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
cd swift
|
|
421
|
+
swift test
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
The suite includes:
|
|
425
|
+
- **Unit tests** — `ArrayBufferReaderTests`, `NostrManagerTests`
|
|
426
|
+
- **Integration tests** — Live WebSocket subscription against `wss://relay.damus.io`
|
|
427
|
+
|
|
428
|
+
> Integration tests require an internet connection and may take a few seconds.
|
|
429
|
+
|
|
430
|
+
## Known Limitations
|
|
431
|
+
|
|
432
|
+
- **Swift 6 language mode warnings** — The package compiles and runs correctly, but produces a handful of concurrency warnings (e.g., accessing `handle`/`boxPtr` in the actor initializer). These are non-blocking.
|
|
433
|
+
- **FlatBuffers Object API** — Unavailable due to a `flatc` code-generation bug (`ParsedDataUnion` enum/struct name collision). All serialization uses the low-level builder API.
|
|
434
|
+
- **Native deployment target warnings** — Rebuild `NipworkerNativeFFI.xcframework` with `crates/native-ffi/ios/build-ios.sh`. The script passes explicit iOS and macOS minimum-version linker flags to Rust so the compiled static libraries match the Swift package deployment targets.
|
|
435
|
+
|
|
436
|
+
## License
|
|
437
|
+
|
|
438
|
+
Same as the parent NIPWorker project.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
/// Wraps a raw mutable buffer allocated with UnsafeMutablePointer.
|
|
4
|
+
/// Buffer format:
|
|
5
|
+
/// [0-3]: write position (UInt32 little-endian)
|
|
6
|
+
/// [4..]: [4-byte len][FlatBuffer payload]...
|
|
7
|
+
public final class SubscriptionBuffer {
|
|
8
|
+
public let pointer: UnsafeMutableRawPointer
|
|
9
|
+
public let capacity: Int
|
|
10
|
+
private let ownsMemory: Bool
|
|
11
|
+
|
|
12
|
+
public init(capacity: Int) {
|
|
13
|
+
self.pointer = .allocate(byteCount: capacity, alignment: MemoryLayout<UInt32>.alignment)
|
|
14
|
+
self.capacity = capacity
|
|
15
|
+
self.ownsMemory = true
|
|
16
|
+
// Initialize write position to 4 (right after header)
|
|
17
|
+
pointer.storeBytes(of: UInt32(4).littleEndian, toByteOffset: 0, as: UInt32.self)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public init(pointer: UnsafeMutableRawPointer, capacity: Int) {
|
|
21
|
+
self.pointer = pointer
|
|
22
|
+
self.capacity = capacity
|
|
23
|
+
self.ownsMemory = false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
deinit {
|
|
27
|
+
if ownsMemory {
|
|
28
|
+
pointer.deallocate()
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public enum ArrayBufferReader {
|
|
34
|
+
public static func initializeBuffer(_ buffer: SubscriptionBuffer) {
|
|
35
|
+
buffer.pointer.storeBytes(of: UInt32(4).littleEndian, toByteOffset: 0, as: UInt32.self)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public static func writeMessage(buffer: SubscriptionBuffer, data: Data) -> Bool {
|
|
39
|
+
let currentWritePosition = readWritePosition(buffer)
|
|
40
|
+
let requiredSpace = 4 + data.count
|
|
41
|
+
guard currentWritePosition + requiredSpace <= buffer.capacity else {
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
buffer.pointer.storeBytes(
|
|
46
|
+
of: UInt32(data.count).littleEndian,
|
|
47
|
+
toByteOffset: currentWritePosition,
|
|
48
|
+
as: UInt32.self
|
|
49
|
+
)
|
|
50
|
+
data.copyBytes(to: buffer.pointer.advanced(by: currentWritePosition + 4).assumingMemoryBound(to: UInt8.self), count: data.count)
|
|
51
|
+
|
|
52
|
+
let newPosition = currentWritePosition + requiredSpace
|
|
53
|
+
buffer.pointer.storeBytes(of: UInt32(newPosition).littleEndian, toByteOffset: 0, as: UInt32.self)
|
|
54
|
+
return true
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public static func writeBatchedData(buffer: SubscriptionBuffer, data: Data, debugId: String? = nil) -> Bool {
|
|
58
|
+
let currentWritePosition = readWritePosition(buffer)
|
|
59
|
+
guard currentWritePosition + data.count <= buffer.capacity else {
|
|
60
|
+
return false
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
data.copyBytes(to: buffer.pointer.advanced(by: currentWritePosition).assumingMemoryBound(to: UInt8.self), count: data.count)
|
|
64
|
+
|
|
65
|
+
let newPosition = currentWritePosition + data.count
|
|
66
|
+
buffer.pointer.storeBytes(of: UInt32(newPosition).littleEndian, toByteOffset: 0, as: UInt32.self)
|
|
67
|
+
return true
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public static func readMessages(
|
|
71
|
+
buffer: SubscriptionBuffer,
|
|
72
|
+
lastReadPosition: Int = 0
|
|
73
|
+
) -> (messages: [Data], newReadPosition: Int, hasNewData: Bool) {
|
|
74
|
+
let currentWritePosition = readWritePosition(buffer)
|
|
75
|
+
let dataStartOffset = 4
|
|
76
|
+
var currentPos = max(lastReadPosition, dataStartOffset)
|
|
77
|
+
|
|
78
|
+
guard currentWritePosition > currentPos else {
|
|
79
|
+
return ([], currentPos, false)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
var messages: [Data] = []
|
|
83
|
+
let maxMessages = 128
|
|
84
|
+
|
|
85
|
+
while currentPos < currentWritePosition && messages.count < maxMessages {
|
|
86
|
+
guard currentPos + 4 <= currentWritePosition else { break }
|
|
87
|
+
|
|
88
|
+
let eventLength = Int(
|
|
89
|
+
UInt32(buffer.pointer.load(fromByteOffset: currentPos, as: UInt8.self)) |
|
|
90
|
+
(UInt32(buffer.pointer.load(fromByteOffset: currentPos + 1, as: UInt8.self)) << 8) |
|
|
91
|
+
(UInt32(buffer.pointer.load(fromByteOffset: currentPos + 2, as: UInt8.self)) << 16) |
|
|
92
|
+
(UInt32(buffer.pointer.load(fromByteOffset: currentPos + 3, as: UInt8.self)) << 24)
|
|
93
|
+
)
|
|
94
|
+
let payloadStart = currentPos + 4
|
|
95
|
+
let nextPos = payloadStart + eventLength
|
|
96
|
+
|
|
97
|
+
guard nextPos <= currentWritePosition else { break }
|
|
98
|
+
|
|
99
|
+
let slice = Data(bytes: buffer.pointer.advanced(by: payloadStart), count: eventLength)
|
|
100
|
+
messages.append(slice)
|
|
101
|
+
currentPos = nextPos
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (messages, currentPos, messages.count > 0)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public static func readAllMessages(buffer: SubscriptionBuffer) -> (messages: [Data], totalMessages: Int) {
|
|
108
|
+
let result = readMessages(buffer: buffer, lastReadPosition: 0)
|
|
109
|
+
return (result.messages, result.messages.count)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public static func getCurrentWritePosition(buffer: SubscriptionBuffer) -> Int {
|
|
113
|
+
return readWritePosition(buffer)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public static func hasNewData(buffer: SubscriptionBuffer, lastReadPosition: Int) -> Bool {
|
|
117
|
+
let currentWritePosition = readWritePosition(buffer)
|
|
118
|
+
return currentWritePosition > max(lastReadPosition, 4)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public static func calculateBufferSize(totalEventLimit: Int = 100, bytesPerEvent: Int = 3072) -> Int {
|
|
122
|
+
let headerSize = 4
|
|
123
|
+
let dataSize = totalEventLimit * bytesPerEvent
|
|
124
|
+
let overhead = Int(Double(dataSize) * 0.25)
|
|
125
|
+
return headerSize + dataSize + overhead
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private static func readWritePosition(_ buffer: SubscriptionBuffer) -> Int {
|
|
129
|
+
return Int(
|
|
130
|
+
UInt32(buffer.pointer.load(fromByteOffset: 0, as: UInt8.self)) |
|
|
131
|
+
(UInt32(buffer.pointer.load(fromByteOffset: 1, as: UInt8.self)) << 8) |
|
|
132
|
+
(UInt32(buffer.pointer.load(fromByteOffset: 2, as: UInt8.self)) << 16) |
|
|
133
|
+
(UInt32(buffer.pointer.load(fromByteOffset: 3, as: UInt8.self)) << 24)
|
|
134
|
+
)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public enum AuthSigner: Codable, Equatable, Sendable {
|
|
4
|
+
case privateKey(String)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
public struct AuthSession: Codable, Equatable, Sendable {
|
|
8
|
+
public var pubkey: String
|
|
9
|
+
public var signer: AuthSigner
|
|
10
|
+
public var createdAt: Date
|
|
11
|
+
public var lastUsedAt: Date?
|
|
12
|
+
|
|
13
|
+
public init(
|
|
14
|
+
pubkey: String,
|
|
15
|
+
signer: AuthSigner,
|
|
16
|
+
createdAt: Date = Date(),
|
|
17
|
+
lastUsedAt: Date? = nil
|
|
18
|
+
) {
|
|
19
|
+
self.pubkey = pubkey
|
|
20
|
+
self.signer = signer
|
|
21
|
+
self.createdAt = createdAt
|
|
22
|
+
self.lastUsedAt = lastUsedAt
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import Darwin
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
// MARK: - C FFI Imports from libnipworker_native_ffi
|
|
5
|
+
|
|
6
|
+
@_silgen_name("nipworker_init")
|
|
7
|
+
func nipworker_init(
|
|
8
|
+
_ callback: @convention(c) (UnsafeMutableRawPointer?, UnsafePointer<UInt8>?, Int) -> Void,
|
|
9
|
+
_ userdata: UnsafeMutableRawPointer?
|
|
10
|
+
) -> UnsafeMutableRawPointer?
|
|
11
|
+
|
|
12
|
+
@_silgen_name("nipworker_handle_message")
|
|
13
|
+
func nipworker_handle_message(
|
|
14
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
15
|
+
_ ptr: UnsafePointer<UInt8>?,
|
|
16
|
+
_ len: Int
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
@_silgen_name("nipworker_subscribe_message")
|
|
20
|
+
func nipworker_subscribe_message(
|
|
21
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
22
|
+
_ ptr: UnsafePointer<UInt8>?,
|
|
23
|
+
_ len: Int
|
|
24
|
+
) -> Bool
|
|
25
|
+
|
|
26
|
+
@_silgen_name("nipworker_publish_message")
|
|
27
|
+
func nipworker_publish_message(
|
|
28
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
29
|
+
_ ptr: UnsafePointer<UInt8>?,
|
|
30
|
+
_ len: Int
|
|
31
|
+
) -> Bool
|
|
32
|
+
|
|
33
|
+
@_silgen_name("nipworker_set_private_key")
|
|
34
|
+
func nipworker_set_private_key(
|
|
35
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
36
|
+
_ ptr: UnsafePointer<Int8>?
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
@_silgen_name("nipworker_deinit")
|
|
40
|
+
func nipworker_deinit(_ handle: UnsafeMutableRawPointer?)
|
|
41
|
+
|
|
42
|
+
@_silgen_name("nipworker_free_bytes")
|
|
43
|
+
func nipworker_free_bytes(_ ptr: UnsafeMutablePointer<UInt8>?, _ len: Int)
|
|
44
|
+
|
|
45
|
+
@_silgen_name("nipworker_register_subscription")
|
|
46
|
+
func nipworker_register_subscription(
|
|
47
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
48
|
+
_ subId: UnsafePointer<Int8>?,
|
|
49
|
+
_ bufferSize: Int
|
|
50
|
+
) -> Bool
|
|
51
|
+
|
|
52
|
+
@_silgen_name("nipworker_register_publish_buffer")
|
|
53
|
+
func nipworker_register_publish_buffer(
|
|
54
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
55
|
+
_ publishId: UnsafePointer<Int8>?,
|
|
56
|
+
_ bufferSize: Int
|
|
57
|
+
) -> Bool
|
|
58
|
+
|
|
59
|
+
@_silgen_name("nipworker_retain_subscription")
|
|
60
|
+
func nipworker_retain_subscription(
|
|
61
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
62
|
+
_ subId: UnsafePointer<Int8>?
|
|
63
|
+
) -> Bool
|
|
64
|
+
|
|
65
|
+
@_silgen_name("nipworker_release_subscription")
|
|
66
|
+
func nipworker_release_subscription(
|
|
67
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
68
|
+
_ subId: UnsafePointer<Int8>?
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@_silgen_name("nipworker_subscription_buffer_ptr")
|
|
72
|
+
func nipworker_subscription_buffer_ptr(
|
|
73
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
74
|
+
_ subId: UnsafePointer<Int8>?
|
|
75
|
+
) -> UnsafeMutablePointer<UInt8>?
|
|
76
|
+
|
|
77
|
+
@_silgen_name("nipworker_subscription_buffer_len")
|
|
78
|
+
func nipworker_subscription_buffer_len(
|
|
79
|
+
_ handle: UnsafeMutableRawPointer?,
|
|
80
|
+
_ subId: UnsafePointer<Int8>?
|
|
81
|
+
) -> Int
|
|
82
|
+
|
|
83
|
+
@_silgen_name("nipworker_cleanup_subscriptions")
|
|
84
|
+
func nipworker_cleanup_subscriptions(_ handle: UnsafeMutableRawPointer?)
|
|
85
|
+
|
|
86
|
+
func nipworker_react_native_shared_handle_if_available() -> UnsafeMutableRawPointer? {
|
|
87
|
+
typealias SharedHandleFunction = @convention(c) () -> UnsafeMutableRawPointer?
|
|
88
|
+
|
|
89
|
+
guard let symbol = dlsym(UnsafeMutableRawPointer(bitPattern: -2), "nipworker_react_native_shared_handle") else {
|
|
90
|
+
return nil
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return unsafeBitCast(symbol, to: SharedHandleFunction.self)()
|
|
94
|
+
}
|