Skip to content

Commit

Permalink
feat: add fetch static function to JS bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
vemonet committed Mar 3, 2024
1 parent 0f72924 commit c5635da
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 13 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ members = [
]

[workspace.package]
version = "0.0.17"
version = "0.0.18"
authors = ["Vincent Emonet <[email protected]>"]
edition = "2021"
repository = "https://github.com/vemonet/nanopub-rs"
Expand Down
2 changes: 1 addition & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ homepage.workspace = true
categories.workspace = true

[dependencies]
nanopub = { version = "0.0.17", path = "../lib" }
nanopub = { version = "0.0.18", path = "../lib" }
clap = { version = "4.4", features = ["derive"] }
clap_complete = "4.4"
tokio = { version = "1.34", features = ["macros", "rt-multi-thread"] }
2 changes: 1 addition & 1 deletion js/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ categories.workspace = true
crate-type = ["cdylib"]

[dependencies]
nanopub = { version = "0.0.17", path = "../lib" }
nanopub = { version = "0.0.18", path = "../lib" }
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
wasm-bindgen-derive = "0.2"
Expand Down
12 changes: 12 additions & 0 deletions js/src/nanopub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ impl Nanopub {
})
}

#[wasm_bindgen(static_method_of = Nanopub)]
pub fn fetch(uri: String) -> Promise {
future_to_promise(async move {
match RsNanopub::fetch(&uri).await {
Ok(np) => Ok(JsValue::from(Nanopub { np })),
Err(e) => Err(JsValue::from_str(&format!(
"Error fetching the Nanopub: {e}"
))),
}
})
}

#[wasm_bindgen(static_method_of = Nanopub)]
pub fn publish_intro(profile: &NpProfile, server_url: String) -> Promise {
let profile = profile.profile.clone();
Expand Down
10 changes: 8 additions & 2 deletions js/tests/nanopub.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@ const unsignedRdf = `@prefix : <http://purl.org/nanopub/temp/mynanopub#> .
describe('Tests for the curies npm package', () => {
// NOTE: `await init()` only needed in browser environment

test('publish np', async () => {
test('publish nanopub', async () => {
const profile = new NpProfile(privKey, orcid, "Your Name", "");
const np = await new Nanopub(unsignedRdf).publish(profile);

console.log("Published Nanopub:", np.info());
// console.log("Published Nanopub:", np.info());
expect(np.info().published).toBeDefined();
// expect(np.info().trusty_hash).toBe("RAE9traVUygMTJ-k8E1_pVNy3gtf7uUvtHJtPeU64WpA4");
});

test('fetch nanopub', async () => {
const npUri = "https://w3id.org/np/RAltRkGOtHoj5LcBJZ62AMVOAVc0hnxt45LMaCXgxJ4fw";
const np = await Nanopub.fetch(npUri);
expect(np.info().published).toBeDefined();
});

});
2 changes: 1 addition & 1 deletion lib/docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
- [Introduction](introduction.md)
- [Use from CLI](use_cli.md)
- [Use Rust crate](use_rust.md)
- [Use Python package](use_python.md)
- [Use NPM package](use_javascript.md)
- [Use Python package](use_python.md)
- [Contributing](contributing.md)
39 changes: 33 additions & 6 deletions lib/docs/use_javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ Install the `npm` package (use `yarn` or `pnpm` if you prefer) to use it from yo
npm install --save @nanopub/sign
```

Or directly import from a CDN in JavaScript code:

```typescript
import init, { Nanopub, NpProfile, getNpServer } from "https://unpkg.com/@nanopub/sign";
```

## ℹ️ How it works

This package provides several functionalities related to the handling of Nanopublications, including signing, publishing, verifying, and fetching them:
Expand All @@ -28,9 +34,9 @@ This package provides several functionalities related to the handling of Nanopub

This process involves signing a Nanopublication RDF string using a specified RSA private key passed through the profile. The signing operation ensures that the Nanopub is authentically created by the holder of the private key.

```admonish success title="Get a private key"
~~~admonish success title="Get a private key"
You can easily create and register a new private key on the [demo page](https://vemonet.github.io/nanopub-rs/demo.html) after login with your ORCID.
```
~~~

```typescript
import init, { Nanopub, NpProfile, getNpServer } from "@nanopub/sign";
Expand All @@ -42,21 +48,36 @@ console.log("Signed:", signed.info());

### 📬 Publish Nanopubs

After signing a Nanopub, it can be published to a Nanopub server. This makes the Nanopub accessible to others in the network.
Signed Nanopubs can be published to a Nanopub server. This makes the Nanopub accessible to others in the network.

Use the `publish` function on a Nanopub, the 2 arguments are optional:

- `profile` is required if you want to also sign the nanopub, it is not required if you provide a signed nanopub
- If the `server_url` is null it will be published to the test server

```typescript
const np = await new Nanopub(rdfStr).publish(profile, "");
import { Nanopub, NpProfile } from "@nanopub/sign";

const profile = new NpProfile(privateKey, "https://orcid.org/0000-0000-0000-0000", "Your Name", "");
const np = await new Nanopub(rdfStr).publish(profile, null);
console.log("Published:", np.info());
```

~~~admonish tip title="Provide the nanopub signed or unsigned"
- If signed nanopub and profile not provided, we publish the signed nanopub as it is
- If signed nanopub and profile provided, we re-sign the nanopub (only the triples related to the signature are changed)
- If unsigned nanopub and profile provided, we sign the nanopub
- If unsigned nanopub and profile not provided, we throw an error
~~~

#### 🧪 Test and productions servers

If the the last argument of `Nanopub.publish` is an empty string the nanopub will be published to the [test server](https://np.test.knowledgepixels.com/). In this case the nanopub will not be available at https://w3id.org/np/, but at https://np.test.knowledgepixels.com/, e.g. https://np.test.knowledgepixels.com/RAKObyGXmbgTYWj2iN0XGgJv0yWNDQd_DTmAWUouGfIsM
If the the last argument of `publish()` is null the nanopub will be published to the [test server](https://np.test.knowledgepixels.com/). In this case the nanopub will not be available at https://w3id.org/np/, but at https://np.test.knowledgepixels.com/, e.g. https://np.test.knowledgepixels.com/RAKObyGXmbgTYWj2iN0XGgJv0yWNDQd_DTmAWUouGfIsM

You can publish to the production network by getting the URL of a server using `getNpServer(true)` (true will pick a random nanopub server on the production network, while false will pick the [main nanopub server](https://server.np.trustyuri.net/)):

```typescript
import init, { Nanopub, NpProfile, getNpServer } from "https://unpkg.com/@nanopub/sign";
import init, { Nanopub, NpProfile, getNpServer } from "@nanopub/sign";

const np = await new Nanopub(rdfStr).publish(profile, getNpServer(true));
```
Expand All @@ -73,6 +94,12 @@ const checked = new Nanopub(rdfStr).check();

This function allows you to retrieve Nanopubs from the network using their URI. It's useful for accessing and using Nanopubs created by others.

```typescript
const npUri = "https://w3id.org/np/RAltRkGOtHoj5LcBJZ62AMVOAVc0hnxt45LMaCXgxJ4fw";
const np = await Nanopub.fetch(npUri);
console.log(np.info())
```


## 🚀 Use it in bare HTML files

Expand Down
42 changes: 42 additions & 0 deletions lib/docs/use_rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,32 @@ let published_np = rt.block_on(async {
println!("{}", published_np)
```

The `publish` function takes 2 optional arguments:

- `profile` is required if you want to also sign the nanopub, it is not required if you provide a signed nanopub
- If the `server_url` is none it will be published to the test server

~~~admonish tip title="Provide the nanopub signed or unsigned"
- If signed nanopub and profile not provided, we publish the signed nanopub as it is
- If signed nanopub and profile provided, we re-sign the nanopub (only the triples related to the signature are changed)
- If unsigned nanopub and profile provided, we sign the nanopub
- If unsigned nanopub and profile not provided, we throw an error
~~~

#### 🧪 Test and productions servers

If the the last argument of `publish()` is none the nanopub will be published to the [test server](https://np.test.knowledgepixels.com/). In this case the nanopub will not be available at https://w3id.org/np/, but at https://np.test.knowledgepixels.com/, e.g. https://np.test.knowledgepixels.com/RAKObyGXmbgTYWj2iN0XGgJv0yWNDQd_DTmAWUouGfIsM

You can publish to the production network by getting the URL of a server using `get_np_server(true)` (true will pick a random nanopub server on the production network, while false will pick the [main nanopub server](https://server.np.trustyuri.net/)), e.g.:

```rust
use nanopub::{Nanopub, NpProfile, NpError, get_np_server};

let published_np = rt.block_on(async {
Nanopub::new(np_rdf).unwrap().publish(Some(&profile), get_np_server(false)).await.unwrap()
});
```

## 🚀 Publish from scratch

You can also build the nanopub from scratch, and publish it:
Expand Down Expand Up @@ -90,6 +116,22 @@ async fn np_from_scratch() -> Result<(), NpError> {
}
```

## 📡 Fetch Nanopubs

The `fetch` static function on the `Nanopub` struct allows you to retrieve Nanopubs from the network using their URI. It's useful for accessing and using Nanopubs created by others.

```rust
use nanopub::{Nanopub, NpProfile, NpError};
use tokio::runtime;

let url = "https://w3id.org/np/RAltRkGOtHoj5LcBJZ62AMVOAVc0hnxt45LMaCXgxJ4fw";
let rt = runtime::Runtime::new().expect("Failed to create Tokio runtime");

let np = rt.block_on(async {
Nanopub::fetch(&url).await
}).unwrap();
```

## 📖 API reference

Checkout the **[API documentation](https://docs.rs/nanopub)** for more details on how to use the different components and functions of the rust crate.
2 changes: 1 addition & 1 deletion python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ name = "nanopub_sign"
crate-type = ["cdylib"]

[dependencies]
nanopub = { version = "0.0.17", path = "../lib" }
nanopub = { version = "0.0.18", path = "../lib" }
pyo3 = { version = "0.20", features = ["extension-module"] }
pyo3-asyncio = "0.20"
tokio = { version = "1.34", features = ["rt-multi-thread"] }
Expand Down

0 comments on commit c5635da

Please sign in to comment.