{"id":31355188,"url":"https://github.com/synonymdev/vss-rust-client-ffi","last_synced_at":"2026-04-02T22:15:02.185Z","repository":{"id":310165311,"uuid":"1028398200","full_name":"synonymdev/vss-rust-client-ffi","owner":"synonymdev","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-10T13:40:30.000Z","size":399299,"stargazers_count":1,"open_issues_count":1,"forks_count":2,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-02-10T18:25:52.425Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/synonymdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-29T13:23:09.000Z","updated_at":"2025-12-09T22:59:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"3ba89e90-23e6-42df-b700-89cdb03faebd","html_url":"https://github.com/synonymdev/vss-rust-client-ffi","commit_stats":null,"previous_names":["synonymdev/vss-rust-client-ffi"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/synonymdev/vss-rust-client-ffi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synonymdev%2Fvss-rust-client-ffi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synonymdev%2Fvss-rust-client-ffi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synonymdev%2Fvss-rust-client-ffi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synonymdev%2Fvss-rust-client-ffi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/synonymdev","download_url":"https://codeload.github.com/synonymdev/vss-rust-client-ffi/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synonymdev%2Fvss-rust-client-ffi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29314704,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-10T17:48:59.043Z","status":"ssl_error","status_checked_at":"2026-02-10T17:45:37.240Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-26T16:58:23.161Z","updated_at":"2026-04-02T22:15:02.179Z","avatar_url":"https://github.com/synonymdev.png","language":"C","readme":"# VSS Rust Client FFI\n\nCross-platform FFI bindings for the [VSS (Versioned Storage Service) Rust Client](https://github.com/lightningdevkit/vss-server), providing a simple interface for mobile applications to interact with VSS servers.\n\n## Installation\n\n### Prerequisites\n\n- Rust 1.75+\n- `uniffi-bindgen` for generating bindings\n\n### Building\n\n```bash\n# Basic build\ncargo build --release\n\n# Generate ALL bindings\n./build.sh all\n\n# Generate Swift bindings for iOS\n./build_ios.sh\n\n# Generate Kotlin bindings for Android  \n./build_android.sh\n\n# Generate Python bindings\n./build_python.sh\n```\n\n## Usage Examples\n\n### Swift (iOS)\n\n```swift\nimport VssRustClientFfi\n\nlet mnemonic = \"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about\"\nlet passphrase: String? = nil\nlet storeId = try vssDeriveStoreId(\n    prefix: \"bitkit_v1_regtest\",\n    mnemonic: mnemonic,\n    passphrase: passphrase\n)\n\ntry await vssNewClientWithLnurlAuth(\n    baseUrl: \"https://vss.example.com\",\n    storeId: storeId,\n    mnemonic: mnemonic,\n    passphrase: passphrase,\n    lnurlAuthServerUrl: \"https://auth.example.com/lnurl\"\n)\n\n// Store data\nlet item = try await vssStore(\n    key: \"user-settings\",\n    value: \"{'theme': 'dark'}\".data(using: .utf8)!\n)\nprint(\"Stored at version: \\(item.version)\")\n\n// Retrieve data\nif let item = try await vssGet(key: \"user-settings\") {\n    let data = String(data: item.value, encoding: .utf8)\n    print(\"Retrieved: \\(data)\")\n}\n\n// List all items with prefix\nlet items = try await vssList(prefix: \"user/\")\nfor item in items {\n    print(\"Key: \\(item.key), Version: \\(item.version)\")\n}\n\n// Delete data\nlet wasDeleted = try await vssDelete(key: \"user-settings\")\nprint(\"Deleted: \\(wasDeleted)\")\n\n// Clean shutdown (optional)\nvssShutdownClient()\n```\n\n#### Dedicated LDK Client (Swift)\n\nFor fully isolated LDK operations with independent key derivation (full 64-byte BIP39 seed):\n\n```swift\n// Initialize the dedicated LDK client (separate from the app client)\ntry await vssNewLdkClientWithLnurlAuth(\n    baseUrl: \"https://vss.example.com\",\n    storeId: storeId,\n    mnemonic: mnemonic,\n    passphrase: passphrase,\n    lnurlAuthServerUrl: \"https://auth.example.com/lnurl\"\n)\n\n// Read an ldk-node key\nif let item = try await vssLdkGet(key: \"network_graph\", namespace: .default) {\n    print(\"Graph size: \\(item.value.count) bytes\")\n}\n\n// Store a key\nlet item = try await vssLdkStore(\n    key: \"network_graph\",\n    value: graphData,\n    namespace: .default\n)\n\n// Delete a key\nlet wasDeleted = try await vssLdkDelete(key: \"network_graph\", namespace: .default)\n\n// List keys in a namespace\nlet keys = try await vssLdkListKeys(namespace: .monitors)\n\n// List all keys across all namespaces\nlet allKeys = try await vssLdkListAllKeys()\n\n// Clean shutdown\nvssShutdownLdkClient()\n```\n\n### Python\n\n```python\nfrom vss_rust_client_ffi import *\n\nmnemonic = \"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about\"\npassphrase = None\nstore_id = vss_derive_store_id(\n    prefix=\"bitkit_v1_regtest\",\n    mnemonic=mnemonic,\n    passphrase=passphrase\n)\n\nawait vss_new_client_with_lnurl_auth(\n    \"https://vss.example.com\",\n    store_id,\n    mnemonic,\n    passphrase,\n    \"https://auth.example.com/lnurl\"\n)\n\n# Store data\nitem = await vss_store(\"user-settings\", b\"{'theme': 'dark'}\")\nprint(f\"Stored at version: {item.version}\")\n\n# Retrieve data  \nitem = await vss_get(\"user-settings\")\nif item:\n    print(f\"Retrieved: {item.value.decode()}\")\n\n# List keys only (more efficient)\nkeys = await vss_list_keys(\"user/\")\nfor kv in keys:\n    print(f\"Key: {kv.key}, Version: {kv.version}\")\n\n# Batch store multiple items\nitems_to_store = [\n    KeyValue(key=\"config/theme\", value=b\"dark\"),\n    KeyValue(key=\"config/lang\", value=b\"en\")\n]\nstored_items = await vss_put_with_key_prefix(items_to_store)\nprint(f\"Stored {len(stored_items)} items\")\n\n# Delete data\nwas_deleted = await vss_delete(\"user-settings\")\nprint(f\"Deleted: {was_deleted}\")\n\n# Clean shutdown (optional)\nvss_shutdown_client()\n```\n\n#### Dedicated LDK Client (Python)\n\n```python\n# Initialize the dedicated LDK client (separate from the app client)\nawait vss_new_ldk_client_with_lnurl_auth(\n    \"https://vss.example.com\",\n    store_id,\n    mnemonic,\n    passphrase,\n    \"https://auth.example.com/lnurl\"\n)\n\n# Read an ldk-node key\nitem = await vss_ldk_get(\"network_graph\", LdkNamespace.DEFAULT)\n\n# Store a key\nitem = await vss_ldk_store(\"network_graph\", graph_data, LdkNamespace.DEFAULT)\n\n# Delete a key\nwas_deleted = await vss_ldk_delete(\"network_graph\", LdkNamespace.DEFAULT)\n\n# List keys in a namespace\nkeys = await vss_ldk_list_keys(LdkNamespace.MONITORS)\n\n# List all keys across all namespaces\nall_keys = await vss_ldk_list_all_keys()\n\n# Clean shutdown\nvss_shutdown_ldk_client()\n```\n\n### Kotlin (Android)\n\n```kotlin\nimport uniffi.vss_rust_client_ffi.*\n\nval mnemonic = \"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about\"\nval passphrase: String? = null\nval storeId = vssDeriveStoreId(\n    prefix = \"bitkit_v1_regtest\",\n    mnemonic = mnemonic,\n    passphrase = passphrase\n)\n\nvssNewClientWithLnurlAuth(\n    baseUrl = \"https://vss.example.com\",\n    storeId = storeId,\n    mnemonic = mnemonic,\n    passphrase = passphrase,\n    lnurlAuthServerUrl = \"https://auth.example.com/lnurl\"\n)\n\n// Store data\nval item = vssStore(\n    key = \"user-settings\", \n    value = \"{'theme': 'dark'}\".toByteArray()\n)\nprintln(\"Stored at version: ${item.version}\")\n\n// Retrieve data\nval retrievedItem = vssGet(\"user-settings\")\nretrievedItem?.let {\n    println(\"Retrieved: ${String(it.value)}\")\n}\n\n// List all items\nval items = vssList(prefix = null)\nitems.forEach { item -\u003e\n    println(\"Key: ${item.key}, Version: ${item.version}\")\n}\n\n// Clean shutdown (optional)\nvssShutdownClient()\n```\n\n#### Dedicated LDK Client (Kotlin)\n\n```kotlin\n// Initialize the dedicated LDK client (separate from the app client)\nvssNewLdkClientWithLnurlAuth(\n    baseUrl = \"https://vss.example.com\",\n    storeId = storeId,\n    mnemonic = mnemonic,\n    passphrase = passphrase,\n    lnurlAuthServerUrl = \"https://auth.example.com/lnurl\"\n)\n\n// Read an ldk-node key\nval item = vssLdkGet(key = \"network_graph\", namespace = LdkNamespace.Default)\nitem?.let { println(\"Graph size: ${it.value.size} bytes\") }\n\n// Store a key\nval stored = vssLdkStore(\n    key = \"network_graph\",\n    value = graphData,\n    namespace = LdkNamespace.Default\n)\n\n// Delete a key\nval wasDeleted = vssLdkDelete(key = \"network_graph\", namespace = LdkNamespace.Default)\n\n// List keys in a namespace\nval keys = vssLdkListKeys(namespace = LdkNamespace.Monitors)\n\n// List all keys across all namespaces\nval allKeys = vssLdkListAllKeys()\n\n// Clean shutdown\nvssShutdownLdkClient()\n```\n\n## API Reference\n\n### Client Management\n\n#### `vssNewClient(baseUrl: String, storeId: String) -\u003e Void`\nInitialize the global VSS client connection without authentication.\n\n- `baseUrl`: VSS server URL (e.g., \"https://vss.example.com\")\n- `storeId`: Unique identifier for your storage namespace  \n\n#### `vssNewClientWithLnurlAuth(baseUrl: String, storeId: String, mnemonic: String, passphrase: String?, lnurlAuthServerUrl: String) -\u003e Void`\nInitialize the global VSS client connection with LNURL-auth authentication. Provides automatic JWT token management and data encryption.\n\n- `baseUrl`: VSS server URL (e.g., \"https://vss.example.com\")\n- `storeId`: Unique identifier for your storage namespace\n- `mnemonic`: BIP39 mnemonic phrase (12 or 24 words)\n- `passphrase`: Optional BIP39 passphrase (pass `null` if none)\n- `lnurlAuthServerUrl`: LNURL-auth server URL for authentication\n\n#### `vssShutdownClient() -\u003e Void`\nShutdown the VSS client and clean up resources. Optional but recommended for clean application shutdown.\n\n### Utility Functions\n\n#### `vssDeriveStoreId(prefix: String, mnemonic: String, passphrase: String?) -\u003e String`\nDerives a deterministic VSS store ID from a mnemonic and optional passphrase using BIP32 key derivation.\n\n- `prefix`: A prefix to include in the store ID (e.g., \"bitkit_v1_regtest\")\n- `mnemonic`: BIP39 mnemonic phrase (12 or 24 words)  \n- `passphrase`: Optional BIP39 passphrase\n\n### Data Operations\n\n#### `vssStore(key: String, value: Data) -\u003e VssItem`\nStore a key-value pair. The server automatically manages versioning, incrementing the version number with each update.\n\n#### `vssGet(key: String) -\u003e VssItem?`\nRetrieve an item by key. Returns `null` if not found.\n\n#### `vssList(prefix: String?) -\u003e [VssItem]`\nList all items, optionally filtered by key prefix. Includes full data.\n\n#### `vssListKeys(prefix: String?) -\u003e [KeyVersion]`\nList keys and versions only (more efficient than `vssList`).\n\n#### `vssPutWithKeyPrefix(items: [KeyValue]) -\u003e [VssItem]`\nStore multiple items in a single atomic transaction. The server manages versioning for all items.\n\n#### `vssDelete(key: String) -\u003e Bool`\nDelete an item. Returns `true` if item existed and was deleted.\n\n### Dedicated LDK Client\n\nA fully separate client (`LdkVssClient`) with its own key derivation using the full 64-byte BIP39 seed, independent from the app backup client. Use this when LDK operations must be completely isolated from app backup operations.\n\n#### `vssNewLdkClientWithLnurlAuth(baseUrl: String, storeId: String, mnemonic: String, passphrase: String?, lnurlAuthServerUrl: String) -\u003e Void`\nInitialize the dedicated LDK client with LNURL-auth authentication. This client is fully separate from the app client initialized with `vssNewClientWithLnurlAuth`.\n\n#### `vssShutdownLdkClient() -\u003e Void`\nShutdown the dedicated LDK client and clean up resources.\n\n#### `vssLdkStore(key: String, value: Data, namespace: LdkNamespace) -\u003e VssItem`\nStore a key-value pair using the dedicated LDK client.\n\n#### `vssLdkGet(key: String, namespace: LdkNamespace) -\u003e VssItem?`\nRetrieve an item by key using the dedicated LDK client. Returns `null` if not found.\n\n#### `vssLdkDelete(key: String, namespace: LdkNamespace) -\u003e Bool`\nDelete an item using the dedicated LDK client. Returns `true` if item existed and was deleted.\n\n#### `vssLdkListKeys(namespace: LdkNamespace) -\u003e [KeyVersion]`\nList keys in a namespace using the dedicated LDK client.\n\n#### `vssLdkListAllKeys() -\u003e [KeyVersion]`\nList all keys across all singleton LDK namespaces using the dedicated LDK client.\n\n### Data Types\n\n#### `VssItem`\n- `key: String` - The item key\n- `value: Data` - The stored data  \n- `version: Int64` - Version number\n\n#### `KeyValue`\n- `key: String` - The item key\n- `value: Data` - The data to store\n\n#### `KeyVersion`\n- `key: String` - The item key\n- `version: Int64` - Version number\n\n#### `LdkNamespace`\n- `Default` - Default namespace (channel_manager, scorer, etc.)\n- `Monitors` - Channel monitors\n- `MonitorUpdates(monitorId)` - Updates for a specific monitor\n- `ArchivedMonitors` - Archived channel monitors\n\n#### `VssError`\nError enum with detailed error information for different failure scenarios.\n\n## Building from Source\n\n### iOS Framework\n\n```bash\n./build_ios.sh\n```\n\nGenerates:\n- `bindings/ios/VssRustClientFfi.xcframework` - iOS framework\n- `bindings/ios/vss_rust_client_ffi.swift` - Swift bindings\n\n### Android Library  \n\n```bash\n./build_android.sh\n```\n\nGenerates:\n- `bindings/android/vss_rust_client_ffi.kt` - Kotlin bindings\n- `bindings/android/jniLibs/` - Native libraries for all Android architectures\n\n### Python Package\n\n```bash\n./build_python.sh\n```\n\nGenerates:\n- `bindings/python/` - Python package with bindings and native library\n\n## Development\n\n### Prerequisites\n\n```bash\n# Install Rust\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n\n# Install uniffi-bindgen\ncargo install uniffi_bindgen\n```\n\n### Running Tests\n\n```bash\n# Run unit tests (recommended)\ncargo test tests::tests --lib\n\n# Check compilation\ncargo check\n\n# Build library\ncargo build --release\n\n# Test bindings generation\ncargo run --bin uniffi-bindgen generate \\\n    --library ./target/release/libvss_rust_client_ffi.dylib \\\n    --language swift \\\n    --out-dir ./test_bindings\n```\n\n## Architecture\n\nThis library provides a thin FFI wrapper around the [vss-client-ng](https://crates.io/crates/vss-client-ng) Rust library, exposing a simplified async API suitable for mobile and cross-platform applications.\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests if applicable  \n5. Run `cargo test` and `cargo clippy`\n6. Submit a pull request\n\n## License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## Related Projects\n\n- [VSS Server](https://github.com/lightningdevkit/vss-server) - The VSS server implementation\n- [vss-client-ng](https://crates.io/crates/vss-client-ng) - The underlying Rust client library\n- [UniFFI](https://mozilla.github.io/uniffi-rs/) - The FFI binding generator\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynonymdev%2Fvss-rust-client-ffi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynonymdev%2Fvss-rust-client-ffi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynonymdev%2Fvss-rust-client-ffi/lists"}