Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support did_dht_resolution in C #390

Merged
merged 3 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bindings/web5_c/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ license-file.workspace = true

[dependencies]
lazy_static = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1.38.0", features = ["full"] }
web5 = { path = "../../crates/web5" }

[lib]
Expand Down
46 changes: 46 additions & 0 deletions bindings/web5_c/src/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,52 @@ pub extern "C" fn free_string(s: *mut c_char) {
}
}

use tokio::runtime::Runtime;
use web5::errors::Result;
use web5::errors::Web5Error;

pub fn get_rt() -> Result<Runtime> {
let rt = Runtime::new()
.map_err(|e| Web5Error::Unknown(format!("unable to instantiate tokio runtime {}", e)))?;
Ok(rt)
}

use serde_json;
use std::ptr;
use web5::dids::methods::did_dht;

#[no_mangle]
pub extern "C" fn did_dht_resolve(uri: *const c_char, gateway_url: *const c_char) -> *mut c_char {
let uri = match unsafe { CStr::from_ptr(uri).to_str() } {
Ok(s) => s,
Err(_) => return ptr::null_mut(),
};

let gateway_url = if gateway_url.is_null() {
None
} else {
match unsafe { CStr::from_ptr(gateway_url).to_str() } {
Ok(s) => Some(s.to_string()),
Err(_) => return ptr::null_mut(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at some point we should introduce better error handling over the C FFI, but it's not necessary at this moment

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created #392 to track.

}
};

let rt = match get_rt() {
Ok(rt) => rt,
Err(_) => return ptr::null_mut(),
};

let resolution_result = rt.block_on(did_dht::DidDht::resolve(uri, gateway_url));

match serde_json::to_string(&resolution_result) {
Ok(json_string) => match CString::new(json_string) {
Ok(c_str) => c_str.into_raw(),
Err(_) => ptr::null_mut(),
},
Err(_) => ptr::null_mut(),
}
}

pub fn free_bytes(ptr: *mut u8) {
if !ptr.is_null() {
unsafe {
Expand Down
5 changes: 5 additions & 0 deletions bindings/web5_c/web5_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,9 @@ void poc_key_manager_from_foreign(const CKeyManager *manager);
CKeyManager *new_in_memory_key_manager();
/** --- */

/** did dht */
char *did_dht_resolve(const char *uri, const char *gateway_url);

/** --- */

#endif // WEB5_C_H
1 change: 1 addition & 0 deletions examples/CExample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/
9 changes: 9 additions & 0 deletions examples/CExample/Justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
compile:
mkdir -p build
gcc -o build/web5_c_example web5_c.c -L../../target/release -lweb5_c -I../../bindings/web5_c

clean:
rm -rf build

run: compile
./build/web5_c_example
51 changes: 51 additions & 0 deletions examples/CExample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## Example Description

This C example demonstrates basic usage of the Web5 SDK functions through the C bindings. Specifically, it showcases:

1. Resolving a `did:dht` identifier
2. Printing the resolved DID document or an error message

This example demonstrates how to resolve a DHT-based DID using the Web5 SDK in C. It uses the `did_dht_resolve` function with a hardcoded DID URI and the default gateway. The program then prints either the resolved DID document or an error message to the console.


## Running the Example

To run this C example:

1. Ensure you have a C compiler installed (e.g. GCC) and [Just](https://github.com/casey/just) command runner.
andresuribe87 marked this conversation as resolved.
Show resolved Hide resolved

2. Navigate to the root directory of the project where the main Justfile is located.

3. Generate the C dynamic library by running:

```
just bindc
```

This command will build the necessary C bindings for the Web5 SDK.

4. Navigate to the `examples/CExample` directory where the example-specific Justfile is located.
KendallWeihe marked this conversation as resolved.
Show resolved Hide resolved

5. Compile the example using the Justfile recipe:

```
just compile
```

This command will create a `build` directory and compile the C example using GCC with the appropriate flags and library paths.

6. Run the compiled example:

```
just run
```

This will compile (if not already done) and execute the example program, demonstrating the usage of Web5 SDK functions in C.

7. To clean up the build artifacts:

```
just clean
```

This will remove the `build` directory.
19 changes: 19 additions & 0 deletions examples/CExample/web5_c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <stdio.h>
#include <stdlib.h>
#include "web5_c.h"

int main() {
const char* did_uri = "did:dht:qgmmpyjw5hwnqfgzn7wmrm33ady8gb8z9ideib6m9gj4ys6wny8y";
const char* gateway_url = NULL; // Using the default gateway

char* result = did_dht_resolve(did_uri, gateway_url);

if (result != NULL) {
printf("%s", result);
free_string(result);
} else {
printf("Failed to resolve DID\n");
}

return 0;
}
Loading