From 256a7bd4109e6b4da6a2d2d8e7ed9d270ad38fe4 Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Wed, 6 Dec 2023 16:28:14 +0100 Subject: [PATCH 1/8] ffi(nostr): use `uniffi` pro-macro instead of `UDL` --- bindings/nostr-ffi/Makefile | 19 +- .../scripts/generate-linux-aarch64.sh | 5 +- .../bindings-python/scripts/generate-linux.sh | 5 +- .../scripts/generate-macos-arm64.sh | 5 +- .../scripts/generate-macos-x86_64.sh | 5 +- .../scripts/generate-windows.sh | 5 +- bindings/nostr-ffi/build.rs | 6 - bindings/nostr-ffi/src/error.rs | 4 +- bindings/nostr-ffi/src/event/builder.rs | 218 ++++---- bindings/nostr-ffi/src/event/id.rs | 38 +- bindings/nostr-ffi/src/event/mod.rs | 10 +- bindings/nostr-ffi/src/event/tag.rs | 21 +- bindings/nostr-ffi/src/event/unsigned.rs | 10 +- bindings/nostr-ffi/src/key/mod.rs | 85 +-- bindings/nostr-ffi/src/key/public_key.rs | 32 +- bindings/nostr-ffi/src/key/secret_key.rs | 25 +- bindings/nostr-ffi/src/lib.rs | 56 +- bindings/nostr-ffi/src/message/client.rs | 2 + bindings/nostr-ffi/src/message/relay.rs | 2 + .../nostr-ffi/src/message/subscription.rs | 89 ++- bindings/nostr-ffi/src/nips/nip04.rs | 2 + bindings/nostr-ffi/src/nips/nip05.rs | 2 + bindings/nostr-ffi/src/nips/nip11.rs | 11 +- bindings/nostr-ffi/src/nips/nip44.rs | 2 + bindings/nostr-ffi/src/nips/nip46.rs | 10 +- bindings/nostr-ffi/src/nips/nip57.rs | 11 +- bindings/nostr-ffi/src/nips/nip94.rs | 11 +- bindings/nostr-ffi/src/nostr.udl | 516 ------------------ bindings/nostr-ffi/src/types/contact.rs | 12 +- bindings/nostr-ffi/src/types/image.rs | 13 +- bindings/nostr-ffi/src/types/metadata.rs | 84 ++- bindings/nostr-ffi/src/types/profile.rs | 27 +- bindings/nostr-ffi/src/types/time.rs | 19 +- bindings/nostr-ffi/src/util.rs | 1 + bindings/nostr-ffi/uniffi.toml | 7 +- 35 files changed, 516 insertions(+), 854 deletions(-) delete mode 100644 bindings/nostr-ffi/build.rs delete mode 100644 bindings/nostr-ffi/src/nostr.udl diff --git a/bindings/nostr-ffi/Makefile b/bindings/nostr-ffi/Makefile index 33e14227b..1b245a01a 100644 --- a/bindings/nostr-ffi/Makefile +++ b/bindings/nostr-ffi/Makefile @@ -24,11 +24,14 @@ sdk-root: exit 1 ; \ fi +kotlin-clean: + mkdir -p ffi/kotlin/jniLibs + find ./ffi/kotlin/jniLibs -name libnostr_ffi.so -type f -delete + kotlin: android - find ./ffi/kotlin/jniLibs -name libnostr_sdk_ffi.so -type f -delete - cargo run -p uniffi-bindgen generate src/nostr.udl --language kotlin --no-format -o ffi/kotlin + cargo run -p uniffi-bindgen generate --library ../../target/x86_64-linux-android/release/libnostr_ffi.so --language kotlin --no-format -o ffi/kotlin -android: aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android +android: kotlin-clean aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android aarch64-linux-android: $(SOURCES) ndk-home cargo ndk -t aarch64-linux-android -o ffi/kotlin/jniLibs build --release @@ -71,18 +74,18 @@ darwin-universal: $(SOURCES) lipo -create -output ../../target/darwin-universal/release/libnostr_ffi.a ../../target/aarch64-apple-darwin/release/libnostr_ffi.a ../../target/x86_64-apple-darwin/release/libnostr_ffi.a swift-ios: ios-universal - cargo run -p uniffi-bindgen generate src/nostr.udl -l swift -o ffi/swift-ios + cargo run -p uniffi-bindgen generate --library ../../target/aarch64-apple-ios/release/libnostr_ffi.a --language swift -o ffi/swift-ios cp ../../target/ios-universal/release/libnostr_ffi.a ffi/swift-ios cd ffi/swift-ios && "swiftc" "-emit-module" "-module-name" "nostr_ffi" "-Xcc" "-fmodule-map-file=$(CURRENT_DIR)/ffi/swift-ios/nostrFFI.modulemap" "-I" "." "-L" "." "-lnostr_ffi" nostr.swift swift-darwin: darwin-universal - cargo run -p uniffi-bindgen generate src/nostr.udl -l swift -o ffi/swift-darwin + cargo run -p uniffi-bindgen generate --library ../../target/aarch64-apple-darwin/release/libnostr_ffi.a --language swift -o ffi/swift-darwin cp ../../target/darwin-universal/release/libnostr_ffi.dylib ffi/swift-darwin cd ffi/swift-darwin && "swiftc" "-emit-module" "-module-name" "nostr_ffi" "-Xcc" "-fmodule-map-file=$(CURRENT_DIR)/ffi/swift-darwin/nostrFFI.modulemap" "-I" "." "-L" "." "-lnostr_ffi" nostr.swift bindings-swift: ios-universal darwin-universal mkdir -p bindings-swift/Sources/Nostr - cargo run -p uniffi-bindgen generate src/nostr.udl --no-format --language swift --out-dir bindings-swift/Sources/Nostr + cargo run -p uniffi-bindgen generate --library ../../target/aarch64-apple-ios/release/libnostr_ffi.a --no-format --language swift --out-dir bindings-swift/Sources/Nostr mv bindings-swift/Sources/Nostr/nostr.swift bindings-swift/Sources/Nostr/Nostr.swift cp bindings-swift/Sources/Nostr/nostrFFI.h bindings-swift/nostrFFI.xcframework/ios-arm64/nostrFFI.framework/Headers cp bindings-swift/Sources/Nostr/nostrFFI.h bindings-swift/nostrFFI.xcframework/ios-arm64_x86_64-simulator/nostrFFI.framework/Headers @@ -97,7 +100,7 @@ python: rm -rf bindings-python/dist pip install -r bindings-python/requirements.txt cargo build --release - cargo run -p uniffi-bindgen generate src/nostr.udl --language python --no-format -o bindings-python/src/nostr/ + cargo run -p uniffi-bindgen generate --library ../../target/release/libnostr_ffi.so --language python --no-format -o bindings-python/src/nostr/ cp ../../target/release/libnostr_ffi.so bindings-python/src/nostr/ | true cp ../../target/release/libnostr_ffi.dylib bindings-python/src/nostr/ | true cd bindings-python && python setup.py --verbose bdist_wheel @@ -106,7 +109,7 @@ python: python-win: pip install -r bindings-python\requirements.txt cargo build --release - cargo run -p uniffi-bindgen generate src/nostr.udl --language python --no-format -o bindings-python/src/nostr/ + cargo run -p uniffi-bindgen generate --library ..\..\target\release\nostr_ffi.dll --language python --no-format -o bindings-python/src/nostr/ copy ..\..\target\release\nostr_ffi.dll bindings-python\src\nostr del /F /Q bindings-python\dist\* cd bindings-python && python setup.py --verbose bdist_wheel diff --git a/bindings/nostr-ffi/bindings-python/scripts/generate-linux-aarch64.sh b/bindings/nostr-ffi/bindings-python/scripts/generate-linux-aarch64.sh index 45be20151..95dcfa168 100755 --- a/bindings/nostr-ffi/bindings-python/scripts/generate-linux-aarch64.sh +++ b/bindings/nostr-ffi/bindings-python/scripts/generate-linux-aarch64.sh @@ -4,14 +4,15 @@ set -euo pipefail python --version pip install -r requirements.txt -echo "Generating nostr.py..." cd ../ -cargo run -p uniffi-bindgen generate src/nostr.udl --language python --no-format -o bindings-python/src/nostr/ echo "Generating native binaries..." rustup target add aarch64-unknown-linux-gnu CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc cargo build --release --target aarch64-unknown-linux-gnu +echo "Generating nostr.py..." +cargo run -p uniffi-bindgen generate --library ../../target/aarch64-unknown-linux-gnu/release/libnostr_ffi.so --language python --no-format -o bindings-python/src/nostr/ + echo "Copying linux libnostr_ffi.so..." cp ../../target/aarch64-unknown-linux-gnu/release/libnostr_ffi.so bindings-python/src/nostr/ diff --git a/bindings/nostr-ffi/bindings-python/scripts/generate-linux.sh b/bindings/nostr-ffi/bindings-python/scripts/generate-linux.sh index 365351b27..d82d4139f 100644 --- a/bindings/nostr-ffi/bindings-python/scripts/generate-linux.sh +++ b/bindings/nostr-ffi/bindings-python/scripts/generate-linux.sh @@ -4,13 +4,14 @@ set -euo pipefail ${PYBIN}/python --version ${PYBIN}/pip install -r requirements.txt -echo "Generating nostr.py..." cd ../ -cargo run -p uniffi-bindgen generate src/nostr.udl --language python --no-format -o bindings-python/src/nostr/ echo "Generating native binaries..." cargo build --release +echo "Generating nostr.py..." +cargo run -p uniffi-bindgen generate --library ../../target/release/libnostr_ffi.so --language python --no-format -o bindings-python/src/nostr/ + echo "Copying linux libnostr_ffi.so..." cp ../../target/release/libnostr_ffi.so bindings-python/src/nostr/ diff --git a/bindings/nostr-ffi/bindings-python/scripts/generate-macos-arm64.sh b/bindings/nostr-ffi/bindings-python/scripts/generate-macos-arm64.sh index 314f02534..1a870082d 100644 --- a/bindings/nostr-ffi/bindings-python/scripts/generate-macos-arm64.sh +++ b/bindings/nostr-ffi/bindings-python/scripts/generate-macos-arm64.sh @@ -4,14 +4,15 @@ set -euo pipefail python3 --version pip install --user -r requirements.txt -echo "Generating nostr.py..." cd ../ -cargo run -p uniffi-bindgen generate src/nostr.udl --language python --no-format -o bindings-python/src/nostr/ echo "Generating native binaries..." rustup target add aarch64-apple-darwin cargo build --release --target aarch64-apple-darwin +echo "Generating nostr.py..." +cargo run -p uniffi-bindgen generate --library ../../target/aarch64-apple-darwin/release/libnostr_ffi.a --language python --no-format -o bindings-python/src/nostr/ + echo "Copying libraries libnostr_ffi.dylib..." cp ../../target/aarch64-apple-darwin/release/libnostr_ffi.dylib bindings-python/src/nostr/ diff --git a/bindings/nostr-ffi/bindings-python/scripts/generate-macos-x86_64.sh b/bindings/nostr-ffi/bindings-python/scripts/generate-macos-x86_64.sh index e24ad5cc8..c43435bde 100644 --- a/bindings/nostr-ffi/bindings-python/scripts/generate-macos-x86_64.sh +++ b/bindings/nostr-ffi/bindings-python/scripts/generate-macos-x86_64.sh @@ -4,14 +4,15 @@ set -euo pipefail python3 --version pip install --user -r requirements.txt -echo "Generating nostr.py..." cd ../ -cargo run -p uniffi-bindgen generate src/nostr.udl --language python --no-format -o bindings-python/src/nostr/ echo "Generating native binaries..." rustup target add x86_64-apple-darwin cargo build --release --target x86_64-apple-darwin +echo "Generating nostr.py..." +cargo run -p uniffi-bindgen generate --library ../../target/x86_64-apple-darwin/release/libnostr_ffi.a --language python --no-format -o bindings-python/src/nostr/ + echo "Copying libraries libnostr_ffi.dylib..." cp ../../target/x86_64-apple-darwin/release/libnostr_ffi.dylib bindings-python/src/nostr/ diff --git a/bindings/nostr-ffi/bindings-python/scripts/generate-windows.sh b/bindings/nostr-ffi/bindings-python/scripts/generate-windows.sh index 16be94533..fc56a3870 100644 --- a/bindings/nostr-ffi/bindings-python/scripts/generate-windows.sh +++ b/bindings/nostr-ffi/bindings-python/scripts/generate-windows.sh @@ -4,14 +4,15 @@ set -euo pipefail python3 --version pip install --user -r requirements.txt -echo "Generating nostr.py..." cd ../ -cargo run -p uniffi-bindgen generate src/nostr.udl --language python --no-format -o bindings-python/src/nostr/ echo "Generating native binaries..." rustup target add x86_64-pc-windows-msvc cargo build --release --target x86_64-pc-windows-msvc +echo "Generating nostr.py..." +cargo run -p uniffi-bindgen generate --library ../../target/x86_64-pc-windows-msvc/release/nostr_ffi.dll --language python --no-format -o bindings-python/src/nostr/ + echo "Copying libraries nostr_ffi.dll..." cp ../../target/x86_64-pc-windows-msvc/release/nostr_ffi.dll bindings-python/src/nostr/ diff --git a/bindings/nostr-ffi/build.rs b/bindings/nostr-ffi/build.rs deleted file mode 100644 index 1ccb303c7..000000000 --- a/bindings/nostr-ffi/build.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) 2022-2023 Yuki Kishimoto -// Distributed under the MIT software license - -fn main() { - uniffi::generate_scaffolding("./src/nostr.udl").expect("Building the UDL file failed"); -} diff --git a/bindings/nostr-ffi/src/error.rs b/bindings/nostr-ffi/src/error.rs index 4fe6a9a0e..b10ba6f73 100644 --- a/bindings/nostr-ffi/src/error.rs +++ b/bindings/nostr-ffi/src/error.rs @@ -4,9 +4,11 @@ use std::fmt; use std::net::AddrParseError; +use uniffi::Error; + pub type Result = std::result::Result; -#[derive(Debug)] +#[derive(Debug, Error)] pub enum NostrError { Generic { err: String }, } diff --git a/bindings/nostr-ffi/src/event/builder.rs b/bindings/nostr-ffi/src/event/builder.rs index 6c49ec809..1b9a52889 100644 --- a/bindings/nostr-ffi/src/event/builder.rs +++ b/bindings/nostr-ffi/src/event/builder.rs @@ -5,7 +5,8 @@ use std::ops::Deref; use std::sync::Arc; use nostr::url::Url; -use nostr::{ChannelId, Contact as ContactSdk, EventBuilder as EventBuilderSdk}; +use nostr::{ChannelId, Contact as ContactSdk}; +use uniffi::Object; use super::{Event, EventId}; use crate::error::Result; @@ -14,42 +15,45 @@ use crate::nips::nip57::ZapRequestData; use crate::types::{Contact, Metadata}; use crate::{FileMetadata, PublicKey, Tag, UnsignedEvent}; +#[derive(Object)] pub struct EventBuilder { - builder: EventBuilderSdk, + inner: nostr::EventBuilder, } -impl From for EventBuilder { - fn from(builder: EventBuilderSdk) -> Self { - Self { builder } +impl From for EventBuilder { + fn from(inner: nostr::EventBuilder) -> Self { + Self { inner } } } impl Deref for EventBuilder { - type Target = EventBuilderSdk; + type Target = nostr::EventBuilder; fn deref(&self) -> &Self::Target { - &self.builder + &self.inner } } +#[uniffi::export] impl EventBuilder { - pub fn new(kind: u64, content: String, tags: Vec>) -> Result { + #[uniffi::constructor] + pub fn new(kind: u64, content: String, tags: Vec>) -> Result> { let tags = tags .into_iter() .map(|t| t.as_ref().deref().clone()) .collect::>(); - Ok(Self { - builder: EventBuilderSdk::new(kind.into(), content, &tags), - }) + Ok(Arc::new(Self { + inner: nostr::EventBuilder::new(kind.into(), content, &tags), + })) } pub fn to_event(&self, keys: Arc) -> Result> { - let event = self.builder.clone().to_event(keys.deref())?; + let event = self.inner.clone().to_event(keys.deref())?; Ok(Arc::new(event.into())) } pub fn to_pow_event(&self, keys: Arc, difficulty: u8) -> Result> { Ok(Arc::new( - self.builder + self.inner .clone() .to_pow_event(keys.deref(), difficulty)? .into(), @@ -58,7 +62,7 @@ impl EventBuilder { pub fn to_unsigned_event(&self, public_key: Arc) -> Arc { Arc::new( - self.builder + self.inner .clone() .to_unsigned_event(*public_key.as_ref().deref()) .into(), @@ -71,198 +75,222 @@ impl EventBuilder { difficulty: u8, ) -> Arc { Arc::new( - self.builder + self.inner .clone() .to_unsigned_pow_event(*public_key.as_ref().deref(), difficulty) .into(), ) } -} -impl EventBuilder { - pub fn set_metadata(metadata: Arc) -> Self { - Self { - builder: EventBuilderSdk::set_metadata(metadata.as_ref().deref().clone()), - } + #[uniffi::constructor] + pub fn set_metadata(metadata: Arc) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::set_metadata(metadata.as_ref().deref().clone()), + }) } - pub fn add_recommended_relay(url: String) -> Result { + #[uniffi::constructor] + pub fn add_recommended_relay(url: String) -> Result> { let url = Url::parse(&url)?; - Ok(Self { - builder: EventBuilderSdk::add_recommended_relay(&url), - }) + Ok(Arc::new(Self { + inner: nostr::EventBuilder::add_recommended_relay(&url), + })) } - pub fn new_text_note(content: String, tags: Vec>) -> Result { + #[uniffi::constructor] + pub fn new_text_note(content: String, tags: Vec>) -> Result> { let tags = tags .into_iter() .map(|t| t.as_ref().deref().clone()) .collect::>(); - Ok(Self { - builder: EventBuilderSdk::new_text_note(content, &tags), - }) + Ok(Arc::new(Self { + inner: nostr::EventBuilder::new_text_note(content, &tags), + })) } - pub fn long_form_text_note(content: String, tags: Vec>) -> Result { + #[uniffi::constructor] + pub fn long_form_text_note(content: String, tags: Vec>) -> Result> { let tags = tags .into_iter() .map(|t| t.as_ref().deref().clone()) .collect::>(); - Ok(Self { - builder: EventBuilderSdk::long_form_text_note(content, &tags), - }) + Ok(Arc::new(Self { + inner: nostr::EventBuilder::long_form_text_note(content, &tags), + })) } - pub fn set_contact_list(list: Vec>) -> Self { + #[uniffi::constructor] + pub fn set_contact_list(list: Vec>) -> Arc { let list: Vec = list .into_iter() .map(|c| c.as_ref().deref().clone()) .collect(); - Self { - builder: EventBuilderSdk::set_contact_list(list), - } + Arc::new(Self { + inner: nostr::EventBuilder::set_contact_list(list), + }) } /// Create encrypted direct msg event + #[uniffi::constructor] pub fn new_encrypted_direct_msg( sender_keys: Arc, receiver_pubkey: Arc, content: String, reply_to: Option>, - ) -> Result { - Ok(Self { - builder: EventBuilderSdk::new_encrypted_direct_msg( + ) -> Result> { + Ok(Arc::new(Self { + inner: nostr::EventBuilder::new_encrypted_direct_msg( sender_keys.deref(), *receiver_pubkey.as_ref().deref(), content, reply_to.map(|id| id.as_ref().into()), )?, - }) + })) } - pub fn repost(event_id: Arc, public_key: Arc) -> Self { - Self { - builder: EventBuilderSdk::repost( + #[uniffi::constructor] + pub fn repost(event_id: Arc, public_key: Arc) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::repost( event_id.as_ref().into(), *public_key.as_ref().deref(), ), - } + }) } /// Create delete event - pub fn delete(ids: Vec>, reason: Option) -> Self { + #[uniffi::constructor] + pub fn delete(ids: Vec>, reason: Option) -> Arc { let ids: Vec = ids.into_iter().map(|e| e.as_ref().into()).collect(); - Self { - builder: match reason { - Some(reason) => EventBuilderSdk::delete_with_reason(ids, reason), - None => EventBuilderSdk::delete(ids), + Arc::new(Self { + inner: match reason { + Some(reason) => nostr::EventBuilder::delete_with_reason(ids, reason), + None => nostr::EventBuilder::delete(ids), }, - } + }) } + #[uniffi::constructor] pub fn new_reaction( event_id: Arc, public_key: Arc, content: String, - ) -> Self { - Self { - builder: EventBuilderSdk::new_reaction( + ) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::new_reaction( event_id.as_ref().into(), *public_key.as_ref().deref(), content, ), - } + }) } - pub fn new_channel(metadata: Arc) -> Self { - Self { - builder: EventBuilderSdk::new_channel(metadata.as_ref().deref().clone()), - } + #[uniffi::constructor] + pub fn new_channel(metadata: Arc) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::new_channel(metadata.as_ref().deref().clone()), + }) } + #[uniffi::constructor] pub fn set_channel_metadata( channel_id: String, relay_url: Option, metadata: Arc, - ) -> Result { + ) -> Result> { let relay_url = match relay_url { Some(url) => Some(Url::parse(&url)?), None => None, }; - Ok(Self { - builder: EventBuilderSdk::set_channel_metadata( + Ok(Arc::new(Self { + inner: nostr::EventBuilder::set_channel_metadata( ChannelId::from_hex(channel_id)?, relay_url, metadata.as_ref().deref().clone(), ), - }) + })) } - pub fn new_channel_msg(channel_id: String, relay_url: String, content: String) -> Result { - Ok(Self { - builder: EventBuilderSdk::new_channel_msg( + #[uniffi::constructor] + pub fn new_channel_msg( + channel_id: String, + relay_url: String, + content: String, + ) -> Result> { + Ok(Arc::new(Self { + inner: nostr::EventBuilder::new_channel_msg( ChannelId::from_hex(channel_id)?, Url::parse(&relay_url)?, content, ), - }) + })) } - pub fn hide_channel_msg(message_id: Arc, reason: Option) -> Self { - Self { - builder: EventBuilderSdk::hide_channel_msg(message_id.as_ref().into(), reason), - } + #[uniffi::constructor] + pub fn hide_channel_msg(message_id: Arc, reason: Option) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::hide_channel_msg(message_id.as_ref().into(), reason), + }) } - pub fn mute_channel_user(public_key: Arc, reason: Option) -> Self { - Self { - builder: EventBuilderSdk::mute_channel_user(*public_key.as_ref().deref(), reason), - } + #[uniffi::constructor] + pub fn mute_channel_user(public_key: Arc, reason: Option) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::mute_channel_user(*public_key.as_ref().deref(), reason), + }) } - pub fn auth(challenge: String, relay_url: String) -> Result { - Ok(Self { - builder: EventBuilderSdk::auth(challenge, Url::parse(&relay_url)?), - }) + #[uniffi::constructor] + pub fn auth(challenge: String, relay_url: String) -> Result> { + Ok(Arc::new(Self { + inner: nostr::EventBuilder::auth(challenge, Url::parse(&relay_url)?), + })) } // TODO: add nostr_connect method - pub fn report(tags: Vec>, content: String) -> Self { + #[uniffi::constructor] + pub fn report(tags: Vec>, content: String) -> Arc { let tags = tags .into_iter() .map(|t| t.as_ref().deref().clone()) .collect::>(); - Self { - builder: EventBuilderSdk::report(&tags, content), - } + Arc::new(Self { + inner: nostr::EventBuilder::report(&tags, content), + }) } - pub fn new_zap_request(data: Arc) -> Self { - Self { - builder: EventBuilderSdk::new_zap_request(data.as_ref().deref().clone()), - } + #[uniffi::constructor] + pub fn new_zap_request(data: Arc) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::new_zap_request(data.as_ref().deref().clone()), + }) } + #[uniffi::constructor] pub fn new_zap_receipt( bolt11: String, preimage: Option, zap_request: Arc, - ) -> Self { - Self { - builder: EventBuilderSdk::new_zap_receipt( + ) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::new_zap_receipt( bolt11, preimage, zap_request.as_ref().deref().clone(), ), - } + }) } - pub fn file_metadata(description: String, metadata: Arc) -> Self { - Self { - builder: EventBuilderSdk::file_metadata(description, metadata.as_ref().deref().clone()), - } + #[uniffi::constructor] + pub fn file_metadata(description: String, metadata: Arc) -> Arc { + Arc::new(Self { + inner: nostr::EventBuilder::file_metadata( + description, + metadata.as_ref().deref().clone(), + ), + }) } } diff --git a/bindings/nostr-ffi/src/event/id.rs b/bindings/nostr-ffi/src/event/id.rs index d31c42a2f..c0959d073 100644 --- a/bindings/nostr-ffi/src/event/id.rs +++ b/bindings/nostr-ffi/src/event/id.rs @@ -7,10 +7,12 @@ use std::sync::Arc; use nostr::nips::nip21::NostrURI; use nostr::prelude::{FromBech32, ToBech32}; use nostr::{Kind, Tag}; +use uniffi::Object; use crate::error::Result; use crate::{PublicKey, Timestamp}; +#[derive(Object)] pub struct EventId { inner: nostr::EventId, } @@ -40,19 +42,21 @@ impl From<&EventId> for nostr::EventId { } } +#[uniffi::export] impl EventId { + #[uniffi::constructor] pub fn new( pubkey: Arc, created_at: Arc, kind: u64, tags: Vec>, content: String, - ) -> Result { + ) -> Result> { let mut new_tags: Vec = Vec::new(); for tag in tags.into_iter() { new_tags.push(Tag::try_from(tag)?); } - Ok(Self { + Ok(Arc::new(Self { inner: nostr::EventId::new( pubkey.as_ref().deref(), *created_at.as_ref().deref(), @@ -60,31 +64,35 @@ impl EventId { &new_tags, &content, ), - }) + })) } - pub fn from_bytes(bytes: Vec) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_bytes(bytes: Vec) -> Result> { + Ok(Arc::new(Self { inner: nostr::EventId::from_slice(&bytes)?, - }) + })) } - pub fn from_hex(hex: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_hex(hex: String) -> Result> { + Ok(Arc::new(Self { inner: nostr::EventId::from_hex(hex)?, - }) + })) } - pub fn from_bech32(id: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_bech32(id: String) -> Result> { + Ok(Arc::new(Self { inner: nostr::EventId::from_bech32(id)?, - }) + })) } - pub fn from_nostr_uri(uri: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_nostr_uri(uri: String) -> Result> { + Ok(Arc::new(Self { inner: nostr::EventId::from_nostr_uri(uri)?, - }) + })) } pub fn as_bytes(&self) -> Vec { diff --git a/bindings/nostr-ffi/src/event/mod.rs b/bindings/nostr-ffi/src/event/mod.rs index aec296886..ac72275c0 100644 --- a/bindings/nostr-ffi/src/event/mod.rs +++ b/bindings/nostr-ffi/src/event/mod.rs @@ -5,6 +5,7 @@ use std::ops::Deref; use std::sync::Arc; use nostr::{Event as EventSdk, JsonUtil}; +use uniffi::Object; mod builder; mod id; @@ -18,6 +19,7 @@ pub use self::unsigned::UnsignedEvent; use crate::error::Result; use crate::{PublicKey, Timestamp}; +#[derive(Object)] pub struct Event { inner: EventSdk, } @@ -35,6 +37,7 @@ impl Deref for Event { } } +#[uniffi::export] impl Event { pub fn id(&self) -> Arc { Arc::new(self.inner.id.into()) @@ -73,10 +76,11 @@ impl Event { self.inner.verify().is_ok() } - pub fn from_json(json: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_json(json: String) -> Result> { + Ok(Arc::new(Self { inner: EventSdk::from_json(json)?, - }) + })) } pub fn as_json(&self) -> String { diff --git a/bindings/nostr-ffi/src/event/tag.rs b/bindings/nostr-ffi/src/event/tag.rs index bbcc9bfea..c49a9220f 100644 --- a/bindings/nostr-ffi/src/event/tag.rs +++ b/bindings/nostr-ffi/src/event/tag.rs @@ -3,6 +3,7 @@ use std::ops::Deref; use std::str::FromStr; +use std::sync::Arc; use nostr::event::tag::{ self, HttpMethod, Identity, ImageDimensions, LiveEventMarker, LiveEventStatus, Marker, Report, @@ -14,14 +15,17 @@ use nostr::nips::nip90::DataVendingMachineStatus; use nostr::secp256k1::schnorr::Signature; use nostr::secp256k1::XOnlyPublicKey; use nostr::{Event, EventId, JsonUtil, Kind, RelayMetadata, Timestamp, UncheckedUrl, Url}; +use uniffi::{Enum, Object}; use crate::error::{NostrError, Result}; +#[derive(Enum)] pub enum TagKind { Known { known: TagKindKnown }, Unknown { unknown: String }, } +#[derive(Enum)] pub enum TagKindKnown { /// Public key P, @@ -333,6 +337,7 @@ impl From for tag::TagKind { } } +#[derive(Enum)] pub enum TagEnum { Unknown { kind: TagKind, @@ -864,6 +869,7 @@ impl TryFrom for tag::Tag { } } +#[derive(Object)] pub struct Tag { inner: tag::Tag, } @@ -881,17 +887,20 @@ impl Deref for Tag { } } +#[uniffi::export] impl Tag { - pub fn parse(data: Vec) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn parse(data: Vec) -> Result> { + Ok(Arc::new(Self { inner: tag::Tag::try_from(data)?, - }) + })) } - pub fn from_enum(e: TagEnum) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_enum(e: TagEnum) -> Result> { + Ok(Arc::new(Self { inner: tag::Tag::try_from(e)?, - }) + })) } pub fn as_enum(&self) -> TagEnum { diff --git a/bindings/nostr-ffi/src/event/unsigned.rs b/bindings/nostr-ffi/src/event/unsigned.rs index 49957e94d..1f247de87 100644 --- a/bindings/nostr-ffi/src/event/unsigned.rs +++ b/bindings/nostr-ffi/src/event/unsigned.rs @@ -7,11 +7,13 @@ use std::sync::Arc; use nostr::secp256k1::schnorr::Signature; use nostr::JsonUtil; +use uniffi::Object; use super::EventId; use crate::error::Result; use crate::{Event, Keys, PublicKey, Tag, Timestamp}; +#[derive(Object)] pub struct UnsignedEvent { inner: nostr::UnsignedEvent, } @@ -22,6 +24,7 @@ impl From for UnsignedEvent { } } +#[uniffi::export] impl UnsignedEvent { pub fn id(&self) -> Arc { Arc::new(self.inner.id.into()) @@ -66,10 +69,11 @@ impl UnsignedEvent { ))) } - pub fn from_json(json: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_json(json: String) -> Result> { + Ok(Arc::new(Self { inner: nostr::UnsignedEvent::from_json(json)?, - }) + })) } pub fn as_json(&self) -> String { diff --git a/bindings/nostr-ffi/src/key/mod.rs b/bindings/nostr-ffi/src/key/mod.rs index 057a97d67..e917bfe40 100644 --- a/bindings/nostr-ffi/src/key/mod.rs +++ b/bindings/nostr-ffi/src/key/mod.rs @@ -4,8 +4,9 @@ use std::ops::Deref; use std::sync::Arc; -use nostr::key::{FromPkStr, FromSkStr, Keys as KeysSdk}; +use nostr::key::{self, FromPkStr, FromSkStr}; use nostr::nips::nip06::FromMnemonic; +use uniffi::Object; mod public_key; mod secret_key; @@ -14,73 +15,81 @@ pub use self::public_key::PublicKey; pub use self::secret_key::SecretKey; use crate::error::{NostrError, Result}; -#[derive(Clone)] +#[derive(Clone, Object)] pub struct Keys { - keys: KeysSdk, + inner: key::Keys, } impl Deref for Keys { - type Target = KeysSdk; + type Target = key::Keys; fn deref(&self) -> &Self::Target { - &self.keys + &self.inner } } -impl From for Keys { - fn from(keys: KeysSdk) -> Self { - Self { keys } +impl From for Keys { + fn from(inner: key::Keys) -> Self { + Self { inner } } } +#[uniffi::export] impl Keys { - pub fn new(sk: Arc) -> Self { - Self { - keys: KeysSdk::new(**sk), - } - } - - pub fn from_public_key(pk: Arc) -> Self { - Self { - keys: KeysSdk::from_public_key(*pk.as_ref().deref()), - } + #[uniffi::constructor] + pub fn new(sk: Arc) -> Arc { + Arc::new(Self { + inner: key::Keys::new(**sk), + }) } - pub fn from_sk_str(sk: String) -> Result { - Ok(Self { - keys: KeysSdk::from_sk_str(&sk)?, + #[uniffi::constructor] + pub fn from_public_key(pk: Arc) -> Arc { + Arc::new(Self { + inner: key::Keys::from_public_key(*pk.as_ref().deref()), }) } - pub fn from_pk_str(pk: String) -> Result { - Ok(Self { - keys: KeysSdk::from_pk_str(&pk)?, - }) + #[uniffi::constructor] + pub fn from_sk_str(sk: String) -> Result> { + Ok(Arc::new(Self { + inner: key::Keys::from_sk_str(&sk)?, + })) } - pub fn generate() -> Self { - Self { - keys: KeysSdk::generate(), - } + #[uniffi::constructor] + pub fn from_pk_str(pk: String) -> Result> { + Ok(Arc::new(Self { + inner: key::Keys::from_pk_str(&pk)?, + })) } - pub fn vanity(prefixes: Vec, bech32: bool, num_cores: u8) -> Result { - Ok(Self { - keys: KeysSdk::vanity(prefixes, bech32, num_cores as usize)?, + #[uniffi::constructor] + pub fn generate() -> Arc { + Arc::new(Self { + inner: key::Keys::generate(), }) } - pub fn from_mnemonic(mnemonic: String, passphrase: Option) -> Result { - Ok(Self { - keys: KeysSdk::from_mnemonic(mnemonic, passphrase) + #[uniffi::constructor] + pub fn vanity(prefixes: Vec, bech32: bool, num_cores: u8) -> Result> { + Ok(Arc::new(Self { + inner: key::Keys::vanity(prefixes, bech32, num_cores as usize)?, + })) + } + + #[uniffi::constructor] + pub fn from_mnemonic(mnemonic: String, passphrase: Option) -> Result> { + Ok(Arc::new(Self { + inner: key::Keys::from_mnemonic(mnemonic, passphrase) .map_err(|e| NostrError::Generic { err: e.to_string() })?, - }) + })) } pub fn public_key(&self) -> Arc { - Arc::new(self.keys.public_key().into()) + Arc::new(self.inner.public_key().into()) } pub fn secret_key(&self) -> Result> { - Ok(Arc::new(self.keys.secret_key()?.into())) + Ok(Arc::new(self.inner.secret_key()?.into())) } } diff --git a/bindings/nostr-ffi/src/key/public_key.rs b/bindings/nostr-ffi/src/key/public_key.rs index 0ceedcb3a..9f664de9e 100644 --- a/bindings/nostr-ffi/src/key/public_key.rs +++ b/bindings/nostr-ffi/src/key/public_key.rs @@ -3,13 +3,16 @@ use std::ops::Deref; use std::str::FromStr; +use std::sync::Arc; use nostr::nips::nip19::{FromBech32, ToBech32}; use nostr::nips::nip21::NostrURI; use nostr::secp256k1::XOnlyPublicKey; +use uniffi::Object; use crate::error::Result; +#[derive(Object)] pub struct PublicKey { inner: XOnlyPublicKey, } @@ -33,29 +36,34 @@ impl Deref for PublicKey { } } +#[uniffi::export] impl PublicKey { - pub fn from_hex(hex: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_hex(hex: String) -> Result> { + Ok(Arc::new(Self { inner: XOnlyPublicKey::from_str(&hex)?, - }) + })) } - pub fn from_bech32(pk: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_bech32(pk: String) -> Result> { + Ok(Arc::new(Self { inner: XOnlyPublicKey::from_bech32(pk)?, - }) + })) } - pub fn from_bytes(bytes: Vec) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_bytes(bytes: Vec) -> Result> { + Ok(Arc::new(Self { inner: XOnlyPublicKey::from_slice(&bytes)?, - }) + })) } - pub fn from_nostr_uri(uri: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_nostr_uri(uri: String) -> Result> { + Ok(Arc::new(Self { inner: XOnlyPublicKey::from_nostr_uri(uri)?, - }) + })) } pub fn to_hex(&self) -> String { diff --git a/bindings/nostr-ffi/src/key/secret_key.rs b/bindings/nostr-ffi/src/key/secret_key.rs index 006950bdc..d7ca57c38 100644 --- a/bindings/nostr-ffi/src/key/secret_key.rs +++ b/bindings/nostr-ffi/src/key/secret_key.rs @@ -3,12 +3,15 @@ use std::ops::Deref; use std::str::FromStr; +use std::sync::Arc; use nostr::nips::nip19::{FromBech32, ToBech32}; use nostr::secp256k1::SecretKey as Sk; +use uniffi::Object; use crate::error::Result; +#[derive(Object)] pub struct SecretKey { inner: Sk, } @@ -26,23 +29,27 @@ impl Deref for SecretKey { } } +#[uniffi::export] impl SecretKey { - pub fn from_hex(hex: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_hex(hex: String) -> Result> { + Ok(Arc::new(Self { inner: Sk::from_str(&hex)?, - }) + })) } - pub fn from_bech32(sk: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_bech32(sk: String) -> Result> { + Ok(Arc::new(Self { inner: Sk::from_bech32(sk)?, - }) + })) } - pub fn from_bytes(bytes: Vec) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_bytes(bytes: Vec) -> Result> { + Ok(Arc::new(Self { inner: Sk::from_slice(&bytes)?, - }) + })) } pub fn to_hex(&self) -> String { diff --git a/bindings/nostr-ffi/src/lib.rs b/bindings/nostr-ffi/src/lib.rs index fcf5fc4bb..6ade572b1 100644 --- a/bindings/nostr-ffi/src/lib.rs +++ b/bindings/nostr-ffi/src/lib.rs @@ -1,6 +1,9 @@ // Copyright (c) 2022-2023 Yuki Kishimoto // Distributed under the MIT software license +//pub use nostr::nips::nip44::Version as NIP44Version; +pub use nostr::Alphabet; + mod error; mod event; pub mod helper; @@ -10,37 +13,28 @@ mod nips; mod types; mod util; -#[allow(missing_docs)] -#[allow(unused_imports)] -mod ffi { - // External - //pub use nostr::nips::nip44::Version as NIP44Version; - pub use nostr::Alphabet; - - // Error - pub use crate::error::NostrError; +// Error +pub use crate::error::NostrError; - // Nostr - pub use crate::event::{ - Event, EventBuilder, EventId, Tag, TagEnum, TagKind, TagKindKnown, UnsignedEvent, - }; - pub use crate::key::{Keys, PublicKey, SecretKey}; - pub use crate::message::{ClientMessage, Filter, RelayMessage}; - pub use crate::nips::nip04::{nip04_decrypt, nip04_encrypt}; - pub use crate::nips::nip05::{get_nip05_profile, verify_nip05}; - pub use crate::nips::nip11::RelayInformationDocument; - //pub use crate::nips::nip44::{nip44_decrypt, nip44_encrypt}; - pub use crate::nips::nip46::NostrConnectURI; - pub use crate::nips::nip57::ZapRequestData; - pub use crate::nips::nip94::FileMetadata; - pub use crate::types::{Contact, ImageDimensions, Metadata, Profile, Timestamp}; - pub use crate::util::generate_shared_key; +// Nostr +pub use crate::event::{ + Event, EventBuilder, EventId, Tag, TagEnum, TagKind, TagKindKnown, UnsignedEvent, +}; +pub use crate::key::{Keys, PublicKey, SecretKey}; +pub use crate::message::{ClientMessage, Filter, RelayMessage}; +pub use crate::nips::nip04::{nip04_decrypt, nip04_encrypt}; +pub use crate::nips::nip05::{get_nip05_profile, verify_nip05}; +pub use crate::nips::nip11::RelayInformationDocument; +//pub use crate::nips::nip44::{nip44_decrypt, nip44_encrypt}; +pub use crate::nips::nip46::NostrConnectURI; +pub use crate::nips::nip57::ZapRequestData; +pub use crate::nips::nip94::FileMetadata; +pub use crate::types::{Contact, ImageDimensions, Metadata, Profile, Timestamp}; +pub use crate::util::generate_shared_key; - pub fn git_hash_version() -> String { - nostr::git_hash_version().to_string() - } - - // UDL - uniffi::include_scaffolding!("nostr"); +#[uniffi::export] +pub fn git_hash_version() -> String { + nostr::git_hash_version().to_string() } -pub use ffi::*; + +uniffi::setup_scaffolding!("nostr"); diff --git a/bindings/nostr-ffi/src/message/client.rs b/bindings/nostr-ffi/src/message/client.rs index 0bbb48371..408e2421e 100644 --- a/bindings/nostr-ffi/src/message/client.rs +++ b/bindings/nostr-ffi/src/message/client.rs @@ -2,9 +2,11 @@ // Distributed under the MIT software license use nostr::{Event, Filter, JsonUtil, SubscriptionId}; +use uniffi::Enum; use crate::NostrError; +#[derive(Enum)] pub enum ClientMessage { Ev { event: String, diff --git a/bindings/nostr-ffi/src/message/relay.rs b/bindings/nostr-ffi/src/message/relay.rs index 16eb52240..e436a4eec 100644 --- a/bindings/nostr-ffi/src/message/relay.rs +++ b/bindings/nostr-ffi/src/message/relay.rs @@ -2,7 +2,9 @@ // Distributed under the MIT software license use nostr::{JsonUtil, RelayMessage as NRelayMessage}; +use uniffi::Enum; +#[derive(Enum)] pub enum RelayMessage { Ev { subscription_id: String, diff --git a/bindings/nostr-ffi/src/message/subscription.rs b/bindings/nostr-ffi/src/message/subscription.rs index d269ed2a4..4c23f02ee 100644 --- a/bindings/nostr-ffi/src/message/subscription.rs +++ b/bindings/nostr-ffi/src/message/subscription.rs @@ -4,24 +4,82 @@ use std::ops::Deref; use std::sync::Arc; -use nostr::message::subscription::Alphabet; +use nostr::message::subscription; use nostr::JsonUtil; +use uniffi::{Enum, Object}; use crate::error::Result; use crate::helper::unwrap_or_clone_arc; use crate::{Event, EventId, PublicKey, Timestamp}; -#[derive(Clone)] -pub struct Filter { - inner: nostr::Filter, +#[derive(Enum)] +pub enum Alphabet { + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, } -impl Default for Filter { - fn default() -> Self { - Self::new() +impl From for subscription::Alphabet { + fn from(value: Alphabet) -> Self { + match value { + Alphabet::A => Self::A, + Alphabet::B => Self::B, + Alphabet::C => Self::C, + Alphabet::D => Self::D, + Alphabet::E => Self::E, + Alphabet::F => Self::F, + Alphabet::G => Self::G, + Alphabet::H => Self::H, + Alphabet::I => Self::I, + Alphabet::J => Self::J, + Alphabet::K => Self::K, + Alphabet::L => Self::L, + Alphabet::M => Self::M, + Alphabet::N => Self::N, + Alphabet::O => Self::O, + Alphabet::P => Self::P, + Alphabet::Q => Self::Q, + Alphabet::R => Self::R, + Alphabet::S => Self::S, + Alphabet::T => Self::T, + Alphabet::U => Self::U, + Alphabet::V => Self::V, + Alphabet::W => Self::W, + Alphabet::X => Self::X, + Alphabet::Y => Self::Y, + Alphabet::Z => Self::Z, + } } } +#[derive(Clone, Object)] +pub struct Filter { + inner: nostr::Filter, +} + impl Deref for Filter { type Target = nostr::Filter; fn deref(&self) -> &Self::Target { @@ -35,11 +93,13 @@ impl From for Filter { } } +#[uniffi::export] impl Filter { - pub fn new() -> Self { - Self { + #[uniffi::constructor] + pub fn new() -> Arc { + Arc::new(Self { inner: nostr::Filter::new(), - } + }) } pub fn id(self: Arc, id: Arc) -> Arc { @@ -138,7 +198,7 @@ impl Filter { pub fn custom_tag(self: Arc, tag: Alphabet, content: Vec) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.inner = builder.inner.custom_tag(tag, content); + builder.inner = builder.inner.custom_tag(tag.into(), content); Arc::new(builder) } @@ -146,10 +206,11 @@ impl Filter { self.inner.match_event(event.as_ref().deref()) } - pub fn from_json(json: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_json(json: String) -> Result> { + Ok(Arc::new(Self { inner: nostr::Filter::from_json(json)?, - }) + })) } pub fn as_json(&self) -> String { diff --git a/bindings/nostr-ffi/src/nips/nip04.rs b/bindings/nostr-ffi/src/nips/nip04.rs index 9a444b527..11d9cbba7 100644 --- a/bindings/nostr-ffi/src/nips/nip04.rs +++ b/bindings/nostr-ffi/src/nips/nip04.rs @@ -9,6 +9,7 @@ use nostr::nips::nip04; use crate::error::Result; use crate::{PublicKey, SecretKey}; +#[uniffi::export] pub fn nip04_encrypt( secret_key: Arc, public_key: Arc, @@ -21,6 +22,7 @@ pub fn nip04_encrypt( )?) } +#[uniffi::export] pub fn nip04_decrypt( secret_key: Arc, public_key: Arc, diff --git a/bindings/nostr-ffi/src/nips/nip05.rs b/bindings/nostr-ffi/src/nips/nip05.rs index 1a710d301..4928ccb15 100644 --- a/bindings/nostr-ffi/src/nips/nip05.rs +++ b/bindings/nostr-ffi/src/nips/nip05.rs @@ -10,6 +10,7 @@ use nostr::nips::nip05; use crate::error::Result; use crate::{Profile, PublicKey}; +#[uniffi::export] pub fn verify_nip05( public_key: Arc, nip05: String, @@ -26,6 +27,7 @@ pub fn verify_nip05( )?) } +#[uniffi::export] pub fn get_nip05_profile(nip05: String, proxy: Option) -> Result> { let proxy: Option = match proxy { Some(proxy) => Some(proxy.parse()?), diff --git a/bindings/nostr-ffi/src/nips/nip11.rs b/bindings/nostr-ffi/src/nips/nip11.rs index a13206f54..5531d6c5d 100644 --- a/bindings/nostr-ffi/src/nips/nip11.rs +++ b/bindings/nostr-ffi/src/nips/nip11.rs @@ -2,12 +2,15 @@ // Distributed under the MIT software license use std::net::SocketAddr; +use std::sync::Arc; use nostr::nips::nip11; use nostr::Url; +use uniffi::Object; use crate::error::Result; +#[derive(Object)] pub struct RelayInformationDocument { inner: nip11::RelayInformationDocument, } @@ -18,16 +21,18 @@ impl From for RelayInformationDocument { } } +#[uniffi::export] impl RelayInformationDocument { - pub fn get(url: String, proxy: Option) -> Result { + #[uniffi::constructor] + pub fn get(url: String, proxy: Option) -> Result> { let url: Url = Url::parse(&url)?; let proxy: Option = match proxy { Some(proxy) => Some(proxy.parse()?), None => None, }; - Ok(Self { + Ok(Arc::new(Self { inner: nip11::RelayInformationDocument::get_blocking(url, proxy)?, - }) + })) } pub fn name(&self) -> Option { diff --git a/bindings/nostr-ffi/src/nips/nip44.rs b/bindings/nostr-ffi/src/nips/nip44.rs index 1fbb2d6e9..92f37255c 100644 --- a/bindings/nostr-ffi/src/nips/nip44.rs +++ b/bindings/nostr-ffi/src/nips/nip44.rs @@ -9,6 +9,7 @@ use nostr::nips::nip44::{self, Version}; use crate::error::Result; use crate::{PublicKey, SecretKey}; +#[uniffi::export] pub fn nip44_encrypt( secret_key: Arc, public_key: Arc, @@ -23,6 +24,7 @@ pub fn nip44_encrypt( )?) } +#[uniffi::export] pub fn nip44_decrypt( secret_key: Arc, public_key: Arc, diff --git a/bindings/nostr-ffi/src/nips/nip46.rs b/bindings/nostr-ffi/src/nips/nip46.rs index bfdef9cfc..fe00a69cb 100644 --- a/bindings/nostr-ffi/src/nips/nip46.rs +++ b/bindings/nostr-ffi/src/nips/nip46.rs @@ -6,10 +6,12 @@ use std::str::FromStr; use std::sync::Arc; use nostr::nips::nip46; +use uniffi::Object; use crate::error::Result; use crate::PublicKey; +#[derive(Object)] pub struct NostrConnectURI { inner: nip46::NostrConnectURI, } @@ -27,11 +29,13 @@ impl Deref for NostrConnectURI { } } +#[uniffi::export] impl NostrConnectURI { - pub fn from_string(uri: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_string(uri: String) -> Result> { + Ok(Arc::new(Self { inner: nip46::NostrConnectURI::from_str(&uri)?, - }) + })) } pub fn public_key(&self) -> Arc { diff --git a/bindings/nostr-ffi/src/nips/nip57.rs b/bindings/nostr-ffi/src/nips/nip57.rs index cc2083d46..167668cbd 100644 --- a/bindings/nostr-ffi/src/nips/nip57.rs +++ b/bindings/nostr-ffi/src/nips/nip57.rs @@ -5,11 +5,12 @@ use std::ops::Deref; use std::sync::Arc; use nostr::nips::nip57; +use uniffi::Object; use crate::helper::unwrap_or_clone_arc; use crate::{EventId, PublicKey}; -#[derive(Clone)] +#[derive(Clone, Object)] pub struct ZapRequestData { inner: nip57::ZapRequestData, } @@ -27,14 +28,16 @@ impl From for ZapRequestData { } } +#[uniffi::export] impl ZapRequestData { - pub fn new(public_key: Arc, relays: Vec) -> Self { - Self { + #[uniffi::constructor] + pub fn new(public_key: Arc, relays: Vec) -> Arc { + Arc::new(Self { inner: nip57::ZapRequestData::new( public_key.as_ref().into(), relays.into_iter().map(|r| r.into()).collect(), ), - } + }) } pub fn amount(self: Arc, amount: u64) -> Arc { diff --git a/bindings/nostr-ffi/src/nips/nip94.rs b/bindings/nostr-ffi/src/nips/nip94.rs index 91a2c8c61..ed7fc2a34 100644 --- a/bindings/nostr-ffi/src/nips/nip94.rs +++ b/bindings/nostr-ffi/src/nips/nip94.rs @@ -8,12 +8,13 @@ use std::sync::Arc; use nostr::hashes::sha256::Hash as Sha256Hash; use nostr::nips::nip94; use nostr::url::Url; +use uniffi::Object; use crate::error::Result; use crate::helper::unwrap_or_clone_arc; use crate::ImageDimensions; -#[derive(Clone)] +#[derive(Clone, Object)] pub struct FileMetadata { inner: nip94::FileMetadata, } @@ -31,13 +32,15 @@ impl From for FileMetadata { } } +#[uniffi::export] impl FileMetadata { - pub fn new(url: String, mime_type: String, hash: String) -> Result { + #[uniffi::constructor] + pub fn new(url: String, mime_type: String, hash: String) -> Result> { let url = Url::parse(&url)?; let hash = Sha256Hash::from_str(&hash)?; - Ok(Self { + Ok(Arc::new(Self { inner: nip94::FileMetadata::new(url, mime_type, hash), - }) + })) } pub fn aes_256_gcm(self: Arc, key: String, iv: String) -> Arc { diff --git a/bindings/nostr-ffi/src/nostr.udl b/bindings/nostr-ffi/src/nostr.udl deleted file mode 100644 index ae7549b85..000000000 --- a/bindings/nostr-ffi/src/nostr.udl +++ /dev/null @@ -1,516 +0,0 @@ -// Copyright (c) 2022-2023 Yuki Kishimoto -// Distributed under the MIT software license - -namespace nostr { - string git_hash_version(); - - [Throws=NostrError] - sequence generate_shared_key(SecretKey secret_key, PublicKey public_key); - - [Throws=NostrError] - string nip04_encrypt(SecretKey secret_key, PublicKey public_key, string content); - [Throws=NostrError] - string nip04_decrypt(SecretKey secret_key, PublicKey public_key, string encrypted_content); - - [Throws=NostrError] - void verify_nip05(PublicKey public_key, string nip05, string? proxy); - [Throws=NostrError] - Profile get_nip05_profile(string nip05, string? proxy); -}; - -[Error] -interface NostrError { - Generic(string err); -}; - -interface RelayInformationDocument { - [Throws=NostrError, Name=get] - constructor(string url, string? proxy); - string? name(); - string? description(); - string? pubkey(); - string? contact(); - sequence? supported_nips(); - string? software(); - string? version(); -}; - -interface NostrConnectURI { - [Throws=NostrError, Name=from_string] - constructor(string uri); - PublicKey public_key(); - string relay_url(); - string name(); - string? url(); - string? description(); -}; - -interface Profile { - constructor(PublicKey public_key, sequence relays); - [Throws=NostrError, Name=from_bech32] - constructor(string bech32); - [Throws=NostrError, Name=from_nostr_uri] - constructor(string uri); - [Throws=NostrError] - string to_bech32(); - [Throws=NostrError] - string to_nostr_uri(); - PublicKey public_key(); - sequence relays(); -}; - -interface ImageDimensions { - constructor(u64 width, u64 height); - u64 width(); - u64 height(); -}; - -interface Timestamp { - [Name=now] - constructor(); - [Name=from_secs] - constructor(u64 secs); - u64 as_secs(); - string to_human_datetime(); -}; - -interface SecretKey { - [Throws=NostrError, Name=from_hex] - constructor(string hex); - [Throws=NostrError, Name=from_bech32] - constructor(string sk); - [Throws=NostrError, Name=from_bytes] - constructor(sequence sk); - string to_hex(); - [Throws=NostrError] - string to_bech32(); -}; - -interface PublicKey { - [Throws=NostrError, Name=from_hex] - constructor(string hex); - [Throws=NostrError, Name=from_bech32] - constructor(string pk); - [Throws=NostrError, Name=from_bytes] - constructor(sequence pk); - [Throws=NostrError, Name=from_nostr_uri] - constructor(string uri); - string to_hex(); - [Throws=NostrError] - string to_bech32(); - [Throws=NostrError] - string to_nostr_uri(); -}; - -interface Keys { - constructor(SecretKey sk); - [Name=from_public_key] - constructor(PublicKey pk); - [Throws=NostrError, Name=from_sk_str] - constructor(string sk); - [Throws=NostrError, Name=from_pk_str] - constructor(string pk); - [Name=generate] - constructor(); - [Throws=NostrError, Name=vanity] - constructor(sequence prefixes, boolean bech32, u8 num_cores); - [Throws=NostrError, Name=from_mnemonic] - constructor(string mnemonic, optional string? passphrase = null); - PublicKey public_key(); - [Throws=NostrError] - SecretKey secret_key(); -}; - -[Enum] -interface ClientMessage { - Ev(string event); - Req(string subscription_id, sequence filters); - Count(string subscription_id, sequence filters); - Close(string subscription_id); - Auth(string event); -}; - -[Enum] -interface RelayMessage { - Ev(string subscription_id, string event); - Notice(string message); - EndOfStoredEvents(string subscription_id); - Ok(string event_id, boolean status, string message); - Auth(string challenge); - Count(string subscription_id, u64 count); - NegMsg(string subscription_id, string message); - NegErr(string subscription_id, string code); -}; - -interface ZapRequestData { - constructor(PublicKey public_key, sequence relays); - [Self=ByArc] - ZapRequestData amount(u64 amount); - [Self=ByArc] - ZapRequestData lnurl(string lnurl); - [Self=ByArc] - ZapRequestData event_id(EventId event_id); -}; - -enum Alphabet { - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", -}; - -interface Filter { - constructor(); - [Self=ByArc] - Filter id(EventId id); - [Self=ByArc] - Filter ids(sequence ids); - [Self=ByArc] - Filter author(PublicKey author); - [Self=ByArc] - Filter authors(sequence authors); - [Self=ByArc] - Filter kind(u64 kind); - [Self=ByArc] - Filter kinds(sequence kinds); - [Self=ByArc] - Filter event(EventId event_id); - [Self=ByArc] - Filter events(sequence ids); - [Self=ByArc] - Filter pubkey(PublicKey pubkey); - [Self=ByArc] - Filter pubkeys(sequence pubkeys); - [Self=ByArc] - Filter identifier(string identifier); - [Self=ByArc] - Filter search(string text); - [Self=ByArc] - Filter since(Timestamp timestamp); - [Self=ByArc] - Filter until(Timestamp timestamp); - [Self=ByArc] - Filter limit(u64 limit); - [Self=ByArc] - Filter custom_tag(Alphabet tag, sequence content); - boolean match_event(Event event); - [Throws=NostrError, Name=from_json] - constructor(string json); - string as_json(); -}; - -interface EventId { - [Throws=NostrError] - constructor(PublicKey pubkey, Timestamp created_at, u64 kind, sequence> tags, string content); - [Throws=NostrError, Name=from_bytes] - constructor(sequence bytes); - [Throws=NostrError, Name=from_hex] - constructor(string hex); - [Throws=NostrError, Name=from_bech32] - constructor(string id); - [Throws=NostrError, Name=from_nostr_uri] - constructor(string uri); - sequence as_bytes(); - string to_hex(); - [Throws=NostrError] - string to_bech32(); - [Throws=NostrError] - string to_nostr_uri(); -}; - -interface UnsignedEvent { - EventId id(); - PublicKey pubkey(); - Timestamp created_at(); - u64 kind(); - sequence tags(); - string content(); - [Throws=NostrError] - Event sign(Keys keys); - [Throws=NostrError] - Event add_signature(string sig); - [Throws=NostrError, Name=from_json] - constructor(string json); - string as_json(); -}; - -interface Event { - EventId id(); - PublicKey pubkey(); - Timestamp created_at(); - u64 kind(); - sequence tags(); - string content(); - string signature(); - boolean verify(); - [Throws=NostrError, Name=from_json] - constructor(string json); - string as_json(); -}; - -interface EventBuilder { - [Throws=NostrError] - constructor(u64 kind, string content, sequence tags); - [Throws=NostrError] - Event to_event(Keys keys); - [Throws=NostrError] - Event to_pow_event(Keys keys, u8 difficulty); - UnsignedEvent to_unsigned_event(PublicKey public_key); - UnsignedEvent to_unsigned_pow_event(PublicKey public_key, u8 difficulty); - - [Name=set_metadata] - constructor(Metadata metadata); - [Throws=NostrError, Name=add_recommended_relay] - constructor(string url); - [Throws=NostrError, Name=new_text_note] - constructor(string content, sequence tags); - [Throws=NostrError, Name=long_form_text_note] - constructor(string content, sequence tags); - [Name=repost] - constructor(EventId event_id, PublicKey public_key); - [Name=set_contact_list] - constructor(sequence list); - [Throws=NostrError, Name=new_encrypted_direct_msg] - constructor(Keys sender_keys, PublicKey receiver_pubkey, string content, EventId? reply_to); - [Name=delete] - constructor(sequence ids, optional string? reason = null); - [Name=new_reaction] - constructor(EventId event_id, PublicKey public_key, string content); - - [Name=new_channel] - constructor(Metadata metadata); - [Throws=NostrError, Name=set_channel_metadata] - constructor(string channel_id, string? relay_url, Metadata metadata); - [Throws=NostrError, Name=new_channel_msg] - constructor(string channel_id, string relay_url, string content); - [Name=hide_channel_msg] - constructor(EventId message_id, string? reason); - [Name=mute_channel_user] - constructor(PublicKey public_key, string? reason); - - [Throws=NostrError, Name=auth] - constructor(string challenge, string relay_url); - - [Name=report] - constructor(sequence tags, string content); - - [Name=new_zap_request] - constructor(ZapRequestData data); - [Name=new_zap_receipt] - constructor(string bolt11, string? preimage, Event zap_request); - - [Name=file_metadata] - constructor(string description, FileMetadata metadata); -}; - -interface Contact { - constructor(PublicKey pk, optional string? relay_url = null, optional string? alias = null); - string? alias(); - PublicKey public_key(); - string? relay_url(); -}; - -interface Metadata { - constructor(); - - [Throws=NostrError, Name=from_json] - constructor(string json); - string as_json(); - - [Self=ByArc] - Metadata set_name(string name); - [Self=ByArc] - Metadata set_display_name(string display_name); - [Self=ByArc] - Metadata set_about(string about); - [Throws=NostrError, Self=ByArc] - Metadata set_website(string website); - [Throws=NostrError, Self=ByArc] - Metadata set_picture(string picture); - [Throws=NostrError, Self=ByArc] - Metadata set_banner(string banner); - [Self=ByArc] - Metadata set_nip05(string nip05); - [Self=ByArc] - Metadata set_lud06(string lud06); - [Self=ByArc] - Metadata set_lud16(string lud16); - [Self=ByArc] - Metadata set_custom_field(string key, string value); - - string? get_name(); - string? get_display_name(); - string? get_about(); - string? get_website(); - string? get_picture(); - string? get_banner(); - string? get_nip05(); - string? get_lud06(); - string? get_lud16(); - string? get_custom_field(string key); -}; - -interface FileMetadata { - [Throws=NostrError] - constructor(string url, string mime_type, string hash); - [Self=ByArc] - FileMetadata aes_256_gcm(string key, string iv); - [Self=ByArc] - FileMetadata size(u64 size); - [Self=ByArc] - FileMetadata dimensions(ImageDimensions dim); - [Self=ByArc] - FileMetadata magnet(string magnet); - [Self=ByArc] - FileMetadata blurhash(string blurhash); -}; - -[Enum] -interface TagKind { - Known(TagKindKnown known); - Unknown(string unknown); -}; - -enum TagKindKnown { - "P", - "E", - "R", - "T", - "G", - "D", - "A", - "I", - "M", - "U", - "X", - "RelayUrl", - "Nonce", - "Delegation", - "ContentWarning", - "Expiration", - "Subject", - "Challenge", - "Title", - "Image", - "Thumb", - "Summary", - "PublishedAt", - "Description", - "Bolt11", - "Preimage", - "Relays", - "Amount", - "Lnurl", - "Name", - "Url", - "Aes256Gcm", - "Size", - "Dim", - "Magnet", - "Blurhash", - "Streaming", - "Recording", - "Starts", - "Ends", - "Status", - "CurrentParticipants", - "TotalParticipants", - "Method", - "Payload", - "Anon", - "Proxy", - "Emoji", - "Request", -}; - -[Enum] -interface TagEnum { - Unknown(TagKind kind, sequence data); - E(string event_id, string? relay_url, string? marker); - PubKey(string public_key, string? relay_url); - EventReport(string event_id, string report); - PubKeyReport(string public_key, string report); - PubKeyLiveEvent(string pk, string? relay_url, string marker, string? proof); - Reference(string reference); - RelayMetadata(string relay_url, string? rw); - Hashtag(string hashtag); - Geohash(string geohash); - Identifier(string identifier); - ExternalIdentity(string identity, string proof); - A(u64 kind, string public_key, string identifier, string? relay_url); - RelayUrl(string relay_url); - ContactList(string pk, string? relay_url, string? alias); - POW(string nonce, u8 difficulty); - Delegation(string delegator_pk, string conditions, string sig); - ContentWarning(string? reason); - Expiration(u64 timestamp); - Subject(string subject); - Challenge(string challenge); - Title(string title); - Image(string url, string? dimensions); - Thumb(string url, string? dimensions); - Summary(string summary); - Description(string desc); - Bolt11(string bolt11); - Preimage(string preimage); - Relays(sequence urls); - Amount(u64 millisats, string? bolt11); - Lnurl(string lnurl); - Name(string name); - PublishedAt(u64 timestamp); - Url(string url); - MimeType(string mime); - Aes256Gcm(string key, string iv); - Sha256(string hash); - Size(u64 size); - Dim(string dimensions); - Magnet(string uri); - Blurhash(string blurhash); - Streaming(string url); - Recording(string url); - Starts(u64 timestamp); - Ends(u64 timestamp); - LiveEventStatus(string status); - CurrentParticipants(u64 num); - TotalParticipants(u64 num); - AbsoluteURL(string url); - Method(string method); - Payload(string hash); - Anon(string? msg); - Proxy(string id, string protocol); - Emoji(string shortcode, string url); - Request(string event); - DataVendingMachineStatus(string status, string? extra_info); -}; - -interface Tag { - [Throws=NostrError, Name=parse] - constructor(sequence data); - [Throws=NostrError, Name=from_enum] - constructor(TagEnum e); - TagEnum as_enum(); - sequence as_vec(); - TagKind kind(); -}; \ No newline at end of file diff --git a/bindings/nostr-ffi/src/types/contact.rs b/bindings/nostr-ffi/src/types/contact.rs index 37a69fe21..f9ad8f606 100644 --- a/bindings/nostr-ffi/src/types/contact.rs +++ b/bindings/nostr-ffi/src/types/contact.rs @@ -5,9 +5,11 @@ use std::ops::Deref; use std::sync::Arc; use nostr::{Contact as ContactSdk, UncheckedUrl}; +use uniffi::Object; use crate::PublicKey; +#[derive(Object)] pub struct Contact { contact: ContactSdk, } @@ -19,12 +21,14 @@ impl Deref for Contact { } } +#[uniffi::export] impl Contact { - pub fn new(pk: Arc, relay_url: Option, alias: Option) -> Self { + #[uniffi::constructor] + pub fn new(pk: Arc, relay_url: Option, alias: Option) -> Arc { let relay_url = relay_url.map(|relay_url| UncheckedUrl::from(&relay_url)); - Self { - contact: ContactSdk::new(*pk.as_ref().deref(), relay_url, alias), - } + Arc::new(Self { + contact: ContactSdk::new(**pk, relay_url, alias), + }) } pub fn alias(&self) -> Option { diff --git a/bindings/nostr-ffi/src/types/image.rs b/bindings/nostr-ffi/src/types/image.rs index eebc886c2..f761d2c26 100644 --- a/bindings/nostr-ffi/src/types/image.rs +++ b/bindings/nostr-ffi/src/types/image.rs @@ -1,6 +1,11 @@ // Copyright (c) 2022-2023 Yuki Kishimoto // Distributed under the MIT software license +use std::sync::Arc; + +use uniffi::Object; + +#[derive(Object)] pub struct ImageDimensions { inner: nostr::ImageDimensions, } @@ -17,11 +22,13 @@ impl From<&ImageDimensions> for nostr::ImageDimensions { } } +#[uniffi::export] impl ImageDimensions { - pub fn new(width: u64, height: u64) -> Self { - Self { + #[uniffi::constructor] + pub fn new(width: u64, height: u64) -> Arc { + Arc::new(Self { inner: nostr::ImageDimensions { width, height }, - } + }) } pub fn width(&self) -> u64 { diff --git a/bindings/nostr-ffi/src/types/metadata.rs b/bindings/nostr-ffi/src/types/metadata.rs index 37338a301..b5614f320 100644 --- a/bindings/nostr-ffi/src/types/metadata.rs +++ b/bindings/nostr-ffi/src/types/metadata.rs @@ -4,152 +4,150 @@ use std::ops::Deref; use std::sync::Arc; -use nostr::{JsonUtil, Metadata as MetadataSdk, Url}; +use nostr::{JsonUtil, Url}; +use uniffi::Object; use crate::error::Result; use crate::helper::unwrap_or_clone_arc; -#[derive(Clone)] +#[derive(Clone, Object)] pub struct Metadata { - metadata: MetadataSdk, -} - -impl Default for Metadata { - fn default() -> Self { - Self::new() - } + inner: nostr::Metadata, } impl Deref for Metadata { - type Target = MetadataSdk; + type Target = nostr::Metadata; fn deref(&self) -> &Self::Target { - &self.metadata + &self.inner } } -impl From for Metadata { - fn from(metadata: MetadataSdk) -> Self { - Self { metadata } +impl From for Metadata { + fn from(inner: nostr::Metadata) -> Self { + Self { inner } } } +#[uniffi::export] impl Metadata { - pub fn new() -> Self { - Self { - metadata: MetadataSdk::new(), - } + #[uniffi::constructor] + pub fn new() -> Arc { + Arc::new(Self { + inner: nostr::Metadata::new(), + }) } - pub fn from_json(json: String) -> Result { - Ok(Self { - metadata: MetadataSdk::from_json(json)?, - }) + #[uniffi::constructor] + pub fn from_json(json: String) -> Result> { + Ok(Arc::new(Self { + inner: nostr::Metadata::from_json(json)?, + })) } pub fn as_json(&self) -> String { - self.metadata.as_json() + self.inner.as_json() } pub fn set_name(self: Arc, name: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.name(name); + builder.inner = builder.inner.name(name); Arc::new(builder) } pub fn get_name(&self) -> Option { - self.metadata.name.clone() + self.inner.name.clone() } pub fn set_display_name(self: Arc, display_name: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.display_name(display_name); + builder.inner = builder.inner.display_name(display_name); Arc::new(builder) } pub fn get_display_name(&self) -> Option { - self.metadata.display_name.clone() + self.inner.display_name.clone() } pub fn set_about(self: Arc, about: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.about(about); + builder.inner = builder.inner.about(about); Arc::new(builder) } pub fn get_about(&self) -> Option { - self.metadata.about.clone() + self.inner.about.clone() } pub fn set_website(self: Arc, website: String) -> Result> { let website = Url::parse(&website)?; let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.website(website); + builder.inner = builder.inner.website(website); Ok(Arc::new(builder)) } pub fn get_website(&self) -> Option { - self.metadata.website.clone() + self.inner.website.clone() } pub fn set_picture(self: Arc, picture: String) -> Result> { let picture = Url::parse(&picture)?; let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.picture(picture); + builder.inner = builder.inner.picture(picture); Ok(Arc::new(builder)) } pub fn get_picture(&self) -> Option { - self.metadata.picture.clone() + self.inner.picture.clone() } pub fn set_banner(self: Arc, banner: String) -> Result> { let banner = Url::parse(&banner)?; let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.banner(banner); + builder.inner = builder.inner.banner(banner); Ok(Arc::new(builder)) } pub fn get_banner(&self) -> Option { - self.metadata.banner.clone() + self.inner.banner.clone() } pub fn set_nip05(self: Arc, nip05: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.nip05(nip05); + builder.inner = builder.inner.nip05(nip05); Arc::new(builder) } pub fn get_nip05(&self) -> Option { - self.metadata.nip05.clone() + self.inner.nip05.clone() } pub fn set_lud06(self: Arc, lud06: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.lud06(lud06); + builder.inner = builder.inner.lud06(lud06); Arc::new(builder) } pub fn get_lud06(&self) -> Option { - self.metadata.lud06.clone() + self.inner.lud06.clone() } pub fn set_lud16(self: Arc, lud16: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.lud16(lud16); + builder.inner = builder.inner.lud16(lud16); Arc::new(builder) } pub fn get_lud16(&self) -> Option { - self.metadata.lud16.clone() + self.inner.lud16.clone() } pub fn set_custom_field(self: Arc, key: String, value: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); - builder.metadata = builder.metadata.custom_field(key, value); + builder.inner = builder.inner.custom_field(key, value); Arc::new(builder) } pub fn get_custom_field(&self, key: String) -> Option { - self.metadata.custom.get(&key).cloned() + self.inner.custom.get(&key).cloned() } } diff --git a/bindings/nostr-ffi/src/types/profile.rs b/bindings/nostr-ffi/src/types/profile.rs index 0b33d52d3..8efb79539 100644 --- a/bindings/nostr-ffi/src/types/profile.rs +++ b/bindings/nostr-ffi/src/types/profile.rs @@ -1,15 +1,16 @@ // Copyright (c) 2022-2023 Yuki Kishimoto // Distributed under the MIT software license -use std::ops::Deref; use std::sync::Arc; use nostr::nips::nip19::{FromBech32, ToBech32}; use nostr::nips::nip21::NostrURI; +use uniffi::Object; use crate::error::Result; use crate::PublicKey; +#[derive(Object)] pub struct Profile { inner: nostr::Profile, } @@ -20,24 +21,28 @@ impl From for Profile { } } +#[uniffi::export] impl Profile { /// New [`Profile`] - pub fn new(public_key: Arc, relays: Vec) -> Self { - Self { - inner: nostr::Profile::new(*public_key.as_ref().deref(), relays), - } + #[uniffi::constructor] + pub fn new(public_key: Arc, relays: Vec) -> Arc { + Arc::new(Self { + inner: nostr::Profile::new(**public_key, relays), + }) } - pub fn from_bech32(bech32: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_bech32(bech32: String) -> Result> { + Ok(Arc::new(Self { inner: nostr::Profile::from_bech32(bech32)?, - }) + })) } - pub fn from_nostr_uri(uri: String) -> Result { - Ok(Self { + #[uniffi::constructor] + pub fn from_nostr_uri(uri: String) -> Result> { + Ok(Arc::new(Self { inner: nostr::Profile::from_nostr_uri(uri)?, - }) + })) } pub fn to_bech32(&self) -> Result { diff --git a/bindings/nostr-ffi/src/types/time.rs b/bindings/nostr-ffi/src/types/time.rs index c15bfe0ef..52f1588a7 100644 --- a/bindings/nostr-ffi/src/types/time.rs +++ b/bindings/nostr-ffi/src/types/time.rs @@ -2,7 +2,11 @@ // Distributed under the MIT software license use std::ops::Deref; +use std::sync::Arc; +use uniffi::Object; + +#[derive(Object)] pub struct Timestamp { inner: nostr::Timestamp, } @@ -20,18 +24,21 @@ impl Deref for Timestamp { } } +#[uniffi::export] impl Timestamp { /// Get UNIX timestamp - pub fn now() -> Self { - Self { + #[uniffi::constructor] + pub fn now() -> Arc { + Arc::new(Self { inner: nostr::Timestamp::now(), - } + }) } - pub fn from_secs(secs: u64) -> Self { - Self { + #[uniffi::constructor] + pub fn from_secs(secs: u64) -> Arc { + Arc::new(Self { inner: nostr::Timestamp::from(secs), - } + }) } /// Get timestamp as [`u64`] diff --git a/bindings/nostr-ffi/src/util.rs b/bindings/nostr-ffi/src/util.rs index fcfd3ac63..19e4e5353 100644 --- a/bindings/nostr-ffi/src/util.rs +++ b/bindings/nostr-ffi/src/util.rs @@ -9,6 +9,7 @@ use nostr::util; use crate::error::Result; use crate::{PublicKey, SecretKey}; +#[uniffi::export] pub fn generate_shared_key( secret_key: Arc, public_key: Arc, diff --git a/bindings/nostr-ffi/uniffi.toml b/bindings/nostr-ffi/uniffi.toml index a9ff4c278..0a50299b9 100644 --- a/bindings/nostr-ffi/uniffi.toml +++ b/bindings/nostr-ffi/uniffi.toml @@ -1,10 +1,5 @@ [bindings.kotlin] package_name = "nostr" -cdylib_name = "nostr_ffi" [bindings.swift] -ffi_module_filename = "nostrFFI" -cdylib_name = "nostr_ffi" - -[bindings.python] -cdylib_name = "nostr_ffi" \ No newline at end of file +ffi_module_filename = "nostrFFI" \ No newline at end of file From d5b701425676ecac7a581877f75a661be8261ea1 Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Wed, 6 Dec 2023 17:30:06 +0100 Subject: [PATCH 2/8] ffi(nostr-sdk): use `uniffi` pro-macro instead of `UDL` --- Cargo.lock | 61 +- Cargo.toml | 2 +- bindings/nostr-sdk-ffi/Makefile | 21 +- .../bindings-android/lib/proguard-rules.pro | 2 + .../nostr-sdk-ffi/bindings-python/.gitignore | 1 + .../bindings-python/examples/bot.py | 6 +- .../examples/client-with-opts.py | 2 +- .../bindings-python/examples/client.py | 2 +- .../bindings-python/examples/database.py | 4 +- .../bindings-python/examples/metadata.py | 2 +- .../bindings-python/examples/nip94.py | 2 +- .../bindings-python/examples/relays.py | 6 +- .../bindings-python/src/nostr-sdk/__init__.py | 3 +- bindings/nostr-sdk-ffi/build.rs | 1 - bindings/nostr-sdk-ffi/src/client/builder.rs | 11 +- bindings/nostr-sdk-ffi/src/client/mod.rs | 18 +- bindings/nostr-sdk-ffi/src/client/options.rs | 11 +- bindings/nostr-sdk-ffi/src/database.rs | 10 +- bindings/nostr-sdk-ffi/src/error.rs | 3 +- bindings/nostr-sdk-ffi/src/lib.rs | 28 +- bindings/nostr-sdk-ffi/src/logger.rs | 3 + bindings/nostr-sdk-ffi/src/nostr_sdk.udl | 709 ------------------ bindings/nostr-sdk-ffi/src/relay.rs | 45 +- bindings/nostr-sdk-ffi/uniffi.toml | 5 - 24 files changed, 163 insertions(+), 795 deletions(-) delete mode 100644 bindings/nostr-sdk-ffi/src/nostr_sdk.udl diff --git a/Cargo.lock b/Cargo.lock index fa20ffeec..4f4fe4bea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2182,6 +2182,12 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "socket2" version = "0.4.10" @@ -2261,6 +2267,17 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.50" @@ -2516,6 +2533,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-normalization" version = "0.1.22" @@ -2525,11 +2548,16 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "uniffi" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e192430644d99babe02bede25316eee84fa154b1e5f8cfe99406c028b8c577" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "anyhow", "camino", @@ -2550,8 +2578,7 @@ dependencies = [ [[package]] name = "uniffi_bindgen" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c235355da41bc8347b2d5851e1060d4652dfbdc6d7d6ccddaabebe25e3c32a4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "anyhow", "askama", @@ -2565,6 +2592,7 @@ dependencies = [ "once_cell", "paste", "serde", + "textwrap", "toml", "uniffi_meta", "uniffi_testing", @@ -2574,8 +2602,7 @@ dependencies = [ [[package]] name = "uniffi_build" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81049ed7015a8a66b085aca3fb0c0011fdae4dd9ab8c38f5751f7861d60eb0f4" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "anyhow", "camino", @@ -2585,8 +2612,7 @@ dependencies = [ [[package]] name = "uniffi_checksum_derive" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce082833f0fcaf6fc221fbab26720440daf99381f5a71e89b6e23375eb6ea770" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "quote", "syn", @@ -2595,8 +2621,7 @@ dependencies = [ [[package]] name = "uniffi_core" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389bbe4d8334b3370c7cc998788d7a9619e0b61b58f1cbcd4a6a8606ab0a6f7d" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "anyhow", "bytes", @@ -2611,8 +2636,7 @@ dependencies = [ [[package]] name = "uniffi_macros" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34aa170f970d42d8fbe205f5794b83f72d6617835a73b91ed1869e1eba5dd06c" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "bincode", "camino", @@ -2630,8 +2654,7 @@ dependencies = [ [[package]] name = "uniffi_meta" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ef337c28a379ed6962eae0cb0824ab31202b21b8ae3bf6c2a706f5e7285f5f" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "anyhow", "bytes", @@ -2642,8 +2665,7 @@ dependencies = [ [[package]] name = "uniffi_testing" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f2e218997229b4ed6e08c1abc9e277dde817f68a633babd3ebbfc77e32db302" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "anyhow", "camino", @@ -2655,10 +2677,10 @@ dependencies = [ [[package]] name = "uniffi_udl" version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb29909e50256f32986ea3b3c32d2c49dece14ae4b3428c047913696ed200b2a" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "anyhow", + "textwrap", "uniffi_meta", "uniffi_testing", "weedle2", @@ -2886,8 +2908,7 @@ checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "weedle2" version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741" +source = "git+https://github.com/mozilla/uniffi-rs?rev=d380d164cfdba9e091c461baa6855f0a2294ac5b#d380d164cfdba9e091c461baa6855f0a2294ac5b" dependencies = [ "nom", ] diff --git a/Cargo.toml b/Cargo.toml index ebbbc8d91..38e3db845 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ thiserror = "1.0" tokio = { version = "1.32", default-features = false } tracing = { version = "0.1", default-features = false } tracing-subscriber = "0.3" -uniffi = "0.25" +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "d380d164cfdba9e091c461baa6855f0a2294ac5b" } url-fork = { version = "3.0", default-features = false } [profile.release] diff --git a/bindings/nostr-sdk-ffi/Makefile b/bindings/nostr-sdk-ffi/Makefile index 3fe8851f7..dbaec9c2f 100644 --- a/bindings/nostr-sdk-ffi/Makefile +++ b/bindings/nostr-sdk-ffi/Makefile @@ -24,11 +24,14 @@ sdk-root: exit 1 ; \ fi +kotlin-clean: + find ./ffi/kotlin/jniLibs -name libnostr_sdk_ffi.so -type f -delete + kotlin: android find ./ffi/kotlin/jniLibs -name libnostr_ffi.so -type f -delete - cargo run -p uniffi-bindgen generate src/nostr_sdk.udl --language kotlin --no-format -o ffi/kotlin + cargo run -p uniffi-bindgen generate --library ../../target/x86_64-linux-android/release/libnostr_sdk_ffi.so --language kotlin --no-format -o ffi/kotlin -android: aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android +android: kotlin-clean aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android aarch64-linux-android: $(SOURCES) ndk-home cargo ndk -t aarch64-linux-android -o ffi/kotlin/jniLibs build --release @@ -46,7 +49,9 @@ bindings-android: sdk-root kotlin rm -rf bindings-android/lib/src/main/jniLibs rm -rf bindings-android/lib/src/main/kotlin cp -r ffi/kotlin/jniLibs bindings-android/lib/src/main - cp -r ffi/kotlin/nostr_sdk bindings-android/lib/src/main/kotlin/ + mkdir -p bindings-android/lib/src/main/kotlin/ + cp ffi/kotlin/nostr/nostr.kt bindings-android/lib/src/main/kotlin/ + cp ffi/kotlin/nostr_sdk/nostr_sdk.kt bindings-android/lib/src/main/kotlin/ cd bindings-android && ./gradlew assemble mkdir -p ffi/android cp bindings-android/lib/build/outputs/aar/lib-release.aar ffi/android @@ -71,18 +76,18 @@ darwin-universal: $(SOURCES) lipo -create -output ../../target/darwin-universal/release/libnostr_sdk_ffi.a ../../target/aarch64-apple-darwin/release/libnostr_sdk_ffi.a ../../target/x86_64-apple-darwin/release/libnostr_sdk_ffi.a swift-ios: ios-universal - cargo run -p uniffi-bindgen generate src/nostr_sdk.udl -l swift -o ffi/swift-ios + cargo run -p uniffi-bindgen generate --library ../../target/aarch64-apple-ios/release/libnostr_sdk_ffi.a -l swift -o ffi/swift-ios cp ../../target/ios-universal/release/libnostr_sdk_ffi.a ffi/swift-ios cd ffi/swift-ios && "swiftc" "-emit-module" "-module-name" "nostr_sdk_ffi" "-Xcc" "-fmodule-map-file=$(CURRENT_DIR)/ffi/swift-ios/nostr_sdkFFI.modulemap" "-I" "." "-L" "." "-lnostr_sdk_ffi" nostr_sdk.swift swift-darwin: darwin-universal - cargo run -p uniffi-bindgen generate src/nostr_sdk.udl -l swift -o ffi/swift-darwin + cargo run -p uniffi-bindgen generate --library ../../target/aarch64-apple-darwin/release/libnostr_sdk_ffi.a -l swift -o ffi/swift-darwin cp ../../target/darwin-universal/release/libnostr_sdk_ffi.dylib ffi/swift-darwin cd ffi/swift-darwin && "swiftc" "-emit-module" "-module-name" "nostr_sdk_ffi" "-Xcc" "-fmodule-map-file=$(CURRENT_DIR)/ffi/swift-darwin/nostr_sdkFFI.modulemap" "-I" "." "-L" "." "-lnostr_sdk_ffi" nostr_sdk.swift bindings-swift: ios-universal darwin-universal mkdir -p bindings-swift/Sources/NostrSDK - cargo run -p uniffi-bindgen generate src/nostr_sdk.udl --no-format --language swift --out-dir bindings-swift/Sources/NostrSDK + cargo run -p uniffi-bindgen generate --library ../../target/aarch64-apple-ios/release/libnostr_sdk_ffi.a --no-format --language swift --out-dir bindings-swift/Sources/NostrSDK mv bindings-swift/Sources/NostrSDK/nostr_sdk.swift bindings-swift/Sources/NostrSDK/NostrSDK.swift cp bindings-swift/Sources/NostrSDK/nostr_sdkFFI.h bindings-swift/nostr_sdkFFI.xcframework/ios-arm64/nostr_sdkFFI.framework/Headers cp bindings-swift/Sources/NostrSDK/nostr_sdkFFI.h bindings-swift/nostr_sdkFFI.xcframework/ios-arm64_x86_64-simulator/nostr_sdkFFI.framework/Headers @@ -97,7 +102,7 @@ python: rm -rf bindings-python/dist pip install -r bindings-python/requirements.txt cargo build --release - cargo run -p uniffi-bindgen generate src/nostr_sdk.udl --language python --no-format -o bindings-python/src/nostr-sdk/ + cargo run -p uniffi-bindgen generate --library ../../target/release/libnostr_sdk_ffi.so --language python --no-format -o bindings-python/src/nostr-sdk/ cp ../../target/release/libnostr_sdk_ffi.so bindings-python/src/nostr-sdk/ | true cp ../../target/release/libnostr_sdk_ffi.dylib bindings-python/src/nostr-sdk/ | true cd bindings-python && python setup.py --verbose bdist_wheel @@ -106,7 +111,7 @@ python: python-win: pip install -r bindings-python\requirements.txt cargo build --release - cargo run -p uniffi-bindgen generate src\nostr_sdk.udl --language python --no-format -o bindings-python\src\nostr-sdk + cargo run -p uniffi-bindgen generate --library ..\..\target\release\nostr_sdk_ffi.dll --language python --no-format -o bindings-python\src\nostr-sdk copy ..\..\target\release\nostr_sdk_ffi.dll bindings-python\src\nostr-sdk del /F /Q bindings-python\dist\* cd bindings-python && python setup.py --verbose bdist_wheel diff --git a/bindings/nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro b/bindings/nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro index 3048d83ab..138837183 100644 --- a/bindings/nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro +++ b/bindings/nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro @@ -24,7 +24,9 @@ -dontwarn java.awt.* -keep class com.sun.jna.* { *; } -keep class rust.nostr.sdk.* { *; } +-keep class nostr.** { *; } -keep class nostr_sdk.** { *; } -keepclassmembers class * extends rust.nostr.sdk.* { public *; } +-keepclassmembers class * extends nostr.** { public *; } -keepclassmembers class * extends nostr_sdk.** { public *; } -keepclassmembers class * extends com.sun.jna.* { public *; } diff --git a/bindings/nostr-sdk-ffi/bindings-python/.gitignore b/bindings/nostr-sdk-ffi/bindings-python/.gitignore index 2711ef622..cb773e3d4 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/.gitignore +++ b/bindings/nostr-sdk-ffi/bindings-python/.gitignore @@ -8,6 +8,7 @@ libnostr_sdk_ffi.dylib *.swp +src/nostr-sdk/nostr.py src/nostr-sdk/nostr_sdk.py src/nostr-sdk/*.so *.whl diff --git a/bindings/nostr-sdk-ffi/bindings-python/examples/bot.py b/bindings/nostr-sdk-ffi/bindings-python/examples/bot.py index 21ccce2a0..6251361ce 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/examples/bot.py +++ b/bindings/nostr-sdk-ffi/bindings-python/examples/bot.py @@ -14,9 +14,9 @@ client = Client(keys) -client.add_relay("wss://relay.damus.io") -client.add_relay("wss://nostr.mom") -client.add_relay("wss://nostr.oxtr.dev") +client.add_relay("wss://relay.damus.io", None) +client.add_relay("wss://nostr.mom", None) +client.add_relay("wss://nostr.oxtr.dev", None) client.connect() filter = Filter().pubkey(pk).kind(4).since(Timestamp.now()) diff --git a/bindings/nostr-sdk-ffi/bindings-python/examples/client-with-opts.py b/bindings/nostr-sdk-ffi/bindings-python/examples/client-with-opts.py index 87d48187c..0a30ecb9a 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/examples/client-with-opts.py +++ b/bindings/nostr-sdk-ffi/bindings-python/examples/client-with-opts.py @@ -8,7 +8,7 @@ opts = Options().send_timeout(timedelta(seconds=10)) client = Client.with_opts(keys, opts) -client.add_relay("wss://relay.damus.io") +client.add_relay("wss://relay.damus.io", None) client.connect() event = EventBuilder.new_text_note("Hello from Rust Nostr Python bindings!", []).to_event(keys) diff --git a/bindings/nostr-sdk-ffi/bindings-python/examples/client.py b/bindings/nostr-sdk-ffi/bindings-python/examples/client.py index 38c9a5c79..ea414b2f0 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/examples/client.py +++ b/bindings/nostr-sdk-ffi/bindings-python/examples/client.py @@ -7,7 +7,7 @@ client = Client(keys) -client.add_relay("wss://relay.damus.io") +client.add_relay("wss://relay.damus.io", None) client.connect() print("Mining a POW text note...") diff --git a/bindings/nostr-sdk-ffi/bindings-python/examples/database.py b/bindings/nostr-sdk-ffi/bindings-python/examples/database.py index eb7ebba43..cd0d18f10 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/examples/database.py +++ b/bindings/nostr-sdk-ffi/bindings-python/examples/database.py @@ -8,8 +8,8 @@ database = NostrDatabase.sqlite("nostr.db") client = ClientBuilder(keys).database(database).build() -client.add_relay("wss://relay.damus.io") -client.add_relay("wss://atl.purplerelay.com") +client.add_relay("wss://relay.damus.io", None) +client.add_relay("wss://atl.purplerelay.com", None) client.connect() # Negentropy reconciliation diff --git a/bindings/nostr-sdk-ffi/bindings-python/examples/metadata.py b/bindings/nostr-sdk-ffi/bindings-python/examples/metadata.py index 3f02419df..89f961b41 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/examples/metadata.py +++ b/bindings/nostr-sdk-ffi/bindings-python/examples/metadata.py @@ -5,7 +5,7 @@ client = Client(keys) -client.add_relay("wss://relay.damus.io") +client.add_relay("wss://relay.damus.io", None) client.connect() # Set metadata diff --git a/bindings/nostr-sdk-ffi/bindings-python/examples/nip94.py b/bindings/nostr-sdk-ffi/bindings-python/examples/nip94.py index 3ddebbb6d..783a69132 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/examples/nip94.py +++ b/bindings/nostr-sdk-ffi/bindings-python/examples/nip94.py @@ -5,7 +5,7 @@ client = Client(keys) -client.add_relay("wss://relay.damus.io") +client.add_relay("wss://relay.damus.io", None) client.add_relay("ws://jgqaglhautb4k6e6i2g34jakxiemqp6z4wynlirltuukgkft2xuglmqd.onion", "127.0.0.1:9050") client.connect() diff --git a/bindings/nostr-sdk-ffi/bindings-python/examples/relays.py b/bindings/nostr-sdk-ffi/bindings-python/examples/relays.py index 8ddf8e6ac..8fd2d629b 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/examples/relays.py +++ b/bindings/nostr-sdk-ffi/bindings-python/examples/relays.py @@ -4,9 +4,9 @@ keys = Keys.generate() client = Client(keys) -client.add_relay("wss://relay.damus.io") -client.add_relay("wss://nostr.wine") -client.add_relay("wss://relay.nostr.info") +client.add_relay("wss://relay.damus.io", None) +client.add_relay("wss://nostr.wine", None) +client.add_relay("wss://relay.nostr.info", None) client.connect() while True: diff --git a/bindings/nostr-sdk-ffi/bindings-python/src/nostr-sdk/__init__.py b/bindings/nostr-sdk-ffi/bindings-python/src/nostr-sdk/__init__.py index 5085043a4..cfb7c0aa7 100644 --- a/bindings/nostr-sdk-ffi/bindings-python/src/nostr-sdk/__init__.py +++ b/bindings/nostr-sdk-ffi/bindings-python/src/nostr-sdk/__init__.py @@ -1 +1,2 @@ -from nostr_sdk.nostr_sdk import * +from nostr_sdk.nostr import * +from nostr_sdk.nostr_sdk import * \ No newline at end of file diff --git a/bindings/nostr-sdk-ffi/build.rs b/bindings/nostr-sdk-ffi/build.rs index f8dd52519..056073af1 100644 --- a/bindings/nostr-sdk-ffi/build.rs +++ b/bindings/nostr-sdk-ffi/build.rs @@ -8,7 +8,6 @@ const DEFAULT_CLANG_VERSION: &str = "14.0.7"; fn main() { setup_x86_64_android_workaround(); - uniffi::generate_scaffolding("./src/nostr_sdk.udl").expect("Building the UDL file failed"); } /// Adds a temporary workaround for an issue with the Rust compiler and Android diff --git a/bindings/nostr-sdk-ffi/src/client/builder.rs b/bindings/nostr-sdk-ffi/src/client/builder.rs index ee34808ee..d23c1a1b8 100644 --- a/bindings/nostr-sdk-ffi/src/client/builder.rs +++ b/bindings/nostr-sdk-ffi/src/client/builder.rs @@ -7,11 +7,12 @@ use std::sync::Arc; use nostr_ffi::helper::unwrap_or_clone_arc; use nostr_ffi::Keys; use nostr_sdk::database::DynNostrDatabase; +use uniffi::Object; use super::{Client, ClientSdk, Options}; use crate::database::NostrDatabase; -#[derive(Clone)] +#[derive(Clone, Object)] pub struct ClientBuilder { inner: nostr_sdk::ClientBuilder, } @@ -22,12 +23,14 @@ impl From for ClientBuilder { } } +#[uniffi::export] impl ClientBuilder { /// New client builder - pub fn new(keys: Arc) -> Self { - Self { + #[uniffi::constructor] + pub fn new(keys: Arc) -> Arc { + Arc::new(Self { inner: nostr_sdk::ClientBuilder::new(keys.as_ref().deref()), - } + }) } pub fn database(self: Arc, database: Arc) -> Arc { diff --git a/bindings/nostr-sdk-ffi/src/client/mod.rs b/bindings/nostr-sdk-ffi/src/client/mod.rs index aab2c2e15..4d5c03443 100644 --- a/bindings/nostr-sdk-ffi/src/client/mod.rs +++ b/bindings/nostr-sdk-ffi/src/client/mod.rs @@ -14,6 +14,7 @@ use nostr_ffi::{ use nostr_sdk::client::blocking::Client as ClientSdk; use nostr_sdk::relay::RelayPoolNotification as RelayPoolNotificationSdk; use nostr_sdk::{NegentropyOptions, Options as OptionsSdk}; +use uniffi::Object; mod builder; mod options; @@ -23,6 +24,7 @@ pub use self::options::Options; use crate::error::Result; use crate::{NostrDatabase, Relay}; +#[derive(Object)] pub struct Client { inner: ClientSdk, } @@ -33,19 +35,22 @@ impl From for Client { } } +#[uniffi::export] impl Client { - pub fn new(keys: Arc) -> Self { + #[uniffi::constructor] + pub fn new(keys: Arc) -> Arc { let opts: OptionsSdk = OptionsSdk::new().shutdown_on_drop(true); - Self { + Arc::new(Self { inner: ClientSdk::with_opts(keys.as_ref().deref(), opts), - } + }) } - pub fn with_opts(keys: Arc, opts: Arc) -> Self { + #[uniffi::constructor] + pub fn with_opts(keys: Arc, opts: Arc) -> Arc { let opts: OptionsSdk = opts.as_ref().deref().clone().shutdown_on_drop(true); - Self { + Arc::new(Self { inner: ClientSdk::with_opts(keys.as_ref().deref(), opts), - } + }) } // TODO: add with_remote_signer @@ -266,6 +271,7 @@ impl Client { } } +#[uniffi::export(callback_interface)] pub trait HandleNotification: Send + Sync + Debug { fn handle_msg(&self, relay_url: String, msg: RelayMessage); fn handle(&self, relay_url: String, event: Arc); diff --git a/bindings/nostr-sdk-ffi/src/client/options.rs b/bindings/nostr-sdk-ffi/src/client/options.rs index b0654739a..c0d8e7519 100644 --- a/bindings/nostr-sdk-ffi/src/client/options.rs +++ b/bindings/nostr-sdk-ffi/src/client/options.rs @@ -6,8 +6,9 @@ use std::sync::Arc; use std::time::Duration; use nostr_ffi::helper::unwrap_or_clone_arc; +use uniffi::Object; -#[derive(Clone)] +#[derive(Clone, Object)] pub struct Options { inner: nostr_sdk::Options, } @@ -25,11 +26,13 @@ impl From for Options { } } +#[uniffi::export] impl Options { - pub fn new() -> Self { - Self { + #[uniffi::constructor] + pub fn new() -> Arc { + Arc::new(Self { inner: nostr_sdk::Options::new(), - } + }) } pub fn wait_for_connection(self: Arc, wait: bool) -> Arc { diff --git a/bindings/nostr-sdk-ffi/src/database.rs b/bindings/nostr-sdk-ffi/src/database.rs index 54659f878..6dcc8e865 100644 --- a/bindings/nostr-sdk-ffi/src/database.rs +++ b/bindings/nostr-sdk-ffi/src/database.rs @@ -7,9 +7,11 @@ use std::sync::Arc; use nostr_ffi::{Event, EventId, Filter, Metadata, PublicKey}; use nostr_sdk::database::{DynNostrDatabase, IntoNostrDatabase, NostrDatabaseExt}; use nostr_sdk::{block_on, SQLiteDatabase}; +use uniffi::Object; use crate::error::Result; +#[derive(Object)] pub struct NostrDatabase { inner: Arc, } @@ -26,13 +28,15 @@ impl From<&NostrDatabase> for Arc { } } +#[uniffi::export] impl NostrDatabase { - pub fn sqlite(path: String) -> Result { + #[uniffi::constructor] + pub fn sqlite(path: String) -> Result> { block_on(async move { let db = Arc::new(SQLiteDatabase::open(path).await?); - Ok(Self { + Ok(Arc::new(Self { inner: db.into_nostr_database(), - }) + })) }) } diff --git a/bindings/nostr-sdk-ffi/src/error.rs b/bindings/nostr-sdk-ffi/src/error.rs index 9ff2fbe0e..9ff420bd6 100644 --- a/bindings/nostr-sdk-ffi/src/error.rs +++ b/bindings/nostr-sdk-ffi/src/error.rs @@ -5,10 +5,11 @@ use std::fmt; use std::net::AddrParseError; use tracing::subscriber::SetGlobalDefaultError; +use uniffi::Error; pub type Result = std::result::Result; -#[derive(Debug)] +#[derive(Debug, Error)] pub enum NostrSdkError { Generic { err: String }, } diff --git a/bindings/nostr-sdk-ffi/src/lib.rs b/bindings/nostr-sdk-ffi/src/lib.rs index bfb67c8c5..0906e83d9 100644 --- a/bindings/nostr-sdk-ffi/src/lib.rs +++ b/bindings/nostr-sdk-ffi/src/lib.rs @@ -3,6 +3,14 @@ #![allow(clippy::new_without_default)] +pub use nostr_ffi::{ + generate_shared_key, get_nip05_profile, git_hash_version, nip04_decrypt, nip04_encrypt, + verify_nip05, Alphabet, ClientMessage, Contact, Event, EventBuilder, EventId, FileMetadata, + Filter, ImageDimensions, Keys, Metadata, NostrConnectURI, NostrError, Profile, PublicKey, + RelayInformationDocument, RelayMessage, SecretKey, Tag, TagEnum, TagKind, TagKindKnown, + Timestamp, UnsignedEvent, ZapRequestData, +}; + mod client; mod database; mod error; @@ -14,24 +22,10 @@ trait FromResult: Sized { fn from_result(_: T) -> error::Result; } -// External -pub use nostr_ffi::{ - generate_shared_key, get_nip05_profile, git_hash_version, nip04_decrypt, nip04_encrypt, - verify_nip05, ClientMessage, Contact, Event, EventBuilder, EventId, FileMetadata, Filter, - ImageDimensions, Keys, Metadata, NostrConnectURI, NostrError, Profile, PublicKey, - RelayInformationDocument, RelayMessage, SecretKey, Tag, TagEnum, TagKind, TagKindKnown, - Timestamp, UnsignedEvent, ZapRequestData, -}; -pub use nostr_sdk::{Alphabet, RelayStatus}; - -// Namespace -pub use crate::logger::{init_logger, LogLevel}; - -// Nostr SDK pub use crate::client::{Client, ClientBuilder, HandleNotification, Options}; pub use crate::database::NostrDatabase; pub use crate::error::NostrSdkError; -pub use crate::relay::{ActiveSubscription, Relay, RelayConnectionStats}; +pub use crate::logger::{init_logger, LogLevel}; +pub use crate::relay::{ActiveSubscription, Relay, RelayConnectionStats, RelayStatus}; -// UDL -uniffi::include_scaffolding!("nostr_sdk"); +uniffi::setup_scaffolding!("nostr_sdk"); diff --git a/bindings/nostr-sdk-ffi/src/logger.rs b/bindings/nostr-sdk-ffi/src/logger.rs index c2339cff1..6ea23ae9e 100644 --- a/bindings/nostr-sdk-ffi/src/logger.rs +++ b/bindings/nostr-sdk-ffi/src/logger.rs @@ -2,9 +2,11 @@ // Distributed under the MIT software license use tracing::Level; +use uniffi::Enum; use crate::error::Result; +#[derive(Enum)] pub enum LogLevel { Error, Warn, @@ -25,6 +27,7 @@ impl From for Level { } } +#[uniffi::export] pub fn init_logger(level: LogLevel) -> Result<()> { let level: Level = level.into(); let subscriber = tracing_subscriber::FmtSubscriber::builder() diff --git a/bindings/nostr-sdk-ffi/src/nostr_sdk.udl b/bindings/nostr-sdk-ffi/src/nostr_sdk.udl deleted file mode 100644 index 2f4fdee34..000000000 --- a/bindings/nostr-sdk-ffi/src/nostr_sdk.udl +++ /dev/null @@ -1,709 +0,0 @@ -// Copyright (c) 2022-2023 Yuki Kishimoto -// Distributed under the MIT software license - -namespace nostr_sdk { - string git_hash_version(); - - // Nostr - [Throws=NostrError] - sequence generate_shared_key(SecretKey secret_key, PublicKey public_key); - - [Throws=NostrError] - string nip04_encrypt(SecretKey secret_key, PublicKey public_key, string content); - [Throws=NostrError] - string nip04_decrypt(SecretKey secret_key, PublicKey public_key, string encrypted_content); - - [Throws=NostrError] - void verify_nip05(PublicKey public_key, string nip05, string? proxy); - [Throws=NostrError] - Profile get_nip05_profile(string nip05, string? proxy); - - // Nostr SDK - [Throws=NostrSdkError] - void init_logger(LogLevel level); -}; - -[Error] -interface NostrSdkError { - Generic(string err); -}; - -enum LogLevel { - "Error", - "Warn", - "Info", - "Debug", - "Trace", -}; - -// NOSTR - -[Error] -interface NostrError { - Generic(string err); -}; - -interface RelayInformationDocument { - [Throws=NostrError, Name=get] - constructor(string url, string? proxy); - string? name(); - string? description(); - string? pubkey(); - string? contact(); - sequence? supported_nips(); - string? software(); - string? version(); -}; - -interface NostrConnectURI { - [Throws=NostrError, Name=from_string] - constructor(string uri); - PublicKey public_key(); - string relay_url(); - string name(); - string? url(); - string? description(); -}; - -interface Profile { - constructor(PublicKey public_key, sequence relays); - [Throws=NostrError, Name=from_bech32] - constructor(string bech32); - [Throws=NostrError, Name=from_nostr_uri] - constructor(string uri); - [Throws=NostrError] - string to_bech32(); - [Throws=NostrError] - string to_nostr_uri(); - PublicKey public_key(); - sequence relays(); -}; - -interface ImageDimensions { - constructor(u64 width, u64 height); - u64 width(); - u64 height(); -}; - -interface Timestamp { - [Name=now] - constructor(); - [Name=from_secs] - constructor(u64 secs); - u64 as_secs(); - string to_human_datetime(); -}; - -interface SecretKey { - [Throws=NostrError, Name=from_hex] - constructor(string hex); - [Throws=NostrError, Name=from_bech32] - constructor(string sk); - [Throws=NostrError, Name=from_bytes] - constructor(sequence sk); - string to_hex(); - [Throws=NostrError] - string to_bech32(); -}; - -interface PublicKey { - [Throws=NostrError, Name=from_hex] - constructor(string hex); - [Throws=NostrError, Name=from_bech32] - constructor(string pk); - [Throws=NostrError, Name=from_bytes] - constructor(sequence pk); - [Throws=NostrError, Name=from_nostr_uri] - constructor(string uri); - string to_hex(); - [Throws=NostrError] - string to_bech32(); - [Throws=NostrError] - string to_nostr_uri(); -}; - -interface Keys { - constructor(SecretKey sk); - [Name=from_public_key] - constructor(PublicKey pk); - [Throws=NostrError, Name=from_sk_str] - constructor(string sk); - [Throws=NostrError, Name=from_pk_str] - constructor(string pk); - [Name=generate] - constructor(); - [Throws=NostrError, Name=vanity] - constructor(sequence prefixes, boolean bech32, u8 num_cores); - [Throws=NostrError, Name=from_mnemonic] - constructor(string mnemonic, optional string? passphrase = null); - PublicKey public_key(); - [Throws=NostrError] - SecretKey secret_key(); -}; - -[Enum] -interface ClientMessage { - Ev(string event); - Req(string subscription_id, sequence filters); - Count(string subscription_id, sequence filters); - Close(string subscription_id); - Auth(string event); -}; - -[Enum] -interface RelayMessage { - Ev(string subscription_id, string event); - Notice(string message); - EndOfStoredEvents(string subscription_id); - Ok(string event_id, boolean status, string message); - Auth(string challenge); - Count(string subscription_id, u64 count); - NegMsg(string subscription_id, string message); - NegErr(string subscription_id, string code); -}; - -interface ZapRequestData { - constructor(PublicKey public_key, sequence relays); - [Self=ByArc] - ZapRequestData amount(u64 amount); - [Self=ByArc] - ZapRequestData lnurl(string lnurl); - [Self=ByArc] - ZapRequestData event_id(EventId event_id); -}; - -enum Alphabet { - "A", - "B", - "C", - "D", - "E", - "F", - "G", - "H", - "I", - "J", - "K", - "L", - "M", - "N", - "O", - "P", - "Q", - "R", - "S", - "T", - "U", - "V", - "W", - "X", - "Y", - "Z", -}; - -interface Filter { - constructor(); - [Self=ByArc] - Filter id(EventId id); - [Self=ByArc] - Filter ids(sequence ids); - [Self=ByArc] - Filter author(PublicKey author); - [Self=ByArc] - Filter authors(sequence authors); - [Self=ByArc] - Filter kind(u64 kind); - [Self=ByArc] - Filter kinds(sequence kinds); - [Self=ByArc] - Filter event(EventId event_id); - [Self=ByArc] - Filter events(sequence ids); - [Self=ByArc] - Filter pubkey(PublicKey pubkey); - [Self=ByArc] - Filter pubkeys(sequence pubkeys); - [Self=ByArc] - Filter identifier(string identifier); - [Self=ByArc] - Filter search(string text); - [Self=ByArc] - Filter since(Timestamp timestamp); - [Self=ByArc] - Filter until(Timestamp timestamp); - [Self=ByArc] - Filter limit(u64 limit); - [Self=ByArc] - Filter custom_tag(Alphabet tag, sequence content); - boolean match_event(Event event); - [Throws=NostrError, Name=from_json] - constructor(string json); - string as_json(); -}; - -interface EventId { - [Throws=NostrError] - constructor(PublicKey pubkey, Timestamp created_at, u64 kind, sequence> tags, string content); - [Throws=NostrError, Name=from_bytes] - constructor(sequence bytes); - [Throws=NostrError, Name=from_hex] - constructor(string hex); - [Throws=NostrError, Name=from_bech32] - constructor(string id); - [Throws=NostrError, Name=from_nostr_uri] - constructor(string uri); - sequence as_bytes(); - string to_hex(); - [Throws=NostrError] - string to_bech32(); - [Throws=NostrError] - string to_nostr_uri(); -}; - -interface UnsignedEvent { - EventId id(); - PublicKey pubkey(); - Timestamp created_at(); - u64 kind(); - sequence tags(); - string content(); - [Throws=NostrError] - Event sign(Keys keys); - [Throws=NostrError] - Event add_signature(string sig); - [Throws=NostrError, Name=from_json] - constructor(string json); - string as_json(); -}; - -interface Event { - EventId id(); - PublicKey pubkey(); - Timestamp created_at(); - u64 kind(); - sequence tags(); - string content(); - string signature(); - boolean verify(); - [Throws=NostrError, Name=from_json] - constructor(string json); - string as_json(); -}; - -interface EventBuilder { - [Throws=NostrError] - constructor(u64 kind, string content, sequence tags); - [Throws=NostrError] - Event to_event(Keys keys); - [Throws=NostrError] - Event to_pow_event(Keys keys, u8 difficulty); - UnsignedEvent to_unsigned_event(PublicKey public_key); - UnsignedEvent to_unsigned_pow_event(PublicKey public_key, u8 difficulty); - - [Name=set_metadata] - constructor(Metadata metadata); - [Throws=NostrError, Name=add_recommended_relay] - constructor(string url); - [Throws=NostrError, Name=new_text_note] - constructor(string content, sequence tags); - [Throws=NostrError, Name=long_form_text_note] - constructor(string content, sequence tags); - [Name=repost] - constructor(EventId event_id, PublicKey public_key); - [Name=set_contact_list] - constructor(sequence list); - [Throws=NostrError, Name=new_encrypted_direct_msg] - constructor(Keys sender_keys, PublicKey receiver_pubkey, string content, EventId? reply_to); - [Name=delete] - constructor(sequence ids, optional string? reason = null); - [Name=new_reaction] - constructor(EventId event_id, PublicKey public_key, string content); - - [Name=new_channel] - constructor(Metadata metadata); - [Throws=NostrError, Name=set_channel_metadata] - constructor(string channel_id, string? relay_url, Metadata metadata); - [Throws=NostrError, Name=new_channel_msg] - constructor(string channel_id, string relay_url, string content); - [Name=hide_channel_msg] - constructor(EventId message_id, string? reason); - [Name=mute_channel_user] - constructor(PublicKey public_key, string? reason); - - [Throws=NostrError, Name=auth] - constructor(string challenge, string relay_url); - - [Name=report] - constructor(sequence tags, string content); - - [Name=new_zap_request] - constructor(ZapRequestData data); - [Name=new_zap_receipt] - constructor(string bolt11, string? preimage, Event zap_request); - - [Name=file_metadata] - constructor(string description, FileMetadata metadata); -}; - -interface Contact { - constructor(PublicKey pk, optional string? relay_url = null, optional string? alias = null); - string? alias(); - PublicKey public_key(); - string? relay_url(); -}; - -interface Metadata { - constructor(); - - [Throws=NostrError, Name=from_json] - constructor(string json); - string as_json(); - - [Self=ByArc] - Metadata set_name(string name); - [Self=ByArc] - Metadata set_display_name(string display_name); - [Self=ByArc] - Metadata set_about(string about); - [Throws=NostrError, Self=ByArc] - Metadata set_website(string website); - [Throws=NostrError, Self=ByArc] - Metadata set_picture(string picture); - [Throws=NostrError, Self=ByArc] - Metadata set_banner(string banner); - [Self=ByArc] - Metadata set_nip05(string nip05); - [Self=ByArc] - Metadata set_lud06(string lud06); - [Self=ByArc] - Metadata set_lud16(string lud16); - [Self=ByArc] - Metadata set_custom_field(string key, string value); - - string? get_name(); - string? get_display_name(); - string? get_about(); - string? get_website(); - string? get_picture(); - string? get_banner(); - string? get_nip05(); - string? get_lud06(); - string? get_lud16(); - string? get_custom_field(string key); -}; - -interface FileMetadata { - [Throws=NostrError] - constructor(string url, string mime_type, string hash); - [Self=ByArc] - FileMetadata aes_256_gcm(string key, string iv); - [Self=ByArc] - FileMetadata size(u64 size); - [Self=ByArc] - FileMetadata dimensions(ImageDimensions dim); - [Self=ByArc] - FileMetadata magnet(string magnet); - [Self=ByArc] - FileMetadata blurhash(string blurhash); -}; - -[Enum] -interface TagKind { - Known(TagKindKnown known); - Unknown(string unknown); -}; - -enum TagKindKnown { - "P", - "E", - "R", - "T", - "G", - "D", - "A", - "I", - "M", - "U", - "X", - "RelayUrl", - "Nonce", - "Delegation", - "ContentWarning", - "Expiration", - "Subject", - "Challenge", - "Title", - "Image", - "Thumb", - "Summary", - "PublishedAt", - "Description", - "Bolt11", - "Preimage", - "Relays", - "Amount", - "Lnurl", - "Name", - "Url", - "Aes256Gcm", - "Size", - "Dim", - "Magnet", - "Blurhash", - "Streaming", - "Recording", - "Starts", - "Ends", - "Status", - "CurrentParticipants", - "TotalParticipants", - "Method", - "Payload", - "Anon", - "Proxy", - "Emoji", - "Request", -}; - -[Enum] -interface TagEnum { - Unknown(TagKind kind, sequence data); - E(string event_id, string? relay_url, string? marker); - PubKey(string public_key, string? relay_url); - EventReport(string event_id, string report); - PubKeyReport(string public_key, string report); - PubKeyLiveEvent(string pk, string? relay_url, string marker, string? proof); - Reference(string reference); - RelayMetadata(string relay_url, string? rw); - Hashtag(string hashtag); - Geohash(string geohash); - Identifier(string identifier); - ExternalIdentity(string identity, string proof); - A(u64 kind, string public_key, string identifier, string? relay_url); - RelayUrl(string relay_url); - ContactList(string pk, string? relay_url, string? alias); - POW(string nonce, u8 difficulty); - Delegation(string delegator_pk, string conditions, string sig); - ContentWarning(string? reason); - Expiration(u64 timestamp); - Subject(string subject); - Challenge(string challenge); - Title(string title); - Image(string url, string? dimensions); - Thumb(string url, string? dimensions); - Summary(string summary); - Description(string desc); - Bolt11(string bolt11); - Preimage(string preimage); - Relays(sequence urls); - Amount(u64 millisats, string? bolt11); - Lnurl(string lnurl); - Name(string name); - PublishedAt(u64 timestamp); - Url(string url); - MimeType(string mime); - Aes256Gcm(string key, string iv); - Sha256(string hash); - Size(u64 size); - Dim(string dimensions); - Magnet(string uri); - Blurhash(string blurhash); - Streaming(string url); - Recording(string url); - Starts(u64 timestamp); - Ends(u64 timestamp); - LiveEventStatus(string status); - CurrentParticipants(u64 num); - TotalParticipants(u64 num); - AbsoluteURL(string url); - Method(string method); - Payload(string hash); - Anon(string? msg); - Proxy(string id, string protocol); - Emoji(string shortcode, string url); - Request(string event); - DataVendingMachineStatus(string status, string? extra_info); -}; - -interface Tag { - [Throws=NostrError, Name=parse] - constructor(sequence data); - [Throws=NostrError, Name=from_enum] - constructor(TagEnum e); - TagEnum as_enum(); - sequence as_vec(); - TagKind kind(); -}; - -// NOSTR-SDK - -interface RelayConnectionStats { - u64 attempts(); - u64 success(); - f64 uptime(); - u64 bytes_sent(); - u64 bytes_received(); - duration? latency(); - Timestamp connected_at(); -}; - -enum RelayStatus { - "Initialized", - "Pending", - "Connecting", - "Connected", - "Disconnected", - "Stopped", - "Terminated", -}; - -interface ActiveSubscription { - string id(); - sequence filters(); -}; - -interface Relay { - string url(); - string? proxy(); - RelayStatus status(); - boolean is_connected(); - RelayInformationDocument document(); - record subscriptions(); - void update_subscription_filters(string internal_id, sequence filters); - RelayConnectionStats stats(); - u64 queue(); - - void connect(boolean wait_for_connection); - [Throws=NostrSdkError] - void stop(); - [Throws=NostrSdkError] - void terminate(); - - [Throws=NostrSdkError] - void send_msg(ClientMessage msg, duration? wait); - [Throws=NostrSdkError] - void subscribe(sequence filters, duration? wait); - [Throws=NostrSdkError] - void unsubscribe(duration? wait); - - [Throws=NostrSdkError] - sequence get_events_of(sequence filters, duration timeout); - void req_events_of(sequence filters, duration timeout); -}; - -interface NostrDatabase { - [Throws=NostrSdkError, Name=sqlite] - constructor(string path); - - [Throws=NostrSdkError] - boolean save_event(Event event); - [Throws=NostrSdkError] - sequence? event_seen_on_relays(EventId event_id); - [Throws=NostrSdkError] - Event event_by_id(EventId event_id); - [Throws=NostrSdkError] - u64 count(sequence filters); - [Throws=NostrSdkError] - sequence query(sequence filters); - [Throws=NostrSdkError] - void wipe(); - [Throws=NostrSdkError] - Metadata profile(PublicKey public_key); -}; - -interface Options { - constructor(); - [Self=ByArc] - Options wait_for_connection(boolean wait); - [Self=ByArc] - Options wait_for_send(boolean wait); - [Self=ByArc] - Options wait_for_subscription(boolean wait); - [Self=ByArc] - Options difficulty(u8 difficulty); - [Self=ByArc] - Options req_filters_chunk_size(u8 req_filters_chunk_size); - [Self=ByArc] - Options skip_disconnected_relays(boolean skip); - [Self=ByArc] - Options timeout(duration timeout); - [Self=ByArc] - Options send_timeout(duration? send_timeout); - [Self=ByArc] - Options nip46_timeout(duration? nip46_timeout); -}; - -interface ClientBuilder { - constructor(Keys keys); - [Self=ByArc] - ClientBuilder opts(Options opts); - [Self=ByArc] - ClientBuilder database(NostrDatabase database); - Client build(); -}; - -interface Client { - constructor(Keys keys); - [Name=with_opts] - constructor(Keys keys, Options opts); - - void update_difficulty(u8 difficulty); - Keys keys(); - NostrDatabase database(); - - void start(); - [Throws=NostrSdkError] - void stop(); - boolean is_running(); - [Throws=NostrSdkError] - void shutdown(); - - record relays(); - [Throws=NostrSdkError] - Relay relay(string url); - [Throws=NostrSdkError] - boolean add_relay(string url, optional string? proxy = null); - [Throws=NostrSdkError] - void remove_relay(string url); - [Throws=NostrSdkError] - void connect_relay(string url); - [Throws=NostrSdkError] - void disconnect_relay(string url); - void connect(); - [Throws=NostrSdkError] - void disconnect(); - - void subscribe(sequence filters); - void unsubscribe(); - - [Throws=NostrSdkError] - sequence get_events_of(sequence filters, duration? timeout); - void req_events_of(sequence filters, duration? timeout); - - [Throws=NostrSdkError] - void send_msg(ClientMessage msg); - [Throws=NostrSdkError] - void send_msg_to(string url, ClientMessage msg); - [Throws=NostrSdkError] - EventId send_event(Event event); - [Throws=NostrSdkError] - EventId send_event_to(string url, Event event); - - [Throws=NostrSdkError] - EventId set_metadata(Metadata metadata); - [Throws=NostrSdkError] - EventId send_direct_msg(PublicKey receiver, string msg, EventId? reply); - [Throws=NostrSdkError] - EventId file_metadata(string description, FileMetadata metadata); - - [Throws=NostrSdkError] - void reconcile(Filter filter); - - [Self=ByArc] - void handle_notifications(HandleNotification handler); -}; - -callback interface HandleNotification { - void handle_msg(string relay_url, RelayMessage msg); - void handle(string relay_url, Event event); -}; diff --git a/bindings/nostr-sdk-ffi/src/relay.rs b/bindings/nostr-sdk-ffi/src/relay.rs index 1b1f5297b..9509ac137 100644 --- a/bindings/nostr-sdk-ffi/src/relay.rs +++ b/bindings/nostr-sdk-ffi/src/relay.rs @@ -7,10 +7,12 @@ use std::{collections::HashMap, ops::Deref}; use nostr_ffi::{ClientMessage, Event, Filter, RelayInformationDocument, Timestamp}; use nostr_sdk::relay::InternalSubscriptionId; -use nostr_sdk::{block_on, relay, FilterOptions, RelayStatus}; +use nostr_sdk::{block_on, relay, FilterOptions}; +use uniffi::{Enum, Object}; use crate::error::Result; +#[derive(Object)] pub struct RelayConnectionStats { inner: relay::RelayConnectionStats, } @@ -21,6 +23,7 @@ impl From for RelayConnectionStats { } } +#[uniffi::export] impl RelayConnectionStats { pub fn attempts(&self) -> u64 { self.inner.attempts() as u64 @@ -36,7 +39,7 @@ impl RelayConnectionStats { pub fn connected_at(&self) -> Arc { let secs = self.inner.connected_at().as_u64(); - Arc::new(Timestamp::from_secs(secs)) + Timestamp::from_secs(secs) } pub fn bytes_sent(&self) -> u64 { @@ -52,6 +55,7 @@ impl RelayConnectionStats { } } +#[derive(Object)] pub struct ActiveSubscription { inner: relay::ActiveSubscription, } @@ -62,6 +66,7 @@ impl From for ActiveSubscription { } } +#[uniffi::export] impl ActiveSubscription { pub fn id(&self) -> String { self.inner.id().to_string() @@ -76,6 +81,39 @@ impl ActiveSubscription { } } +#[derive(Enum)] +pub enum RelayStatus { + /// Relay initialized + Initialized, + /// Pending + Pending, + /// Connecting + Connecting, + /// Relay connected + Connected, + /// Relay disconnected, will retry to connect again + Disconnected, + /// Stop + Stopped, + /// Relay completely disconnected + Terminated, +} + +impl From for RelayStatus { + fn from(value: nostr_sdk::RelayStatus) -> Self { + match value { + nostr_sdk::RelayStatus::Initialized => Self::Initialized, + nostr_sdk::RelayStatus::Pending => Self::Pending, + nostr_sdk::RelayStatus::Connecting => Self::Connecting, + nostr_sdk::RelayStatus::Connected => Self::Connected, + nostr_sdk::RelayStatus::Disconnected => Self::Disconnected, + nostr_sdk::RelayStatus::Stopped => Self::Stopped, + nostr_sdk::RelayStatus::Terminated => Self::Terminated, + } + } +} + +#[derive(Object)] pub struct Relay { inner: relay::Relay, } @@ -86,6 +124,7 @@ impl From for Relay { } } +#[uniffi::export] impl Relay { pub fn url(&self) -> String { self.inner.url().to_string() @@ -96,7 +135,7 @@ impl Relay { } pub fn status(&self) -> RelayStatus { - self.inner.status_blocking() + self.inner.status_blocking().into() } pub fn is_connected(&self) -> bool { diff --git a/bindings/nostr-sdk-ffi/uniffi.toml b/bindings/nostr-sdk-ffi/uniffi.toml index 19edbcf28..38905989e 100644 --- a/bindings/nostr-sdk-ffi/uniffi.toml +++ b/bindings/nostr-sdk-ffi/uniffi.toml @@ -1,10 +1,5 @@ [bindings.kotlin] package_name = "nostr_sdk" -cdylib_name = "nostr_sdk_ffi" [bindings.swift] ffi_module_filename = "nostr_sdkFFI" -cdylib_name = "nostr_sdk_ffi" - -[bindings.python] -cdylib_name = "nostr_sdk_ffi" From ef6b75a36db6ed5259a868c2b52d452fa2e562cc Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Wed, 6 Dec 2023 17:59:48 +0100 Subject: [PATCH 3/8] ffi: fix `make python-win` command --- bindings/nostr-ffi/Makefile | 2 +- bindings/nostr-sdk-ffi/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/nostr-ffi/Makefile b/bindings/nostr-ffi/Makefile index 1b245a01a..12d73158b 100644 --- a/bindings/nostr-ffi/Makefile +++ b/bindings/nostr-ffi/Makefile @@ -111,6 +111,6 @@ python-win: cargo build --release cargo run -p uniffi-bindgen generate --library ..\..\target\release\nostr_ffi.dll --language python --no-format -o bindings-python/src/nostr/ copy ..\..\target\release\nostr_ffi.dll bindings-python\src\nostr - del /F /Q bindings-python\dist\* + del /F /Q bindings-python\dist\* 2>nul || exit /b 0 cd bindings-python && python setup.py --verbose bdist_wheel FOR %%i in (.\bindings-python\dist\*.whl) DO pip install %i --force-reinstall \ No newline at end of file diff --git a/bindings/nostr-sdk-ffi/Makefile b/bindings/nostr-sdk-ffi/Makefile index dbaec9c2f..f1054ce00 100644 --- a/bindings/nostr-sdk-ffi/Makefile +++ b/bindings/nostr-sdk-ffi/Makefile @@ -113,6 +113,6 @@ python-win: cargo build --release cargo run -p uniffi-bindgen generate --library ..\..\target\release\nostr_sdk_ffi.dll --language python --no-format -o bindings-python\src\nostr-sdk copy ..\..\target\release\nostr_sdk_ffi.dll bindings-python\src\nostr-sdk - del /F /Q bindings-python\dist\* + del /F /Q bindings-python\dist\* 2>nul || exit /b 0 cd bindings-python && python setup.py --verbose bdist_wheel FOR %%i in (.\bindings-python\dist\*.whl) DO pip install %i --force-reinstall From 8746a07fa48fc12b6273cfbe9fa986fa63aa0720 Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Wed, 6 Dec 2023 18:42:06 +0100 Subject: [PATCH 4/8] workflows: fix deprecated --- .github/workflows/publish-python.yaml | 2 +- .github/workflows/publish-sdk-python.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-python.yaml b/.github/workflows/publish-python.yaml index 59f326faf..550f2acec 100644 --- a/.github/workflows/publish-python.yaml +++ b/.github/workflows/publish-python.yaml @@ -204,4 +204,4 @@ jobs: with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} - packages_dir: dist/*/ + packages-dir: dist/*/ diff --git a/.github/workflows/publish-sdk-python.yaml b/.github/workflows/publish-sdk-python.yaml index 4eeb404dd..7cc0a41ed 100644 --- a/.github/workflows/publish-sdk-python.yaml +++ b/.github/workflows/publish-sdk-python.yaml @@ -204,4 +204,4 @@ jobs: with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} - packages_dir: dist/*/ + packages-dir: dist/*/ From 97e4dde796b1ff577c2ec8791572b6ccfd34f2a7 Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Thu, 7 Dec 2023 10:39:22 +0100 Subject: [PATCH 5/8] ffi: replace `kotlin-clean` with `clean-android` --- bindings/nostr-ffi/Makefile | 10 +++++----- bindings/nostr-sdk-ffi/Makefile | 9 +++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/bindings/nostr-ffi/Makefile b/bindings/nostr-ffi/Makefile index 12d73158b..5875944c5 100644 --- a/bindings/nostr-ffi/Makefile +++ b/bindings/nostr-ffi/Makefile @@ -24,14 +24,14 @@ sdk-root: exit 1 ; \ fi -kotlin-clean: - mkdir -p ffi/kotlin/jniLibs - find ./ffi/kotlin/jniLibs -name libnostr_ffi.so -type f -delete +clean-android: + rm -rf ffi/android + rm -rf ffi/kotlin -kotlin: android +kotlin: clean-android android cargo run -p uniffi-bindgen generate --library ../../target/x86_64-linux-android/release/libnostr_ffi.so --language kotlin --no-format -o ffi/kotlin -android: kotlin-clean aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android +android: aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android aarch64-linux-android: $(SOURCES) ndk-home cargo ndk -t aarch64-linux-android -o ffi/kotlin/jniLibs build --release diff --git a/bindings/nostr-sdk-ffi/Makefile b/bindings/nostr-sdk-ffi/Makefile index f1054ce00..1084dcaed 100644 --- a/bindings/nostr-sdk-ffi/Makefile +++ b/bindings/nostr-sdk-ffi/Makefile @@ -24,14 +24,15 @@ sdk-root: exit 1 ; \ fi -kotlin-clean: - find ./ffi/kotlin/jniLibs -name libnostr_sdk_ffi.so -type f -delete +clean-android: + rm -rf ffi/android + rm -rf ffi/kotlin -kotlin: android +kotlin: clean-android android find ./ffi/kotlin/jniLibs -name libnostr_ffi.so -type f -delete cargo run -p uniffi-bindgen generate --library ../../target/x86_64-linux-android/release/libnostr_sdk_ffi.so --language kotlin --no-format -o ffi/kotlin -android: kotlin-clean aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android +android: aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android aarch64-linux-android: $(SOURCES) ndk-home cargo ndk -t aarch64-linux-android -o ffi/kotlin/jniLibs build --release From 47073da658c817bc82ce192ce87f8a9c0c4b5cef Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Thu, 7 Dec 2023 11:09:53 +0100 Subject: [PATCH 6/8] ffi(nostr): add `NostrLibrary` struct --- .../bindings-python/examples/git_version.py | 4 ++++ bindings/nostr-ffi/src/lib.rs | 24 ++++++++++++------- bindings/nostr-ffi/src/message/mod.rs | 2 +- bindings/nostr-sdk-ffi/src/lib.rs | 6 ++--- 4 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 bindings/nostr-ffi/bindings-python/examples/git_version.py diff --git a/bindings/nostr-ffi/bindings-python/examples/git_version.py b/bindings/nostr-ffi/bindings-python/examples/git_version.py new file mode 100644 index 000000000..9ada6281e --- /dev/null +++ b/bindings/nostr-ffi/bindings-python/examples/git_version.py @@ -0,0 +1,4 @@ +from nostr_protocol import NostrLibrary + +hash = NostrLibrary().git_hash_version() +print(hash) \ No newline at end of file diff --git a/bindings/nostr-ffi/src/lib.rs b/bindings/nostr-ffi/src/lib.rs index 6ade572b1..85dce702c 100644 --- a/bindings/nostr-ffi/src/lib.rs +++ b/bindings/nostr-ffi/src/lib.rs @@ -1,8 +1,9 @@ // Copyright (c) 2022-2023 Yuki Kishimoto // Distributed under the MIT software license -//pub use nostr::nips::nip44::Version as NIP44Version; -pub use nostr::Alphabet; +use std::sync::Arc; + +use uniffi::Object; mod error; mod event; @@ -13,15 +14,12 @@ mod nips; mod types; mod util; -// Error pub use crate::error::NostrError; - -// Nostr pub use crate::event::{ Event, EventBuilder, EventId, Tag, TagEnum, TagKind, TagKindKnown, UnsignedEvent, }; pub use crate::key::{Keys, PublicKey, SecretKey}; -pub use crate::message::{ClientMessage, Filter, RelayMessage}; +pub use crate::message::{Alphabet, ClientMessage, Filter, RelayMessage}; pub use crate::nips::nip04::{nip04_decrypt, nip04_encrypt}; pub use crate::nips::nip05::{get_nip05_profile, verify_nip05}; pub use crate::nips::nip11::RelayInformationDocument; @@ -32,9 +30,19 @@ pub use crate::nips::nip94::FileMetadata; pub use crate::types::{Contact, ImageDimensions, Metadata, Profile, Timestamp}; pub use crate::util::generate_shared_key; +#[derive(Object)] +pub struct NostrLibrary; + #[uniffi::export] -pub fn git_hash_version() -> String { - nostr::git_hash_version().to_string() +impl NostrLibrary { + #[uniffi::constructor] + pub fn new() -> Arc { + Arc::new(Self) + } + + pub fn git_hash_version(&self) -> String { + nostr::git_hash_version().to_string() + } } uniffi::setup_scaffolding!("nostr"); diff --git a/bindings/nostr-ffi/src/message/mod.rs b/bindings/nostr-ffi/src/message/mod.rs index b36a56368..9638ca8ee 100644 --- a/bindings/nostr-ffi/src/message/mod.rs +++ b/bindings/nostr-ffi/src/message/mod.rs @@ -7,4 +7,4 @@ mod subscription; pub use self::client::ClientMessage; pub use self::relay::RelayMessage; -pub use self::subscription::Filter; +pub use self::subscription::{Alphabet, Filter}; diff --git a/bindings/nostr-sdk-ffi/src/lib.rs b/bindings/nostr-sdk-ffi/src/lib.rs index 0906e83d9..65b631800 100644 --- a/bindings/nostr-sdk-ffi/src/lib.rs +++ b/bindings/nostr-sdk-ffi/src/lib.rs @@ -4,9 +4,9 @@ #![allow(clippy::new_without_default)] pub use nostr_ffi::{ - generate_shared_key, get_nip05_profile, git_hash_version, nip04_decrypt, nip04_encrypt, - verify_nip05, Alphabet, ClientMessage, Contact, Event, EventBuilder, EventId, FileMetadata, - Filter, ImageDimensions, Keys, Metadata, NostrConnectURI, NostrError, Profile, PublicKey, + generate_shared_key, get_nip05_profile, nip04_decrypt, nip04_encrypt, verify_nip05, Alphabet, + ClientMessage, Contact, Event, EventBuilder, EventId, FileMetadata, Filter, ImageDimensions, + Keys, Metadata, NostrConnectURI, NostrError, NostrLibrary, Profile, PublicKey, RelayInformationDocument, RelayMessage, SecretKey, Tag, TagEnum, TagKind, TagKindKnown, Timestamp, UnsignedEvent, ZapRequestData, }; From 8208ff9d854f3b1b1905ef887e3c5702a13c1765 Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Thu, 7 Dec 2023 11:32:10 +0100 Subject: [PATCH 7/8] ffi(nostr): set `android` pakage name to `rust.nostr.protocol` --- bindings/nostr-ffi/Makefile | 3 ++- bindings/nostr-ffi/bindings-android/lib/proguard-rules.pro | 2 -- bindings/nostr-ffi/uniffi.toml | 2 +- book/src/nostr/02-installation.md | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bindings/nostr-ffi/Makefile b/bindings/nostr-ffi/Makefile index 5875944c5..f64d4e413 100644 --- a/bindings/nostr-ffi/Makefile +++ b/bindings/nostr-ffi/Makefile @@ -49,7 +49,8 @@ bindings-android: sdk-root kotlin rm -rf bindings-android/lib/src/main/jniLibs rm -rf bindings-android/lib/src/main/kotlin cp -r ffi/kotlin/jniLibs bindings-android/lib/src/main - cp -r ffi/kotlin/nostr bindings-android/lib/src/main/kotlin/ + mkdir -p bindings-android/lib/src/main/kotlin/ + cp -r ffi/kotlin/rust bindings-android/lib/src/main/kotlin/ cd bindings-android && ./gradlew assemble mkdir -p ffi/android cp bindings-android/lib/build/outputs/aar/lib-release.aar ffi/android diff --git a/bindings/nostr-ffi/bindings-android/lib/proguard-rules.pro b/bindings/nostr-ffi/bindings-android/lib/proguard-rules.pro index 83986845e..5287e7c47 100644 --- a/bindings/nostr-ffi/bindings-android/lib/proguard-rules.pro +++ b/bindings/nostr-ffi/bindings-android/lib/proguard-rules.pro @@ -24,7 +24,5 @@ -dontwarn java.awt.* -keep class com.sun.jna.* { *; } -keep class rust.nostr.* { *; } --keep class nostr.** { *; } -keepclassmembers class * extends rust.nostr.* { public *; } --keepclassmembers class * extends nostr.** { public *; } -keepclassmembers class * extends com.sun.jna.* { public *; } diff --git a/bindings/nostr-ffi/uniffi.toml b/bindings/nostr-ffi/uniffi.toml index 0a50299b9..cc1520d6a 100644 --- a/bindings/nostr-ffi/uniffi.toml +++ b/bindings/nostr-ffi/uniffi.toml @@ -1,5 +1,5 @@ [bindings.kotlin] -package_name = "nostr" +package_name = "rust.nostr.protocol" [bindings.swift] ffi_module_filename = "nostrFFI" \ No newline at end of file diff --git a/book/src/nostr/02-installation.md b/book/src/nostr/02-installation.md index 8cd055a27..34f8db66a 100644 --- a/book/src/nostr/02-installation.md +++ b/book/src/nostr/02-installation.md @@ -56,7 +56,7 @@ Import the library in your code: ```kotlin - import nostr.* + import rust.nostr.protocol.* ``` ## Known issues From 62f7375d1fd064dc9b65d12e579faadea0d11933 Mon Sep 17 00:00:00 2001 From: Yuki Kishimoto Date: Thu, 7 Dec 2023 11:32:28 +0100 Subject: [PATCH 8/8] ffi(nostr-sdk): set `android` pakage name to `rust.nostr.sdk` --- bindings/nostr-sdk-ffi/Makefile | 3 +-- .../nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro | 8 ++------ bindings/nostr-sdk-ffi/uniffi.toml | 2 +- book/src/nostr-sdk/02-installation.md | 6 ++++++ 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/bindings/nostr-sdk-ffi/Makefile b/bindings/nostr-sdk-ffi/Makefile index 1084dcaed..dedaa64eb 100644 --- a/bindings/nostr-sdk-ffi/Makefile +++ b/bindings/nostr-sdk-ffi/Makefile @@ -51,8 +51,7 @@ bindings-android: sdk-root kotlin rm -rf bindings-android/lib/src/main/kotlin cp -r ffi/kotlin/jniLibs bindings-android/lib/src/main mkdir -p bindings-android/lib/src/main/kotlin/ - cp ffi/kotlin/nostr/nostr.kt bindings-android/lib/src/main/kotlin/ - cp ffi/kotlin/nostr_sdk/nostr_sdk.kt bindings-android/lib/src/main/kotlin/ + cp -r ffi/kotlin/rust bindings-android/lib/src/main/kotlin/ cd bindings-android && ./gradlew assemble mkdir -p ffi/android cp bindings-android/lib/build/outputs/aar/lib-release.aar ffi/android diff --git a/bindings/nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro b/bindings/nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro index 138837183..04e9b6b44 100644 --- a/bindings/nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro +++ b/bindings/nostr-sdk-ffi/bindings-android/lib/proguard-rules.pro @@ -23,10 +23,6 @@ # for JNA -dontwarn java.awt.* -keep class com.sun.jna.* { *; } --keep class rust.nostr.sdk.* { *; } --keep class nostr.** { *; } --keep class nostr_sdk.** { *; } --keepclassmembers class * extends rust.nostr.sdk.* { public *; } --keepclassmembers class * extends nostr.** { public *; } --keepclassmembers class * extends nostr_sdk.** { public *; } +-keep class rust.nostr.** { *; } +-keepclassmembers class * extends rust.nostr.* { public *; } -keepclassmembers class * extends com.sun.jna.* { public *; } diff --git a/bindings/nostr-sdk-ffi/uniffi.toml b/bindings/nostr-sdk-ffi/uniffi.toml index 38905989e..02575995a 100644 --- a/bindings/nostr-sdk-ffi/uniffi.toml +++ b/bindings/nostr-sdk-ffi/uniffi.toml @@ -1,5 +1,5 @@ [bindings.kotlin] -package_name = "nostr_sdk" +package_name = "rust.nostr.sdk" [bindings.swift] ffi_module_filename = "nostr_sdkFFI" diff --git a/book/src/nostr-sdk/02-installation.md b/book/src/nostr-sdk/02-installation.md index 045dc02ee..f0a42f615 100644 --- a/book/src/nostr-sdk/02-installation.md +++ b/book/src/nostr-sdk/02-installation.md @@ -41,6 +41,12 @@ } ``` + Import the library in your code: + + ```kotlin + import rust.nostr.sdk.* + ``` + ## Known issues ### JNA dependency