Skip to content

Commit

Permalink
Support did_dht_resolution in C (#390)
Browse files Browse the repository at this point in the history
* Add did_dht_resolution

* Add c example

* Simplify docs
  • Loading branch information
andresuribe87 authored Oct 11, 2024
1 parent 2a618b9 commit 4193238
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 0 deletions.
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(),
}
};

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
66 changes: 66 additions & 0 deletions examples/CExample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## 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).

2. Navigate to the root directory of the project (where you cloned the git repository). It's the same location this [Justfile](../../Justfile) is located.

3. Generate the C dynamic library by running:

```shell
just bindc
```

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

4. Navigate to the `examples/CExample` directory:

```shell
cd examples/CExample
```

5. Compile the example using the Justfile recipe:

```shell
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:

```shell
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:

```shell
just clean
```

This will remove the `build` directory.

## Available Justfile Recipes

Before running any of the recipes below, ensure you have executed the following command from the root directory of the project.

The recipes available for this example are:

| Recipe | Description |
|----------|-----------------------------------------------------------------------|
| compile | Compiles the C example, creating a `build` directory with the binary |
| run | Compiles (if needed) and runs the example program |
| clean | Removes the `build` directory, cleaning up all build artifacts |
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;
}

0 comments on commit 4193238

Please sign in to comment.