Compare commits
194 Commits
de2ac33050
...
d80f3d5d1a
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
@ -1,7 +1,16 @@ |
||||
*~ |
||||
*.tar.gz |
||||
.ng |
||||
.direnv |
||||
!.github |
||||
\#* |
||||
/target |
||||
/result* |
||||
.DS_Store |
||||
node_modules |
||||
*/tests/*.ng |
||||
*/tests/*.ngw |
||||
*/tests/*.pazzle |
||||
*/tests/*.mnemonic |
||||
*/ng-example/* |
||||
.vscode/settings.json |
||||
|
@ -1,17 +1,42 @@ |
||||
[workspace] |
||||
members = [ |
||||
"p2p-repo", |
||||
"p2p-net", |
||||
"p2p-broker", |
||||
"p2p-client-ws", |
||||
"p2p-verifier", |
||||
"p2p-stores-lmdb", |
||||
"nextgraph", |
||||
"ngcli", |
||||
"ngd", |
||||
"ng-app-js", |
||||
"ng-app-native/src-tauri", |
||||
"ng-repo", |
||||
"ng-net", |
||||
"ng-broker", |
||||
"ng-client-ws", |
||||
"ng-verifier", |
||||
"ng-wallet", |
||||
"ng-storage-rocksdb", |
||||
"ngone", |
||||
"ngaccount", |
||||
"ng-sdk-js", |
||||
"ng-app/src-tauri", |
||||
] |
||||
default-members = [ "nextgraph", "ngcli", "ngd" ] |
||||
|
||||
[workspace.package] |
||||
version = "0.1.0" |
||||
edition = "2021" |
||||
rust-version = "1.74.0" |
||||
license = "MIT/Apache-2.0" |
||||
authors = ["Niko PLP <niko@nextgraph.org>"] |
||||
repository = "https://git.nextgraph.org/NextGraph/nextgraph-rs" |
||||
homepage = "https://nextgraph.org" |
||||
keywords = [ |
||||
"crdt","dapp","decentralized","e2ee","local-first","p2p","semantic-web","eventual-consistency","json-ld","markdown", |
||||
"ocap","z-cap","offline-first","p2p-network","collaboration","privacy-protection","rdf","rich-text-editor","self-hosted", |
||||
"sparql","byzantine-fault-tolerance", |
||||
"web3", "graph-database", "database","triplestore" |
||||
] |
||||
documentation = "https://docs.nextgraph.org/" |
||||
|
||||
[profile.release] |
||||
lto = true |
||||
opt-level = 's' |
||||
opt-level = 's' |
||||
|
||||
[patch.crates-io] |
||||
# tauri = { git = "https://github.com/simonhyll/tauri.git", branch="fix/ipc-mixup"} |
||||
# tauri = { git = "https://git.nextgraph.org/NextGraph/tauri.git", branch="alpha.11-nextgraph", features = ["no-ipc-custom-protocol"] } |
@ -0,0 +1 @@ |
||||
tests |
@ -0,0 +1,49 @@ |
||||
[package] |
||||
name = "nextgraph" |
||||
description = "NextGraph client library. Nextgraph is a decentralized, secure and local-first web 3.0 ecosystem based on Semantic Web and CRDTs" |
||||
categories = ["asynchronous","text-editors","web-programming","development-tools","database-implementations"] |
||||
version.workspace = true |
||||
edition.workspace = true |
||||
license.workspace = true |
||||
authors.workspace = true |
||||
repository.workspace = true |
||||
homepage.workspace = true |
||||
keywords.workspace = true |
||||
documentation.workspace = true |
||||
rust-version.workspace = true |
||||
|
||||
[badges] |
||||
maintenance = { status = "actively-developed" } |
||||
|
||||
[dependencies] |
||||
ng-repo = { path = "../ng-repo", version = "0.1.0" } |
||||
ng-net = { path = "../ng-net", version = "0.1.0" } |
||||
ng-wallet = { path = "../ng-wallet", version = "0.1.0" } |
||||
ng-client-ws = { path = "../ng-client-ws", version = "0.1.0" } |
||||
ng-verifier = { path = "../ng-verifier", version = "0.1.0" } |
||||
async-once-cell = "0.5.3" |
||||
once_cell = "1.17.1" |
||||
serde = { version = "1.0", features = ["derive"] } |
||||
serde_bare = "0.5.0" |
||||
serde_bytes = "0.11.7" |
||||
base64-url = "2.0.0" |
||||
web-time = "0.2.0" |
||||
async-std = { version = "1.12.0", features = [ "attributes", "unstable" ] } |
||||
zeroize = { version = "1.6.0", features = ["zeroize_derive"] } |
||||
serde_json = "1.0" |
||||
async-trait = "0.1.64" |
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] |
||||
ng-storage-rocksdb = { path = "../ng-storage-rocksdb", version = "0.1.0" } |
||||
|
||||
[[example]] |
||||
name = "in_memory" |
||||
required-features = [] |
||||
|
||||
[[example]] |
||||
name = "persistent" |
||||
required-features = [] |
||||
|
||||
[[example]] |
||||
name = "open" |
||||
required-features = [] |
@ -0,0 +1,79 @@ |
||||
<p align="center"> |
||||
<img src="../.github/header.png" alt="nextgraph-header" /> |
||||
</p> |
||||
|
||||
# nextgraph |
||||
|
||||
![MSRV][rustc-image] |
||||
[![Apache 2.0 Licensed][license-image]][license-link] |
||||
[![MIT Licensed][license-image2]][license-link2] |
||||
![Crates.io Version](https://img.shields.io/crates/v/nextgraph) |
||||
![docs.rs](https://img.shields.io/docsrs/nextgraph) |
||||
|
||||
Rust client library of NextGraph framework |
||||
|
||||
This library is in active development at [https://git.nextgraph.org/NextGraph/nextgraph-rs](https://git.nextgraph.org/NextGraph/nextgraph-rs), a Gitea instance. For bug reports, issues, merge requests, and in order to join the dev team, please visit the link above and create an account (you can do so with a github account). The [github repo](https://github.com/nextgraph-org/nextgraph-rs) is just a read-only mirror that does not accept issues. |
||||
|
||||
## NextGraph |
||||
|
||||
> NextGraph brings about the convergence of P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs. |
||||
> |
||||
> This open source ecosystem provides solutions for end-users (a platform) and software developers (a framework), wishing to use or create **decentralized** apps featuring: **live collaboration** on rich-text documents, peer to peer communication with **end-to-end encryption**, offline-first, **local-first**, portable and interoperable data, total ownership of data and software, security and privacy. Centered on repositories containing **semantic data** (RDF), **rich text**, and structured data formats like **JSON**, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of **CRDTs**. Documents can be linked together, signed, shared securely, queried using the **SPARQL** language and organized into sites and containers. |
||||
> |
||||
> More info here [https://nextgraph.org](https://nextgraph.org) |
||||
|
||||
## Support |
||||
|
||||
This crate has official documentation at [docs.rs](https://docs.rs/nextgraph/0.1.0/nextgraph/) |
||||
|
||||
Documentation can be found here [https://docs.nextgraph.org](https://docs.nextgraph.org) |
||||
|
||||
And our community forum where you can ask questions is here [https://forum.nextgraph.org](https://forum.nextgraph.org) |
||||
|
||||
## Status |
||||
|
||||
NextGraph is not ready yet. You can subscribe to [our newsletter](https://list.nextgraph.org/subscription/form) to get updates, and support us with a [donation](https://nextgraph.org/donate/). |
||||
|
||||
## Dependencies |
||||
|
||||
Nextgraph library is dependent on [async-std](https://async.rs/). You must include it in your `Cargo.toml`. |
||||
A tokio-based version (as a feature) might be available in the future. |
||||
|
||||
```toml |
||||
[dependencies] |
||||
nextgraph = "0.1.0" |
||||
async-std = "1.12.0" |
||||
``` |
||||
|
||||
## Examples |
||||
|
||||
You can find some examples on how to use the library: |
||||
|
||||
- [in_memory](examples/in_memory) |
||||
- [persistent](examples/persistent) |
||||
|
||||
## License |
||||
|
||||
Licensed under either of |
||||
|
||||
- Apache License, Version 2.0 ([LICENSE-APACHE2](LICENSE-APACHE2) or http://www.apache.org/licenses/LICENSE-2.0) |
||||
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) |
||||
at your option. |
||||
|
||||
`SPDX-License-Identifier: Apache-2.0 OR MIT` |
||||
|
||||
### Contributions license |
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted |
||||
for inclusion in the work by you shall be dual licensed as below, without any |
||||
additional terms or conditions. |
||||
|
||||
--- |
||||
|
||||
NextGraph received funding through the [NGI Assure Fund](https://nlnet.nl/project/NextGraph/index.html), a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 957073. |
||||
|
||||
[rustc-image]: https://img.shields.io/badge/rustc-1.74+-blue.svg |
||||
[license-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg |
||||
[license-link]: https://git.nextgraph.org/NextGraph/nextgraph-rs/raw/branch/master/LICENSE-APACHE2 |
||||
[license-image2]: https://img.shields.io/badge/license-MIT-blue.svg |
||||
[license-link2]: https://git.nextgraph.org/NextGraph/nextgraph-rs/src/branch/master/LICENSE-MIT |
@ -0,0 +1,17 @@ |
||||
# Examples |
||||
|
||||
Some examples of using `nextgraph` client library |
||||
|
||||
run them with: |
||||
|
||||
``` |
||||
cargo run -p nextgraph --example in_memory |
||||
cargo run -p nextgraph --example persistent |
||||
cargo run -p nextgraph --example open |
||||
``` |
||||
|
||||
See the code: |
||||
|
||||
- [in_memory](in_memory.md) |
||||
- [persistent](persistent.md) |
||||
- [open](open.md) |
@ -0,0 +1,13 @@ |
||||
# in-memory LocalBroker |
||||
|
||||
Example of LocalBroker configured with in-memory (no persistence). |
||||
|
||||
run with: |
||||
|
||||
``` |
||||
cargo run -p nextgraph -r --example in_memory |
||||
``` |
||||
|
||||
we assume that you run this command from the root of the git repo (nextgraph-rs) |
||||
|
||||
the `-r` for release version is important, without it, the creation and opening of the wallet will take ages. |
@ -0,0 +1,167 @@ |
||||
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||
// All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// at your option. All files in the project carrying such
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use nextgraph::local_broker::{ |
||||
doc_fetch, init_local_broker, session_start, session_stop, user_connect, user_disconnect, |
||||
wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import, |
||||
wallet_open_with_pazzle_words, wallet_read_file, wallet_was_opened, LocalBrokerConfig, |
||||
SessionConfig, |
||||
}; |
||||
use nextgraph::net::types::BootstrapContentV0; |
||||
use nextgraph::repo::errors::NgError; |
||||
use nextgraph::repo::types::PubKey; |
||||
use nextgraph::wallet::types::CreateWalletV0; |
||||
use nextgraph::wallet::{display_mnemonic, emojis::display_pazzle}; |
||||
|
||||
use std::env::current_dir; |
||||
use std::fs::read; |
||||
|
||||
#[async_std::main] |
||||
async fn main() -> std::io::Result<()> { |
||||
// initialize the local_broker with in-memory config.
|
||||
// all sessions will be lost when the program exits
|
||||
init_local_broker(Box::new(|| LocalBrokerConfig::InMemory)).await; |
||||
|
||||
// load some image that will be used as security_img
|
||||
// we assume here for the sake of this example,
|
||||
// that the current directory contains this demo image file
|
||||
let security_img = read("nextgraph/examples/wallet-security-image-demo.png")?; |
||||
|
||||
// the peer_id should come from somewhere else.
|
||||
// this is just given for the sake of an example
|
||||
#[allow(deprecated)] |
||||
let peer_id_of_server_broker = PubKey::nil(); |
||||
|
||||
// Create your wallet
|
||||
// this will take some time !
|
||||
println!("Creating the wallet. this will take some time..."); |
||||
|
||||
let wallet_result = wallet_create_v0(CreateWalletV0 { |
||||
security_img, |
||||
security_txt: "know yourself".to_string(), |
||||
pin: [1, 2, 1, 2], |
||||
pazzle_length: 9, |
||||
send_bootstrap: false, |
||||
send_wallet: false, |
||||
result_with_wallet_file: true, |
||||
local_save: false, |
||||
// we default to localhost:14400. this is just for the sake of an example
|
||||
core_bootstrap: BootstrapContentV0::new_localhost(peer_id_of_server_broker), |
||||
core_registration: None, |
||||
additional_bootstrap: None, |
||||
}) |
||||
.await?; |
||||
|
||||
println!("Your wallet name is : {}", wallet_result.wallet_name); |
||||
|
||||
let pazzle = display_pazzle(&wallet_result.pazzle); |
||||
let mut pazzle_words = vec![]; |
||||
println!("Your pazzle is: {:?}", wallet_result.pazzle); |
||||
for emoji in pazzle { |
||||
println!(" {}:\t{}", emoji.0, emoji.1); |
||||
pazzle_words.push(emoji.1.to_string()); |
||||
} |
||||
println!("Your mnemonic is:"); |
||||
display_mnemonic(&wallet_result.mnemonic) |
||||
.iter() |
||||
.for_each(|word| print!("{} ", word.as_str())); |
||||
println!(""); |
||||
|
||||
// A session has been opened for you and you can directly use it without the need to call [wallet_was_opened] nor [session_start].
|
||||
let user_id = wallet_result.personal_identity(); |
||||
|
||||
// if the user has internet access, they can now decide to connect to its Server Broker, in order to sync data
|
||||
let status = user_connect(&user_id).await?; |
||||
|
||||
// The connection cannot succeed because we miss-configured the core_bootstrap of the wallet. its Peer ID is invalid.
|
||||
let error_reason = status[0].3.as_ref().unwrap(); |
||||
assert!(error_reason == "NoiseHandshakeFailed" || error_reason == "ConnectionError"); |
||||
|
||||
// a session ID has been assigned to you in `wallet_result.session_id` you can use it to fetch a document
|
||||
//let _ = doc_fetch(wallet_result.session_id, "ng:example".to_string(), None).await?;
|
||||
|
||||
// Then we should disconnect
|
||||
user_disconnect(&user_id).await?; |
||||
|
||||
// if you need the Wallet File again (if you didn't select `result_with_wallet_file` by example), you can retrieve it with:
|
||||
let wallet_file = wallet_get_file(&wallet_result.wallet_name).await?; |
||||
|
||||
// if you did ask for `result_with_wallet_file`, as we did above, then the 2 vectors should be identical
|
||||
assert_eq!(wallet_file, wallet_result.wallet_file); |
||||
|
||||
// stop the session
|
||||
session_stop(&user_id).await?; |
||||
|
||||
// closes the wallet
|
||||
wallet_close(&wallet_result.wallet_name).await?; |
||||
|
||||
// if you have saved the wallet locally (which we haven't done in the example above, see `local_save: false`), next time you want to connect,
|
||||
// you can retrieve the wallet, display the security phrase and image to the user, ask for the pazzle or mnemonic, and then open the wallet
|
||||
// if you haven't saved the wallet, the next line will not work once you restart the LocalBroker.
|
||||
let wallet = wallet_get(&wallet_result.wallet_name).await?; |
||||
|
||||
// at this point, the wallet is kept in the internal memory of the LocalBroker
|
||||
// and it hasn't been opened yet, so it is not usable right away.
|
||||
// now let's open the wallet, by providing the pazzle and PIN code
|
||||
let opened_wallet = |
||||
wallet_open_with_pazzle_words(&wallet_result.wallet, &pazzle_words, [1, 2, 1, 2])?; |
||||
|
||||
// once the wallet is opened, we notify the LocalBroker that we have opened it.
|
||||
let _client = wallet_was_opened(opened_wallet).await?; |
||||
|
||||
// if instead of saving the wallet locally, you want to provide the Wallet File for every login,
|
||||
// then you have to import the wallet. here is an example:
|
||||
{ |
||||
// this part should happen on another device or on the same machine if you haven't saved the wallet locally
|
||||
|
||||
// you could use the Wallet File and import it there so it could be used for login.
|
||||
// first you would read and decode the Wallet File
|
||||
// this fails here because we already added this wallet in the LocalBroker (when we created it).
|
||||
// But on another device or after a restart of LocalBroker, it would work.
|
||||
let wallet = wallet_read_file(wallet_file).await; |
||||
assert_eq!(wallet.unwrap_err(), NgError::WalletAlreadyAdded); |
||||
|
||||
// we would then open the wallet
|
||||
// (here we take the Wallet as we received it from wallet_create_v0, but in real case you would use `wallet`)
|
||||
let opened_wallet2 = |
||||
wallet_open_with_pazzle_words(&wallet_result.wallet, &pazzle_words, [1, 2, 1, 2])?; |
||||
|
||||
// once it has been opened, the Wallet can be imported into the LocalBroker
|
||||
// if you try to import the same wallet in a LocalBroker where it is already opened, it will fail.
|
||||
// So here it fails. But on another device, it would work.
|
||||
let client_fail = wallet_import(wallet_result.wallet.clone(), opened_wallet2, true).await; |
||||
assert_eq!(client_fail.unwrap_err(), NgError::WalletAlreadyAdded); |
||||
} |
||||
|
||||
// now that the wallet is opened or imported, let's start a session.
|
||||
// we pass the user_id and the wallet_name
|
||||
let _session = session_start(SessionConfig::new_in_memory( |
||||
&user_id, |
||||
&wallet_result.wallet_name, |
||||
)) |
||||
.await?; |
||||
|
||||
// if the user has internet access, they can now decide to connect to its Server Broker, in order to sync data
|
||||
let status = user_connect(&user_id).await?; |
||||
|
||||
// The connection cannot succeed because we miss-configured the core_bootstrap of the wallet. its Peer ID is invalid.
|
||||
let error_reason = status[0].3.as_ref().unwrap(); |
||||
assert!(error_reason == "NoiseHandshakeFailed" || error_reason == "ConnectionError"); |
||||
|
||||
// Then we should disconnect
|
||||
user_disconnect(&user_id).await?; |
||||
|
||||
// stop the session
|
||||
session_stop(&user_id).await?; |
||||
|
||||
// closes the wallet
|
||||
wallet_close(&wallet_result.wallet_name).await?; |
||||
|
||||
Ok(()) |
||||
} |
@ -0,0 +1,17 @@ |
||||
# open LocalBroker |
||||
|
||||
Example of LocalBroker configured with persistence to disk, and opening of a previsouly saved wallet |
||||
|
||||
You need to replace `wallet_name` on line 40 with the name that was given to you when you ran the example [persistent], in `Your wallet name is : ` |
||||
|
||||
You need to replace the argument `pazzle` in the function call `wallet_open_with_pazzle` with the array that you received in `Your pazzle is:` |
||||
|
||||
then, run with: |
||||
|
||||
``` |
||||
cargo run -p nextgraph -r --example open |
||||
``` |
||||
|
||||
we assume that you run this command from the root of the git repo (nextgraph-rs). |
||||
|
||||
the `-r` for release version is important, without it, the creation and opening of the wallet will take ages. |
@ -0,0 +1,81 @@ |
||||
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||
// All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// at your option. All files in the project carrying such
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use nextgraph::local_broker::{ |
||||
doc_fetch, init_local_broker, session_start, session_stop, user_connect, user_disconnect, |
||||
wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import, |
||||
wallet_open_with_pazzle, wallet_open_with_pazzle_words, wallet_read_file, wallet_was_opened, |
||||
LocalBrokerConfig, SessionConfig, |
||||
}; |
||||
use nextgraph::net::types::BootstrapContentV0; |
||||
use nextgraph::repo::errors::NgError; |
||||
use nextgraph::repo::types::PubKey; |
||||
use nextgraph::wallet::types::CreateWalletV0; |
||||
use nextgraph::wallet::{display_mnemonic, emojis::display_pazzle}; |
||||
|
||||
use std::env::current_dir; |
||||
use std::fs::create_dir_all; |
||||
use std::fs::read; |
||||
|
||||
#[async_std::main] |
||||
async fn main() -> std::io::Result<()> { |
||||
// get the current working directory
|
||||
let mut current_path = current_dir()?; |
||||
current_path.push(".ng"); |
||||
current_path.push("example"); |
||||
create_dir_all(current_path.clone())?; |
||||
|
||||
// initialize the local_broker with config to save to disk in a folder called `.ng/example` in the current directory
|
||||
init_local_broker(Box::new(move || { |
||||
LocalBrokerConfig::BasePath(current_path.clone()) |
||||
})) |
||||
.await; |
||||
|
||||
let wallet_name = "9ivXl3TpgcQlDKTmR9NOipjhPWxQw6Yg5jkWBTlJuXw".to_string(); |
||||
|
||||
// as we have previously saved the wallet,
|
||||
// we can retrieve it, display the security phrase and image to the user, ask for the pazzle or mnemonic, and then open the wallet
|
||||
let wallet = wallet_get(&wallet_name).await?; |
||||
|
||||
// at this point, the wallet is kept in the internal memory of the LocalBroker
|
||||
// and it hasn't been opened yet, so it is not usable right away.
|
||||
// now let's open the wallet, by providing the pazzle and PIN code
|
||||
let opened_wallet = wallet_open_with_pazzle( |
||||
&wallet, |
||||
vec![110, 139, 115, 94, 9, 40, 74, 25, 52], |
||||
[2, 3, 2, 3], |
||||
)?; |
||||
|
||||
let user_id = opened_wallet.personal_identity(); |
||||
|
||||
// once the wallet is opened, we notify the LocalBroker that we have opened it.
|
||||
let _client = wallet_was_opened(opened_wallet).await?; |
||||
|
||||
// now that the wallet is opened, let's start a session.
|
||||
// we pass the user_id and the wallet_name
|
||||
let _session = session_start(SessionConfig::new_save(&user_id, &wallet_name)).await?; |
||||
|
||||
// if the user has internet access, they can now decide to connect to its Server Broker, in order to sync data
|
||||
let status = user_connect(&user_id).await?; |
||||
|
||||
// The connection cannot succeed because we miss-configured the core_bootstrap of the wallet. its Peer ID is invalid.
|
||||
println!("Connection was : {:?}", status[0]); |
||||
//assert!(error_reason == "NoiseHandshakeFailed" || error_reason == "ConnectionError");
|
||||
|
||||
// Then we should disconnect
|
||||
user_disconnect(&user_id).await?; |
||||
|
||||
// stop the session
|
||||
session_stop(&user_id).await?; |
||||
|
||||
// closes the wallet
|
||||
wallet_close(&wallet_name).await?; |
||||
|
||||
Ok(()) |
||||
} |
@ -0,0 +1,13 @@ |
||||
# persistent LocalBroker |
||||
|
||||
Example of LocalBroker configured with persistence to disk |
||||
|
||||
run with: |
||||
|
||||
``` |
||||
cargo run -p nextgraph -r --example persistent |
||||
``` |
||||
|
||||
we assume that you run this command from the root of the git repo (nextgraph-rs). |
||||
|
||||
the `-r` for release version is important, without it, the creation and opening of the wallet will take ages. |
@ -0,0 +1,150 @@ |
||||
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
|
||||
// All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// at your option. All files in the project carrying such
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use nextgraph::local_broker::{ |
||||
doc_fetch, init_local_broker, session_start, session_stop, user_connect, user_disconnect, |
||||
wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import, |
||||
wallet_open_with_pazzle_words, wallet_read_file, wallet_was_opened, LocalBrokerConfig, |
||||
SessionConfig, |
||||
}; |
||||
use nextgraph::net::types::BootstrapContentV0; |
||||
use nextgraph::repo::errors::NgError; |
||||
use nextgraph::repo::types::PubKey; |
||||
use nextgraph::wallet::types::CreateWalletV0; |
||||
use nextgraph::wallet::{display_mnemonic, emojis::display_pazzle}; |
||||
|
||||
use std::env::current_dir; |
||||
use std::fs::create_dir_all; |
||||
use std::fs::read; |
||||
|
||||
#[async_std::main] |
||||
async fn main() -> std::io::Result<()> { |
||||
// get the current working directory
|
||||
let mut current_path = current_dir()?; |
||||
current_path.push(".ng"); |
||||
current_path.push("example"); |
||||
create_dir_all(current_path.clone())?; |
||||
|
||||
// initialize the local_broker with config to save to disk in a folder called `.ng/example` in the current directory
|
||||
init_local_broker(Box::new(move || { |
||||
LocalBrokerConfig::BasePath(current_path.clone()) |
||||
})) |
||||
.await; |
||||
|
||||
// load some image that will be used as security_img
|
||||
// we assume here for the sake of this example,
|
||||
// that the current directory contains this demo image file
|
||||
let security_img = read("nextgraph/examples/wallet-security-image-demo.png")?; |
||||
|
||||
// the peer_id should come from somewhere else.
|
||||
// this is just given for the sake of an example
|
||||
let peer_id_of_server_broker = PubKey::nil(); |
||||
|
||||
// Create your wallet
|
||||
// this will take some time !
|
||||
println!("Creating the wallet. this will take some time..."); |
||||
|
||||
let wallet_result = wallet_create_v0(CreateWalletV0 { |
||||
security_img, |
||||
security_txt: "know yourself".to_string(), |
||||
pin: [1, 2, 1, 2], |
||||
pazzle_length: 9, |
||||
send_bootstrap: false, |
||||
send_wallet: false, |
||||
result_with_wallet_file: true, |
||||
local_save: true, |
||||
// we default to localhost:14400. this is just for the sake of an example
|
||||
core_bootstrap: BootstrapContentV0::new_localhost(peer_id_of_server_broker), |
||||
core_registration: None, |
||||
additional_bootstrap: None, |
||||
}) |
||||
.await?; |
||||
|
||||
println!("Your wallet name is : {}", wallet_result.wallet_name); |
||||
|
||||
let pazzle = display_pazzle(&wallet_result.pazzle); |
||||
let mut pazzle_words = vec![]; |
||||
println!("Your pazzle is: {:?}", wallet_result.pazzle); |
||||
for emoji in pazzle { |
||||
println!(" {}:\t{}", emoji.0, emoji.1); |
||||
pazzle_words.push(emoji.1.to_string()); |
||||
} |
||||
println!("Your mnemonic is:"); |
||||
display_mnemonic(&wallet_result.mnemonic) |
||||
.iter() |
||||
.for_each(|word| print!("{} ", word.as_str())); |
||||
println!(""); |
||||
|
||||
// A session has been opened for you and you can directly use it without the need to call [wallet_was_opened] nor [session_start].
|
||||
let user_id = wallet_result.personal_identity(); |
||||
|
||||
// if the user has internet access, they can now decide to connect to its Server Broker, in order to sync data
|
||||
let status = user_connect(&user_id).await?; |
||||
|
||||
// The connection cannot succeed because we miss-configured the core_bootstrap of the wallet. its Peer ID is invalid.
|
||||
let error_reason = status[0].3.as_ref().unwrap(); |
||||
assert!(error_reason == "NoiseHandshakeFailed" || error_reason == "ConnectionError"); |
||||
|
||||
// a session ID has been assigned to you in `wallet_result.session_id` you can use it to fetch a document
|
||||
//let _ = doc_fetch(wallet_result.session_id, "ng:example".to_string(), None).await?;
|
||||
|
||||
// Then we should disconnect
|
||||
user_disconnect(&user_id).await?; |
||||
|
||||
// if you need the Wallet File again (if you didn't select `result_with_wallet_file` by example), you can retrieve it with:
|
||||
let wallet_file = wallet_get_file(&wallet_result.wallet_name).await?; |
||||
|
||||
// if you did ask for `result_with_wallet_file`, as we did above, then the 2 vectors should be identical
|
||||
assert_eq!(wallet_file, wallet_result.wallet_file); |
||||
|
||||
// stop the session
|
||||
session_stop(&user_id).await?; |
||||
|
||||
// closes the wallet
|
||||
wallet_close(&wallet_result.wallet_name).await?; |
||||
|
||||
// as we have saved the wallet, the next time we want to connect,
|
||||
// we can retrieve the wallet, display the security phrase and image to the user, ask for the pazzle or mnemonic, and then open the wallet
|
||||
let wallet = wallet_get(&wallet_result.wallet_name).await?; |
||||
|
||||
// at this point, the wallet is kept in the internal memory of the LocalBroker
|
||||
// and it hasn't been opened yet, so it is not usable right away.
|
||||
// now let's open the wallet, by providing the pazzle and PIN code
|
||||
let opened_wallet = |
||||
wallet_open_with_pazzle_words(&wallet_result.wallet, &pazzle_words, [1, 2, 1, 2])?; |
||||
|
||||
// once the wallet is opened, we notify the LocalBroker that we have opened it.
|
||||
let _client = wallet_was_opened(opened_wallet).await?; |
||||
|
||||
// now that the wallet is opened, let's start a session.
|
||||
// we pass the user_id and the wallet_name
|
||||
let _session = session_start(SessionConfig::new_save( |
||||
&user_id, |
||||
&wallet_result.wallet_name, |
||||
)) |
||||
.await?; |
||||
|
||||
// if the user has internet access, they can now decide to connect to its Server Broker, in order to sync data
|
||||
let status = user_connect(&user_id).await?; |
||||
|
||||
// The connection cannot succeed because we miss-configured the core_bootstrap of the wallet. its Peer ID is invalid.
|
||||
let error_reason = status[0].3.as_ref().unwrap(); |
||||
assert!(error_reason == "NoiseHandshakeFailed" || error_reason == "ConnectionError"); |
||||
|
||||
// Then we should disconnect
|
||||
user_disconnect(&user_id).await?; |
||||
|
||||
// stop the session
|
||||
session_stop(&user_id).await?; |
||||
|
||||
// closes the wallet
|
||||
wallet_close(&wallet_result.wallet_name).await?; |
||||
|
||||
Ok(()) |
||||
} |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
@ -0,0 +1,62 @@ |
||||
#![doc(html_logo_url = "https://file.nextgraph.org/download/1fd175bb6d7d832156bd5ad4abcdee7e")] |
||||
#![doc(issue_tracker_base_url = "https://git.nextgraph.org/NextGraph/nextgraph-rs/issues")] |
||||
#![doc(html_favicon_url = "https://nextgraph.org/favicon.svg")] |
||||
//! # NextGraph framework client library
|
||||
//!
|
||||
//! NextGraph brings about the convergence of P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs.
|
||||
//!
|
||||
//! This open source ecosystem provides solutions for end-users (a platform) and software developers (a framework), wishing to use or create **decentralized** apps featuring: **live collaboration** on rich-text documents, peer to peer communication with **end-to-end encryption**, offline-first, **local-first**, portable and interoperable data, total ownership of data and software, security and privacy. Centered on repositories containing **semantic data** (RDF), **rich text**, and structured data formats like **JSON**, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of **CRDTs**. Documents can be linked together, signed, shared securely, queried using the **SPARQL** language and organized into sites and containers.
|
||||
//!
|
||||
//! More info here [https://nextgraph.org](https://nextgraph.org). Documentation available here [https://docs.nextgraph.org](https://docs.nextgraph.org).
|
||||
//!
|
||||
//! ## LocalBroker, the entrypoint to NextGraph network
|
||||
//!
|
||||
//! `local_broker` contains the API for controlling the Local Broker, which is a reduced instance of the network Broker.
|
||||
//! This is your entrypoint to NextGraph network.
|
||||
//! It runs embedded in your client program, and once configured (by opening a Session), it can keep for you (on disk or in memory):
|
||||
//! - the blocks of the repos,
|
||||
//! - the connection(s) to your Server Broker
|
||||
//! - the events that you send to the Overlay, if there is no connectivity (Outbox)
|
||||
//! - A reference to the verifier
|
||||
//!
|
||||
//! In addition, the API for creating and managing your wallet is provided here.
|
||||
//!
|
||||
//! The same API is also made available in Javascript for the browser (and is used by our webapp), nodejs, in the CLI, and for all the Tauri-based Apps.
|
||||
//!
|
||||
//! The library requires `async-std` minimal version 1.12.0
|
||||
//!
|
||||
//! See [examples](https://git.nextgraph.org/NextGraph/nextgraph-rs/src/branch/master/nextgraph/examples) for a quick start.
|
||||
//!
|
||||
//! ## In-memory
|
||||
//!
|
||||
//! With this config, no data will be persisted to disk.
|
||||
//!
|
||||
//! ```
|
||||
//! use nextgraph::local_broker::{init_local_broker, LocalBrokerConfig};
|
||||
//!
|
||||
//! #[async_std::main]
|
||||
//! async fn main() -> std::io::Result<()> {
|
||||
//! // initialize the local_broker with in-memory config.
|
||||
//! // all sessions will be lost when the program exits
|
||||
//! init_local_broker(Box::new(|| LocalBrokerConfig::InMemory)).await;
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
pub mod local_broker; |
||||
|
||||
pub mod repo { |
||||
pub use ng_repo::*; |
||||
} |
||||
|
||||
pub mod net { |
||||
pub use ng_net::*; |
||||
} |
||||
|
||||
pub mod verifier { |
||||
pub use ng_verifier::*; |
||||
} |
||||
|
||||
pub mod wallet { |
||||
pub use ng_wallet::*; |
||||
} |
@ -1,116 +0,0 @@ |
||||
# ng-app-js |
||||
|
||||
JS/WASM module of NextGraph (SDK and apps) |
||||
|
||||
## NextGraph |
||||
|
||||
> NextGraph brings about the convergence between P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs. |
||||
> |
||||
> This open source ecosystem provides solutions for end-users and software developers alike, wishing to use or create **decentralized** apps featuring: **live collaboration** on rich-text documents, peer to peer communication with end-to-end encryption, offline-first, **local-first**, portable and interoperable data, total ownership of data and software, security and privacy. Centered on repositories containing **semantic data** (RDF), **rich text**, and structured data formats like **JSON**, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of **CRDTs**. Documents can be linked together, signed, shared securely, queried using the **SPARQL** language and organized into sites and containers. |
||||
> |
||||
> More info here [https://nextgraph.org](https://nextgraph.org) |
||||
|
||||
## JS/WASM module |
||||
|
||||
This module is part of the SDK of NextGraph. |
||||
|
||||
It is composed of |
||||
- the npm package `ng-app-js` which is the SDK |
||||
- the plain JS web app `app-web` |
||||
- the React web app `app-react` |
||||
- the node-js app `app-node` |
||||
|
||||
## Support |
||||
|
||||
Documentation can be found here [https://docs.nextgraph.org](https://docs.nextgraph.org) |
||||
|
||||
And our community forum where you can ask questions is here [https://forum.nextgraph.org](https://forum.nextgraph.org) |
||||
|
||||
## For developers |
||||
|
||||
Read our [getting started guide](https://docs.nextgraph.org/en/getting-started/). |
||||
|
||||
``` |
||||
npm i ng-app-js-sdk |
||||
``` |
||||
|
||||
## For contributors |
||||
|
||||
``` |
||||
wasm-pack build --target bundler |
||||
cd pkg |
||||
// if you have access to npm registry and want to publish the package |
||||
// npm publish --access=public |
||||
|
||||
cd .. |
||||
wasm-pack build -t nodejs -d pkg-node |
||||
node prepare-node.js |
||||
cd pkg-node |
||||
// if you have access to npm registry and want to publish the package |
||||
// npm publish --access=public |
||||
``` |
||||
|
||||
For testing in vanilla JS |
||||
``` |
||||
wasm-pack build --target web -d web |
||||
python3 -m http.server |
||||
// open http://localhost:8000 |
||||
|
||||
``` |
||||
Or automated testing with headless chrome: |
||||
``` |
||||
wasm-pack test --chrome --headless |
||||
``` |
||||
|
||||
### Plain JS web app |
||||
|
||||
``` |
||||
cd ../app-web |
||||
// for local development |
||||
npm install --no-save ../pkg |
||||
// or, for install from npm registry: npm install |
||||
npm start |
||||
``` |
||||
|
||||
Open this URL in browser : [http://localhost:8080](http://localhost:8080) |
||||
|
||||
### React web app |
||||
|
||||
``` |
||||
cd ../app-react |
||||
// for local development |
||||
npm install --no-save ../pkg |
||||
// or, for install from npm registry: npm install |
||||
npm run dev |
||||
``` |
||||
|
||||
Open this URL in browser : [http://localhost:8080](http://localhost:8080) |
||||
|
||||
### NodeJS app |
||||
|
||||
``` |
||||
cd ../app-node |
||||
// for local development |
||||
npm install --no-save ../pkg-node |
||||
// or, for install from npm registry: npm install |
||||
npm run start |
||||
``` |
||||
|
||||
### Contributions license |
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted |
||||
for inclusion in the work by you shall be dual licensed as below, without any |
||||
additional terms or conditions.s |
||||
|
||||
## License |
||||
|
||||
Licensed under either of |
||||
* Apache License, Version 2.0 ([LICENSE-APACHE2](LICENSE-APACHE2) or http://www.apache.org/licenses/LICENSE-2.0) |
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) |
||||
at your option. |
||||
|
||||
`SPDX-License-Identifier: Apache-2.0 OR MIT` |
||||
|
||||
--- |
||||
|
||||
NextGraph received funding through the [NGI Assure Fund](https://nlnet.nl/project/NextGraph/index.html), a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 957073. |
@ -1,41 +0,0 @@ |
||||
# ng-app-react |
||||
|
||||
React app client of NextGraph |
||||
|
||||
## NextGraph |
||||
|
||||
> NextGraph brings about the convergence between P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs. |
||||
> |
||||
> This open source ecosystem provides solutions for end-users and software developers alike, wishing to use or create **decentralized** apps featuring: **live collaboration** on rich-text documents, peer to peer communication with end-to-end encryption, offline-first, **local-first**, portable and interoperable data, total ownership of data and software, security and privacy. Centered on repositories containing **semantic data** (RDF), **rich text**, and structured data formats like **JSON**, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of **CRDTs**. Documents can be linked together, signed, shared securely, queried using the **SPARQL** language and organized into sites and containers. |
||||
> |
||||
> More info here [https://nextgraph.org](https://nextgraph.org) |
||||
|
||||
## For contributors |
||||
|
||||
Build the JS SDK |
||||
|
||||
``` |
||||
cd .. |
||||
wasm-pack build --target bundler |
||||
``` |
||||
|
||||
``` |
||||
cd app-react |
||||
npm install --no-save ../pkg |
||||
npm run dev |
||||
``` |
||||
|
||||
Open this URL in browser : [http://localhost:8080](http://localhost:8080) |
||||
|
||||
## License |
||||
|
||||
Licensed under either of |
||||
* Apache License, Version 2.0 ([LICENSE-APACHE2](LICENSE-APACHE2) or http://www.apache.org/licenses/LICENSE-2.0) |
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) |
||||
at your option. |
||||
|
||||
`SPDX-License-Identifier: Apache-2.0 OR MIT` |
||||
|
||||
--- |
||||
|
||||
NextGraph received funding through the [NGI Assure Fund](https://nlnet.nl/project/NextGraph/index.html), a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 957073. |
@ -1,41 +0,0 @@ |
||||
# ng-app-web |
||||
|
||||
Web app client of NextGraph |
||||
|
||||
## NextGraph |
||||
|
||||
> NextGraph brings about the convergence between P2P and Semantic Web technologies, towards a decentralized, secure and privacy-preserving cloud, based on CRDTs. |
||||
> |
||||
> This open source ecosystem provides solutions for end-users and software developers alike, wishing to use or create **decentralized** apps featuring: **live collaboration** on rich-text documents, peer to peer communication with end-to-end encryption, offline-first, **local-first**, portable and interoperable data, total ownership of data and software, security and privacy. Centered on repositories containing **semantic data** (RDF), **rich text**, and structured data formats like **JSON**, synced between peers belonging to permissioned groups of users, it offers strong eventual consistency, thanks to the use of **CRDTs**. Documents can be linked together, signed, shared securely, queried using the **SPARQL** language and organized into sites and containers. |
||||
> |
||||
> More info here [https://nextgraph.org](https://nextgraph.org) |
||||
|
||||
## For contributors |
||||
|
||||
Build the JS SDK |
||||
|
||||
``` |
||||
cd .. |
||||
wasm-pack build --target bundler |
||||
``` |
||||
|
||||
``` |
||||
cd app-web |
||||
npm install --no-save ../pkg |
||||
npm start |
||||
``` |
||||
|
||||
Open this URL in browser : [http://localhost:8080](http://localhost:8080) |
||||
|
||||
## License |
||||
|
||||
Licensed under either of |
||||
* Apache License, Version 2.0 ([LICENSE-APACHE2](LICENSE-APACHE2) or http://www.apache.org/licenses/LICENSE-2.0) |
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) |
||||
at your option. |
||||
|
||||
`SPDX-License-Identifier: Apache-2.0 OR MIT` |
||||
|
||||
--- |
||||
|
||||
NextGraph received funding through the [NGI Assure Fund](https://nlnet.nl/project/NextGraph/index.html), a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 957073. |
@ -1,128 +0,0 @@ |
||||
/* |
||||
* Copyright (c) 2022-2023 Niko Bonnieure, Par le Peuple, NextGraph.org developers |
||||
* All rights reserved. |
||||
* Licensed under the Apache License, Version 2.0 |
||||
* <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
||||
* or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
* at your option. All files in the project carrying such |
||||
* notice may not be copied, modified, or distributed except |
||||
* according to those terms. |
||||
*/ |
||||
|
||||
use async_std::task; |
||||
// #[cfg(target_arch = "wasm32")]
|
||||
// use js_sys::Reflect;
|
||||
#[cfg(target_arch = "wasm32")] |
||||
use p2p_client_ws::remote_ws_wasm::ConnectionWebSocket; |
||||
use p2p_net::broker::*; |
||||
use p2p_net::connection::{ClientConfig, StartConfig}; |
||||
use p2p_net::types::{DirectPeerId, IP}; |
||||
use p2p_net::utils::{spawn_and_log_error, ResultSend}; |
||||
use p2p_net::{log, sleep}; |
||||
use p2p_repo::types::PubKey; |
||||
use p2p_repo::utils::generate_keypair; |
||||
use std::net::IpAddr; |
||||
use std::str::FromStr; |
||||
use std::sync::Arc; |
||||
use wasm_bindgen::prelude::*; |
||||
|
||||
#[wasm_bindgen] |
||||
extern "C" { |
||||
pub fn alert(s: &str); |
||||
} |
||||
|
||||
#[cfg(target_arch = "wasm32")] |
||||
#[wasm_bindgen] |
||||
pub async fn start() { |
||||
// let mut random_buf = [0u8; 32];
|
||||
// getrandom::getrandom(&mut random_buf).unwrap();
|
||||
|
||||
async fn inner_task() -> ResultSend<()> { |
||||
let server_key = PubKey::Ed25519PubKey([ |
||||
95, 155, 249, 202, 41, 105, 71, 51, 206, 126, 9, 84, 132, 92, 60, 7, 74, 179, 46, 21, |
||||
21, 242, 171, 27, 249, 79, 76, 176, 168, 43, 83, 2, |
||||
]); |
||||
|
||||
let keys = p2p_net::utils::gen_keys(); |
||||
let pub_key = PubKey::Ed25519PubKey(keys.1); |
||||
|
||||
let (client_priv_key, client_pub_key) = generate_keypair(); |
||||
let (user_priv_key, user_pub_key) = generate_keypair(); |
||||
|
||||
log!("start connecting"); |
||||
|
||||
let res = BROKER |
||||
.write() |
||||
.await |
||||
.connect( |
||||
Box::new(ConnectionWebSocket {}), |
||||
IP::try_from(&IpAddr::from_str("127.0.0.1").unwrap()).unwrap(), |
||||
None, |
||||
keys.0, |
||||
pub_key, |
||||
server_key, |
||||
StartConfig::Client(ClientConfig { |
||||
user: user_pub_key, |
||||
client: client_pub_key, |
||||
client_priv: client_priv_key, |
||||
}), |
||||
) |
||||
.await; |
||||
log!("broker.connect : {:?}", res); |
||||
if res.is_err() { |
||||
panic!("Cannot connect"); |
||||
} |
||||
BROKER.read().await.print_status(); |
||||
|
||||
//res.expect_throw("assume the connection succeeds");
|
||||
|
||||
async fn timer_close(remote_peer_id: DirectPeerId) -> ResultSend<()> { |
||||
async move { |
||||
sleep!(std::time::Duration::from_secs(3)); |
||||
log!("timeout"); |
||||
BROKER |
||||
.write() |
||||
.await |
||||
.close_peer_connection(&remote_peer_id) |
||||
.await; |
||||
} |
||||
.await; |
||||
Ok(()) |
||||
} |
||||
spawn_and_log_error(timer_close(server_key)); |
||||
|
||||
//Broker::graceful_shutdown().await;
|
||||
|
||||
Broker::join_shutdown_with_timeout(std::time::Duration::from_secs(5)).await; |
||||
|
||||
Ok(()) |
||||
} |
||||
spawn_and_log_error(inner_task()).await; |
||||
} |
||||
|
||||
#[cfg(not(target_arch = "wasm32"))] |
||||
#[wasm_bindgen] |
||||
pub fn start() { |
||||
//alert(&format!("I say: {}", name));
|
||||
task::spawn(async move {}); |
||||
} |
||||
|
||||
#[wasm_bindgen] |
||||
pub fn change(name: &str) -> JsValue { |
||||
let mut random_buf = [0u8; 32]; |
||||
getrandom::getrandom(&mut random_buf).unwrap(); |
||||
JsValue::from_str(&format!("Hellooo, {}!", name)) |
||||
} |
||||
|
||||
#[cfg(target_arch = "wasm32")] |
||||
#[cfg(test)] |
||||
mod test { |
||||
use wasm_bindgen_test::*; |
||||
wasm_bindgen_test_configure!(run_in_browser); |
||||
use crate::start; |
||||
|
||||
#[wasm_bindgen_test] |
||||
pub async fn test_connection() { |
||||
start().await; |
||||
} |
||||
} |
@ -1,102 +0,0 @@ |
||||
# NextGraph native apps (Linux, MacOS, Windows, Android, iOS) |
||||
|
||||
NextGraph native apps use the Tauri framework. |
||||
|
||||
The apps are using an embedded WebView that renders the Svelte app. |
||||
|
||||
## Install |
||||
|
||||
``` |
||||
cargo install tauri-cli --version "^2.0.0-alpha" |
||||
npm install -g pnpm |
||||
pnpm install |
||||
``` |
||||
|
||||
## Recommended IDE Setup |
||||
|
||||
[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer). |
||||
|
||||
## Desktop |
||||
|
||||
Install [all prerequisites](https://next--tauri.netlify.app/next/guides/getting-started/prerequisites/) for your dev platform. |
||||
|
||||
to run the dev env : |
||||
|
||||
``` |
||||
## on macos |
||||
cargo tauri dev |
||||
## on linux |
||||
cargo tauri dev --target x86_64-unknown-linux-gnu |
||||
## on win |
||||
cargo tauri dev --target x86_64-pc-windows-msvc |
||||
``` |
||||
|
||||
to build the production app installer : |
||||
|
||||
### MacOs |
||||
|
||||
``` |
||||
cargo tauri build |
||||
``` |
||||
|
||||
### Linux (Ubuntu 22.04) |
||||
|
||||
``` |
||||
cargo tauri build --target x86_64-unknown-linux-gnu |
||||
``` |
||||
|
||||
### Windows (7) |
||||
|
||||
``` |
||||
cargo tauri build --target x86_64-pc-windows-msvc |
||||
``` |
||||
|
||||
## Android |
||||
|
||||
- [Install Android Studio](https://developer.android.com/studio) |
||||
|
||||
- add the rust targets for android |
||||
|
||||
``` |
||||
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android |
||||
``` |
||||
|
||||
- follow the steps for Android in the [Prerquisites guide of Tauri](https://next--tauri.netlify.app/next/guides/getting-started/prerequisites/) |
||||
|
||||
to launch the dev app : |
||||
|
||||
``` |
||||
cargo tauri android dev |
||||
``` |
||||
|
||||
to build the production app : |
||||
|
||||
``` |
||||
cargo tauri android build |
||||
``` |
||||
|
||||
to debug the Svelte app, use Chrome : |
||||
|
||||
- [chrome://inspect/#devices](chrome://inspect/#devices) |
||||
- install the [svelte extension](https://chrome.google.com/webstore/detail/svelte-devtools/ckolcbmkjpjmangdbmnkpjigpkddpogn) |
||||
|
||||
## iOS |
||||
|
||||
First, make sure Xcode is properly installed. then : |
||||
|
||||
``` |
||||
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim |
||||
``` |
||||
|
||||
to launch the dev app : |
||||
|
||||
``` |
||||
cargo tauri ios dev |
||||
``` |
||||
|
||||
to build the production app : |
||||
|
||||
``` |
||||
cargo tauri ios build |
||||
|
||||
``` |
@ -1,49 +0,0 @@ |
||||
{ |
||||
"name": "ng-app-native", |
||||
"private": true, |
||||
"version": "0.1.0", |
||||
"type": "module", |
||||
"scripts": { |
||||
"dev": "vite", |
||||
"webdev": "cross-env NG_APP_WEB=1 TAURI_DEBUG=1 vite", |
||||
"webbuild": "cross-env NG_APP_WEB=1 vite build", |
||||
"filebuild": "cross-env NG_APP_WEB=1 NG_APP_FILE=1 vite build", |
||||
"build": "vite build", |
||||
"preview": "vite preview", |
||||
"check": "svelte-check --tsconfig ./tsconfig.json", |
||||
"tauri": "tauri" |
||||
}, |
||||
"dependencies": { |
||||
"@popperjs/core": "^2.11.8", |
||||
"@tauri-apps/api": "2.0.0-alpha.4", |
||||
"classnames": "^2.3.2", |
||||
"flowbite": "^1.6.5", |
||||
"flowbite-svelte": "^0.37.1", |
||||
"svelte-spa-router": "^3.3.0" |
||||
}, |
||||
"devDependencies": { |
||||
"@sveltejs/vite-plugin-svelte": "^2.0.0", |
||||
"@tauri-apps/cli": "2.0.0-alpha.9", |
||||
"@tsconfig/svelte": "^3.0.0", |
||||
"@types/node": "^18.7.10", |
||||
"autoprefixer": "^10.4.14", |
||||
"cross-env": "^7.0.3", |
||||
"internal-ip": "^7.0.0", |
||||
"postcss": "^8.4.23", |
||||
"postcss-load-config": "^4.0.1", |
||||
"svelte": "^3.54.0", |
||||
"svelte-check": "^3.0.0", |
||||
"svelte-preprocess": "^5.0.3", |
||||
"tailwindcss": "^3.3.1", |
||||
"tslib": "^2.4.1", |
||||
"typescript": "^4.9.5", |
||||
"vite": "^4.2.1", |
||||
"vite-plugin-singlefile": "^0.13.5", |
||||
"vite-plugin-svelte-svg": "^2.2.1" |
||||
}, |
||||
"pnpm": { |
||||
"peerDependencyRules": { |
||||
"ignoreMissing": ["rollup"] |
||||
} |
||||
} |
||||
} |
@ -1,27 +0,0 @@ |
||||
[package] |
||||
name = "ng-app-native" |
||||
version = "0.1.0" |
||||
description = "NextGraph App" |
||||
authors = ["Niko PLP <niko@nextgraph.org>"] |
||||
license = "MIT/Apache-2.0" |
||||
repository = "https://git.nextgraph.org/NextGraph/nextgraph-rs" |
||||
edition = "2021" |
||||
|
||||
[lib] |
||||
name = "nativelib" |
||||
crate-type = ["staticlib", "cdylib", "rlib"] |
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||
|
||||
[build-dependencies] |
||||
tauri-build = { version = "2.0.0-alpha.5", features = [] } |
||||
|
||||
[dependencies] |
||||
tauri = { version = "2.0.0-alpha.9", features = [] } |
||||
serde = { version = "1.0", features = ["derive"] } |
||||
serde_json = "1.0" |
||||
|
||||
[features] |
||||
# this feature is used for production builds or when `devPath` points to the filesystem |
||||
# DO NOT REMOVE!! |
||||
custom-protocol = ["tauri/custom-protocol"] |
@ -1,48 +0,0 @@ |
||||
use tauri::App; |
||||
|
||||
#[cfg(mobile)] |
||||
mod mobile; |
||||
#[cfg(mobile)] |
||||
pub use mobile::*; |
||||
|
||||
pub type SetupHook = Box<dyn FnOnce(&mut App) -> Result<(), Box<dyn std::error::Error>> + Send>; |
||||
|
||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
|
||||
#[tauri::command] |
||||
fn greet(name: &str) -> String { |
||||
format!("Hello, {}! You've been greeted from Rust!", name) |
||||
} |
||||
|
||||
#[derive(Default)] |
||||
pub struct AppBuilder { |
||||
setup: Option<SetupHook>, |
||||
} |
||||
|
||||
impl AppBuilder { |
||||
pub fn new() -> Self { |
||||
Self::default() |
||||
} |
||||
|
||||
#[must_use] |
||||
pub fn setup<F>(mut self, setup: F) -> Self |
||||
where |
||||
F: FnOnce(&mut App) -> Result<(), Box<dyn std::error::Error>> + Send + 'static, |
||||
{ |
||||
self.setup.replace(Box::new(setup)); |
||||
self |
||||
} |
||||
|
||||
pub fn run(self) { |
||||
let setup = self.setup; |
||||
tauri::Builder::default() |
||||
.setup(move |app| { |
||||
if let Some(setup) = setup { |
||||
(setup)(app)?; |
||||
} |
||||
Ok(()) |
||||
}) |
||||
.invoke_handler(tauri::generate_handler![greet]) |
||||
.run(tauri::generate_context!()) |
||||
.expect("error while running tauri application"); |
||||
} |
||||
} |
@ -1,13 +0,0 @@ |
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(
|
||||
all(not(debug_assertions), target_os = "windows"), |
||||
windows_subsystem = "windows" |
||||
)] |
||||
|
||||
fn main() { |
||||
nativelib::AppBuilder::new().run(); |
||||
// tauri::Builder::default()
|
||||
// .invoke_handler(tauri::generate_handler![greet])
|
||||
// .run(tauri::generate_context!())
|
||||
// .expect("error while running tauri application");
|
||||
} |
@ -1,4 +0,0 @@ |
||||
#[tauri::mobile_entry_point] |
||||
fn main() { |
||||
crate::AppBuilder::new().run(); |
||||
} |
@ -1,22 +0,0 @@ |
||||
<script lang="ts"> |
||||
import Router from "svelte-spa-router"; |
||||
|
||||
import Home from "./routes/Home.svelte"; |
||||
import Test from "./routes/Test.svelte"; |
||||
import NotFound from "./routes/NotFound.svelte"; |
||||
|
||||
const routes = { |
||||
// Exact path |
||||
"/": Home, |
||||
|
||||
"/test": Test, |
||||
|
||||
// Catch-all |
||||
// This is optional, but if present it must be the last |
||||
"*": NotFound, |
||||
}; |
||||
</script> |
||||
|
||||
<main class="container2"> |
||||
<Router {routes} /> |
||||
</main> |
@ -1,30 +0,0 @@ |
||||
<script lang="ts"> |
||||
let name = ""; |
||||
let greetMsg = ""; |
||||
let ng; |
||||
|
||||
if (import.meta.env.NG_APP_WEB) { |
||||
ng = { |
||||
greet: async function (n) { |
||||
return "greetings from web " + n; |
||||
}, |
||||
}; |
||||
} else { |
||||
import("@tauri-apps/api/tauri").then((tauri) => { |
||||
ng = { greet: (n) => tauri.invoke("greet", { name: n }) }; |
||||
}); |
||||
} |
||||
|
||||
async function greet() { |
||||
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command |
||||
greetMsg = await ng.greet(name); |
||||
} |
||||
</script> |
||||
|
||||
<div> |
||||
<div class="row"> |
||||
<input id="greet-input" placeholder="Enter a name..." bind:value={name} /> |
||||
<button on:click={greet}> Greet </button> |
||||
</div> |
||||
<p>{greetMsg}</p> |
||||
</div> |
@ -1,9 +0,0 @@ |
||||
import "./app.postcss"; |
||||
import "./styles.css"; |
||||
import App from "./App.svelte"; |
||||
|
||||
const app = new App({ |
||||
target: document.getElementById("app"), |
||||
}); |
||||
|
||||
export default app; |
@ -1,61 +0,0 @@ |
||||
<script> |
||||
import { Button } from "flowbite-svelte"; |
||||
import { link } from "svelte-spa-router"; |
||||
import Logo from "../assets/nextgraph.svg?component"; |
||||
</script> |
||||
|
||||
<main class="container2"> |
||||
<div class="row"> |
||||
<Logo class="logo block h-40" alt="NextGraph Logo" /> |
||||
</div> |
||||
<h1 class="text-2xl mb-10">Welcome to NextGraph</h1> |
||||
|
||||
<div class="row"> |
||||
<a href="/test" use:link> |
||||
<button |
||||
type="button" |
||||
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:outline-none focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mr-2 mb-2" |
||||
> |
||||
<svg |
||||
class="w-8 h-8 mr-2 -ml-1" |
||||
fill="none" |
||||
stroke="currentColor" |
||||
stroke-width="1.5" |
||||
viewBox="0 0 24 24" |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
aria-hidden="true" |
||||
> |
||||
<path |
||||
stroke-linecap="round" |
||||
stroke-linejoin="round" |
||||
d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z" |
||||
/> |
||||
</svg> |
||||
Create account |
||||
</button> |
||||
</a> |
||||
</div> |
||||
<div class="row mt-10"> |
||||
<button |
||||
type="button" |
||||
class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:outline-none focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mr-2 mb-2" |
||||
> |
||||
<svg |
||||
class="w-8 h-8 mr-2 -ml-1" |
||||
fill="currentColor" |
||||
stroke="currentColor" |
||||
stroke-width="2" |
||||
viewBox="0 0 24 24" |
||||
xmlns="http://www.w3.org/2000/svg" |
||||
aria-hidden="true" |
||||
> |
||||
<path |
||||
stroke-linecap="round" |
||||
stroke-linejoin="round" |
||||
d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" |
||||
/> |
||||
</svg> |
||||
Log in |
||||
</button> |
||||
</div> |
||||
</main> |
@ -1,9 +0,0 @@ |
||||
<script> |
||||
import { Alert } from "flowbite-svelte"; |
||||
</script> |
||||
|
||||
<div class="p-8"> |
||||
<Alert color="red"> |
||||
<span class="font-medium">404</span> Page not found. |
||||
</Alert> |
||||
</div> |
@ -1,14 +0,0 @@ |
||||
<script lang="ts"> |
||||
import Greet from "../lib/Greet.svelte"; |
||||
</script> |
||||
|
||||
<main class="container2"> |
||||
<h1>Welcome to test</h1> |
||||
|
||||
<div class="row"> |
||||
<Greet /> |
||||
</div> |
||||
</main> |
||||
|
||||
<style> |
||||
</style> |
@ -0,0 +1,151 @@ |
||||
# NextGraph apps (Linux, MacOS, Windows, Android, iOS, web) |
||||
|
||||
All the apps are based on Svelte and share the same code. |
||||
|
||||
The native apps are using the Tauri framework with an embedded WebView to render the Svelte app. |
||||
|
||||
## Install |
||||
|
||||
``` |
||||
npm install -g pnpm |
||||
pnpm install |
||||
``` |
||||
|
||||
## Recommended IDE Setup |
||||
|
||||
[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer). |
||||
|
||||
## Web |
||||
|
||||
prerequisites: compile the local SDK |
||||
|
||||
``` |
||||
cd ../ng-sdk-js |
||||
wasm-pack build --target bundler |
||||
cd ../ng-app |
||||
``` |
||||
|
||||
#### Dev |
||||
|
||||
``` |
||||
pnpm webdev |
||||
// then open http://localhost:1421/ |
||||
``` |
||||
|
||||
#### Prod |
||||
|
||||
this will produce a single html file embedding all the resources. this is what you need for production |
||||
|
||||
``` |
||||
pnpm webfilebuild |
||||
// single file is available in dist-file/index.html |
||||
|
||||
``` |
||||
|
||||
alternatively, to obtain a regular dist folder with all resources in separate files (we dont use it anymore): |
||||
|
||||
``` |
||||
pnpm webbuild |
||||
// then the application is available in dist-web folder |
||||
// can be served with: |
||||
cd dist-web ; python3 -m http.server |
||||
``` |
||||
|
||||
## Desktop |
||||
|
||||
``` |
||||
cargo install tauri-cli --version "2.0.0-alpha.11" |
||||
``` |
||||
|
||||
Install [all prerequisites](https://next--tauri.netlify.app/next/guides/getting-started/prerequisites/) for your dev platform. |
||||
|
||||
to run the dev env : |
||||
|
||||
``` |
||||
## on macos |
||||
cargo tauri dev --no-watch |
||||
## on linux |
||||
cargo tauri dev --no-watch --target x86_64-unknown-linux-gnu |
||||
## on win |
||||
cargo tauri dev --no-watch --target x86_64-pc-windows-msvc |
||||
``` |
||||
|
||||
to build the production app installer : |
||||
|
||||
### MacOs (10.14+) |
||||
|
||||
``` |
||||
cargo tauri build |
||||
// the installer is then available in target/x86_64-apple-darwin/release/bundle/dmg/NextGraph_0.1.0_x64.dmg |
||||
// or if you just want the app, it is at target/x86_64-apple-darwin/release/bundle/macos/NextGraph.app |
||||
``` |
||||
|
||||
### Linux (Ubuntu 22.04) |
||||
|
||||
``` |
||||
cargo tauri build --target x86_64-unknown-linux-gnu |
||||
``` |
||||
|
||||
### Windows (7+) |
||||
|
||||
``` |
||||
cargo tauri build --target x86_64-pc-windows-msvc |
||||
``` |
||||
|
||||
### Android |
||||
|
||||
- [Install Android Studio](https://developer.android.com/studio) |
||||
|
||||
- add the rust targets for android |
||||
|
||||
``` |
||||
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android |
||||
``` |
||||
|
||||
- follow the steps for Android in the [Prerequisites guide of Tauri](https://next--tauri.netlify.app/next/guides/getting-started/prerequisites/) |
||||
|
||||
Until I find out how to do this properly, if you are compiling the android app from a macos station, you need to override an env var. this is due to reqwest needing SSL support, and on linux and android it compiles it from source. apparently the compiler (cc-rs) doesn't know that when cross compiling to android targets, the tool ranlib is called llvm-ranlib (and not [target]-ranlib) |
||||
|
||||
``` |
||||
export RANLIB=/Users/[user]/Library/Android/sdk/ndk/[yourNDKversion]/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ranlib |
||||
``` |
||||
|
||||
to launch the dev app : |
||||
|
||||
``` |
||||
cargo tauri android dev |
||||
``` |
||||
|
||||
to build the production app : |
||||
|
||||
``` |
||||
cargo tauri android build |
||||
``` |
||||
|
||||
to debug the Svelte app, use Chrome : |
||||
|
||||
- [chrome://inspect/#devices](chrome://inspect/#devices) |
||||
- install the [svelte extension](https://chrome.google.com/webstore/detail/svelte-devtools/ckolcbmkjpjmangdbmnkpjigpkddpogn) |
||||
|
||||
### iOS |
||||
|
||||
Disclaimer: iOS hasn't been tested yet, for lack of suitable dev env (latest MacOS version needed). |
||||
|
||||
First, make sure Xcode is properly installed. then : |
||||
|
||||
``` |
||||
rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim |
||||
``` |
||||
|
||||
to launch the dev app : |
||||
|
||||
``` |
||||
cargo tauri ios dev |
||||
``` |
||||
|
||||
to build the production app : |
||||
|
||||
``` |
||||
cargo tauri ios build |
||||
|
||||
``` |
@ -0,0 +1,65 @@ |
||||
<!-- |
||||
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers |
||||
// All rights reserved. |
||||
// Licensed under the Apache License, Version 2.0 |
||||
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0> |
||||
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>, |
||||
// at your option. All files in the project carrying such |
||||
// notice may not be copied, modified, or distributed except |
||||
// according to those terms. |
||||
--> |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link |
||||
rel="icon" |
||||
type="image/svg+xml" |
||||
href="data:image/svg+xml;base64, |
||||
PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMjUg |
||||
MjI1Ij48Y2lyY2xlIGN4PSIxMDkuODgxIiBjeT0iMTEyLjkwNSIgcj0iMTA2Ljk4IiBzdHlsZT0i |
||||
ZmlsbDogcmdiKDI1NSwgMjU1LCAyNTUpOyBzdHJva2U6IG5vbmU7IHN0cm9rZS13aWR0aDogMC4y |
||||
NjgzNzU7Ij48L2NpcmNsZT48cGF0aCBkPSJNOTguMzQzIDE5MC4yNjFjLTE3Ljk0LTIuNzI3LTMz |
||||
LjMzMS0xMC42ODMtNDUuNzM1LTIzLjYzOC0xNC4wMDYtMTQuNjI5LTIxLjQzLTMzLjIxLTIxLjQz |
||||
LTUzLjYzNSAwLTEwLjIxOCAxLjctMTkuNDQ0IDUuMjIxLTI4LjMzMiA0LjI4Ny0xMC44MiAxMC4w |
||||
MzgtMTkuMzkgMTguNTM1LTI3LjYyMiA0LjczLTQuNTgyIDYuNjA3LTYuMTA3IDExLjI4MS05LjE2 |
||||
MyAxMS45LTcuNzggMjQuMTc0LTExLjg4IDM4LjA5Ni0xMi43MjUgMTkuODA1LTEuMjAxIDM5LjEx |
||||
MiA1LjExMyA1NC42MDMgMTcuODYgMS41MDcgMS4yNCAyLjczIDIuMzU4IDIuNzE2IDIuNDg2LS4w |
||||
MTMuMTI4LTMuODU4IDMuNjM1LTguNTQ0IDcuNzkzLTQuNjg2IDQuMTU3LTEwLjA0NyA4Ljk2Mi0x |
||||
MS45MTQgMTAuNjc3LTEuODY2IDEuNzE1LTMuNTQgMy4xMTktMy43MjEgMy4xMTktLjE4MSAwLTEu |
||||
NC0uNzQ2LTIuNzEtMS42NTYtNy41My01LjIzOS0xNS45OTQtNy44MjItMjUuNjI1LTcuODIyLTEy |
||||
LjczMiAwLTIzLjI1IDQuMzM4LTMyLjE0NCAxMy4yNTctNi4zOTYgNi40MTQtMTAuNzA0IDE0LjU1 |
||||
Ni0xMi41IDIzLjYyNC0uNjkxIDMuNDg4LS42OSAxMy41My4wMDIgMTcuMDA5IDMuNzA1IDE4LjYy |
||||
NiAxOC4zMTggMzMuMTAyIDM2LjY0MiAzNi4yOTcgNC4xNjQuNzI2IDExLjk4LjcxMiAxNS45OS0u |
||||
MDI4IDE0LjAzMi0yLjU5NCAyNS44Ni0xMS4zNjggMzIuMjY1LTIzLjkzNi43NzQtMS41MTkgMS4y |
||||
Ni0yLjg4NSAxLjA4LTMuMDM2LS4xNzgtLjE1Mi02Ljg3NC0xLjE3OC0xNC44NzctMi4yODEtOS43 |
||||
OC0xLjM0OC0xNC45MjQtMi4yMTQtMTUuNjg1LTIuNjQxLTEuNTItLjg1NC0yLjgzNi0yLjg4OC0y |
||||
LjgzNi00LjM4NiAwLTEuMTczIDIuMDI3LTE1Ljg2OSAyLjQ5LTE4LjA2LjI5OC0xLjQwMSAyLjQy |
||||
Ni0zLjQ5MyAzLjg0NC0zLjc3Ny42MjItLjEyNCA4LjgyNy44NTYgMTguMjggMi4xODQgOS40MzQg |
||||
MS4zMjUgMTcuMjYzIDIuMjk0IDE3LjM5OSAyLjE1NC4xMzYtLjE0IDEuMTE4LTYuNTQ4IDIuMTgz |
||||
LTE0LjI0IDEuMTA4LTggMi4yMDQtMTQuNjAyIDIuNTYyLTE1LjQyNi4zNDQtLjc5MyAxLjExLTEu |
||||
ODUgMS43MDMtMi4zNDggMi4wNjMtMS43MzYgMy4xNDMtMS43ODUgMTIuMjA0LS41NTMgOS42MzYg |
||||
MS4zMSAxMC43MDkgMS41NjIgMTIuMjggMi44ODUgMS42NDQgMS4zODMgMi4yNzQgMi44MSAyLjI2 |
||||
IDUuMTIzLS4wMDcgMS4xMDItLjkyMiA4LjI5Ny0yLjAzMyAxNS45ODktMS4xMTIgNy42OTEtMS45 |
||||
NzIgMTQuMDQtMS45MTIgMTQuMTA5LjA2MS4wNjggNy4xNjcgMS4xMTEgMTUuNzkyIDIuMzE4IDEx |
||||
LjEwNSAxLjU1NCAxNi4wMDggMi4zODcgMTYuODAyIDIuODU2IDEuNTMuOTA0IDIuNDggMi42NDgg |
||||
Mi40NSA0LjQ5OC0uMDQ2IDIuODQ0LTIuNDEzIDE4LjEyMy0yLjk3NSAxOS4yMS0uNjYyIDEuMjgt |
||||
Mi42MDMgMi41NDgtMy45MjEgMi41NjItLjUyLjAwNS03Ljg3NS0uOTYtMTYuMzQ0LTIuMTQ0LTgu |
||||
NDctMS4xODUtMTUuNDc2LTIuMDc3LTE1LjU3LTEuOTgzLS4wOTQuMDk0LTEuMTg4IDcuMzQxLTIu |
||||
NDMxIDE2LjEwNi0xLjQ0IDEwLjE1My0yLjQ5OCAxNi40MzYtMi45MTYgMTcuMzE2LS43MjUgMS41 |
||||
MjgtMi43NjIgMy4wNjMtNC41MzggMy40MTgtLjk1Ny4xOTEtMTAuOS0uOTI4LTEzLjU5OC0xLjUz |
||||
LS41NDgtLjEyMy0xLjg5Mi42NzItNC41MSAyLjY2NS0xMS4yNjMgOC41NzYtMjQuMzQyIDEzLjkx |
||||
LTM4LjM1NyAxNS42NDItNC40LjU0NC0xNS43MjcuNDMzLTE5Ljg1NC0uMTk1eiIgc3R5bGU9ImZp |
||||
bGw6IHJnYig3MywgMTE0LCAxNjUpOyBmaWxsLW9wYWNpdHk6IDE7IHN0cm9rZTogcmdiKDczLCAx |
||||
MTQsIDE2NSk7IHN0cm9rZS13aWR0aDogMC4zNzc5NzY7IHN0cm9rZS1vcGFjaXR5OiAxOyI+PC9w |
||||
YXRoPjwvc3ZnPg==" |
||||
/> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
<title>NextGraph</title> |
||||
</head> |
||||
|
||||
<body> |
||||
<div id="app"></div> |
||||
<script type="module" src="/src/main-web.ts"></script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,56 @@ |
||||
{ |
||||
"name": "ng-app", |
||||
"private": true, |
||||
"version": "0.1.0", |
||||
"type": "module", |
||||
"scripts": { |
||||
"dev": "shx cp index-native.html index.html && vite", |
||||
"webdev": "shx cp index-web.html index.html && cross-env NG_APP_WEB=1 TAURI_DEBUG=1 vite", |
||||
"webbuild": "shx cp index-web.html index.html && cross-env NG_APP_WEB=1 vite build && rm -f ./dist-web/assets/*.svg && tar --exclude .DS_Store -zcvf dist-web.tar.gz dist-web", |
||||
"webfilebuild": "shx cp index-web.html index.html && cross-env NG_APP_WEB=1 NG_APP_FILE=1 vite build && node prepare-app-file.cjs && rm -rf ./dist-file/assets && tar --exclude .DS_Store -zcvf dist-file.tar.gz dist-file", |
||||
"webfilebuilddebug": "shx cp index-web.html index.html && cross-env NG_APP_WEB=1 NG_APP_FILE=1 TAURI_DEBUG=1 vite build -m debug", |
||||
"build": "shx cp index-native.html index.html && vite build && shx rm -f ./dist/assets/*.svg", |
||||
"buildfile": "shx cp index-native.html index.html && cross-env NG_APP_FILE=1 vite build && rm -rf ./dist/assets && tar --exclude .DS_Store -zcvf dist.tar.gz dist", |
||||
"preview": "vite preview", |
||||
"check": "svelte-check --tsconfig ./tsconfig.json", |
||||
"tauri": "tauri" |
||||
}, |
||||
"dependencies": { |
||||
"@popperjs/core": "^2.11.8", |
||||
"@tauri-apps/api": "2.0.0-alpha.8", |
||||
"@tauri-apps/plugin-window": "2.0.0-alpha.1", |
||||
"async-proxy": "^0.4.1", |
||||
"classnames": "^2.3.2", |
||||
"flowbite": "^1.6.5", |
||||
"flowbite-svelte": "^0.43.3", |
||||
"ng-sdk-js": "workspace:^0.1.0", |
||||
"svelte-spa-router": "^3.3.0", |
||||
"vite-plugin-top-level-await": "^1.3.1" |
||||
}, |
||||
"devDependencies": { |
||||
"@sveltejs/vite-plugin-svelte": "^2.0.0", |
||||
"@tauri-apps/cli": "2.0.0-alpha.14", |
||||
"@tsconfig/svelte": "^3.0.0", |
||||
"@types/node": "^18.7.10", |
||||
"autoprefixer": "^10.4.14", |
||||
"cross-env": "^7.0.3", |
||||
"dayjs": "^1.11.10", |
||||
"internal-ip": "^7.0.0", |
||||
"node-gzip": "^1.1.2", |
||||
"postcss": "^8.4.23", |
||||
"postcss-load-config": "^4.0.1", |
||||
"shx": "^0.3.4", |
||||
"svelte": "^3.54.0", |
||||
"svelte-check": "^3.0.0", |
||||
"svelte-heros-v2": "^0.10.12", |
||||
"svelte-preprocess": "^5.0.3", |
||||
"svelte-time": "^0.8.0", |
||||
"tailwindcss": "^3.3.1", |
||||
"tslib": "^2.4.1", |
||||
"typescript": "^4.9.5", |
||||
"vite": "^4.2.1", |
||||
"vite-plugin-singlefile": "^0.13.5", |
||||
"vite-plugin-svelte-svg": "^2.2.1", |
||||
"vite-plugin-wasm": "^3.2.2" |
||||
} |
||||
} |
@ -0,0 +1,32 @@ |
||||
var crypto = require('crypto') |
||||
, fs = require('fs') |
||||
const {gzip, } = require('node-gzip'); |
||||
|
||||
var algorithm = 'sha256' |
||||
, shasum = crypto.createHash(algorithm) |
||||
|
||||
const sha_file = './dist-file/index.sha256'; |
||||
const gzip_file = './dist-file/index.gzip'; |
||||
var filename = './dist-file/index.html' |
||||
, s = fs.ReadStream(filename) |
||||
|
||||
var bufs = []; |
||||
s.on('data', function(data) { |
||||
shasum.update(data) |
||||
bufs.push(data); |
||||
}) |
||||
|
||||
s.on('end', function() { |
||||
var hash = shasum.digest('hex') |
||||
console.log(hash + ' ' + filename) |
||||
|
||||
fs.writeFileSync(sha_file, hash, 'utf8'); |
||||
|
||||
var buf = Buffer.concat(bufs); |
||||
gzip(buf).then((compressed) => {fs.writeFileSync(gzip_file, compressed);}); |
||||
|
||||
fs.rm(filename,()=>{}); |
||||
|
||||
}) |
||||
|
||||
|
@ -0,0 +1,45 @@ |
||||
[package] |
||||
name = "ng-app" |
||||
# version = "0.1.0" |
||||
description = "NextGraph App" |
||||
publish = false |
||||
version.workspace = true |
||||
edition.workspace = true |
||||
license.workspace = true |
||||
authors.workspace = true |
||||
repository.workspace = true |
||||
homepage.workspace = true |
||||
keywords.workspace = true |
||||
documentation.workspace = true |
||||
rust-version.workspace = true |
||||
|
||||
[lib] |
||||
name = "nativelib" |
||||
crate-type = ["staticlib", "cdylib", "rlib"] |
||||
|
||||
[build-dependencies] |
||||
tauri-build = { version = "2.0.0-alpha.8", features = [] } |
||||
# tauri-macros = { version = "=2.0.0-alpha.6" } |
||||
# tauri-codegen = { version = "=2.0.0-alpha.6" } |
||||
# tauri-utils = { version = "=2.0.0-alpha.6" } |
||||
|
||||
[dependencies] |
||||
tauri = { version = "2.0.0-alpha.14", features = [] } |
||||
# tauri = { git = "https://git.nextgraph.org/NextGraph/tauri.git", branch="alpha.11-nextgraph", features = ["no-ipc-custom-protocol"] } |
||||
# tauri = { git = "https://github.com/simonhyll/tauri.git", branch="fix/ipc-mixup", features = [] } |
||||
serde = { version = "1.0", features = ["derive"] } |
||||
serde_json = "1.0" |
||||
ng-repo = { path = "../../ng-repo" } |
||||
ng-net = { path = "../../ng-net" } |
||||
ng-client-ws = { path = "../../ng-client-ws" } |
||||
ng-wallet = { path = "../../ng-wallet" } |
||||
nextgraph = { path = "../../nextgraph" } |
||||
async-std = { version = "1.12.0", features = ["attributes", "unstable"] } |
||||
# tauri-plugin-window = { git = "https://git.nextgraph.org/NextGraph/plugins-workspace.git", branch="window-alpha.1-nextgraph" } |
||||
tauri-plugin-window = "2.0.0-alpha.1" |
||||
async-tungstenite = { git = "https://git.nextgraph.org/NextGraph/async-tungstenite.git", branch = "nextgraph", features = ["async-std-runtime", "async-native-tls"] } |
||||
|
||||
[features] |
||||
# this feature is used for production builds or when `devPath` points to the filesystem |
||||
# DO NOT REMOVE!! |
||||
custom-protocol = ["tauri/custom-protocol"] |
After Width: | Height: | Size: 53 KiB |
@ -1,4 +1,4 @@ |
||||
/src/main/java/org/nextgraph/ng_app_native/generated |
||||
/src/main/java/org/nextgraph/ng_app/generated |
||||
/src/main/jniLibs/**/*.so |
||||
/src/main/assets/tauri.conf.json |
||||
/tauri.build.gradle.kts |
@ -1,3 +1,3 @@ |
||||
package org.nextgraph.ng_app_native |
||||
package org.nextgraph.ng_app |
||||
|
||||
class MainActivity : TauriActivity() |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 7.2 KiB |