From 460464e79ab7e3a10943fb4bd9684ef2f484b104 Mon Sep 17 00:00:00 2001
From: Niko PLP <niko@nextgraph.org>
Date: Tue, 4 Mar 2025 00:17:05 +0200
Subject: [PATCH] fix nodeJS SDK

---
 ng-app/src/locales/en.json           |   4 +-
 ng-sdk-js/Cargo.toml                 |  12 +-
 ng-sdk-js/app-node/index.js          | 293 +++++++++++++++++----------
 ng-sdk-js/app-node/package-lock.json |  13 +-
 ng-sdk-js/app-node/package.json      |   2 +-
 ng-sdk-js/app-web/index.js           |  10 +-
 ng-sdk-js/app-web/package.json       |   2 +-
 ng-sdk-js/app-web/test.js            |   2 +-
 ng-sdk-js/js/node.js                 |   2 +-
 ng-sdk-js/src/lib.rs                 |  17 ++
 10 files changed, 230 insertions(+), 127 deletions(-)

diff --git a/ng-app/src/locales/en.json b/ng-app/src/locales/en.json
index 616dbb81..38333354 100644
--- a/ng-app/src/locales/en.json
+++ b/ng-app/src/locales/en.json
@@ -331,7 +331,7 @@
     },
     "install": {
       "app_availability": "<b>NextGraph App</b> is available for download as a native app for your mobile, tablet, laptop and desktop.<br /> The app supports iOS, Android, Linux, macOS, Windows, or any other platform with a modern browser.",
-      "has_wallet_warning": "A wallet is saved in this browser. If it is yours,<br /> once the installation of the app will be finished,<br /> choose the option \"Login\" on the app.<br /> (do not create another wallet from the app).",
+      "has_wallet_warning": "A wallet is saved in this browser. <br />If it is yours, once the installation of the app will be finished,<br /> choose the option \"Login\" on the app.<br /> (do not create another wallet from the app).",
       "android_play_store": "Android Play Store",
       "download_apk": "Download APK",
       "ios_app_store": "iOS App Store",
@@ -420,7 +420,7 @@
         "5": "At anytime you can decide to switch to another broker service provider or host it yourself. Your data is totally <b >portable</b > and can freely move to another broker.",
         "6": "Soon we will offer you the opportunity to host your own broker at <b>home</b> or <b>office</b>. Instead of using a \"broker service provider\", you will own a small device that you connect behind your internet router. It is called <b>NG Box</b> and will be available soon.",
         "7": "Organizations and companies have the opportunity to host a broker <b>on-premise</b> or in the <b>cloud</b>, as the software is open source. Individuals can also <b>self-host</b> a broker on any VPS server or at home, on their dedicated hardware.",
-        "8": "You can also start by installing the Native App and create the wallet from there, and select the broker also from the app. <br/>At any time you will be able to transfer your Wallet from one device to another (including from the web-app and the native apps)."
+        "8": "You can also start by installing the Native App and create the wallet from there, and then select the broker from the app. <br/>At any time you will be able to transfer your Wallet from one device to another (including from the web-app and the native apps)."
       },
       "choose_broker": "Please choose one broker among the list",
       "register_with_broker": "Register with {broker}",
diff --git a/ng-sdk-js/Cargo.toml b/ng-sdk-js/Cargo.toml
index 86b3befc..5b3b147f 100644
--- a/ng-sdk-js/Cargo.toml
+++ b/ng-sdk-js/Cargo.toml
@@ -17,12 +17,12 @@ rust-version.workspace = true
 wasm-opt = false
 
 [package.metadata.scripts]
-appdev = "rm -r pkg && wasm-pack build --target bundler"
-app = "rm -r pkg && wasm-pack build --target bundler"
-nodedev = "rm -r pkg-node && wasm-pack build --dev -t nodejs -d pkg-node && node prepare-node.js"
-node = "rm -r pkg-node && wasm-pack build -t nodejs -d pkg-node && node prepare-node.js"
-web = "rm -r web && wasm-pack build --target web -d web"
-webdev = "rm -r web && wasm-pack build --dev --target web -d web"
+appdev = "rm -rf pkg && wasm-pack build --target bundler"
+app = "rm -rf pkg && wasm-pack build --target bundler"
+nodedev = "rm -rf pkg-node && wasm-pack build --dev -t nodejs -d pkg-node && node prepare-node.js"
+node = "rm -rf pkg-node && wasm-pack build -t nodejs -d pkg-node && node prepare-node.js"
+web = "rm -rf web && wasm-pack build --target web -d web"
+webdev = "rm -rf web && wasm-pack build --dev --target web -d web"
 
 [lib]
 crate-type = ["cdylib"]
diff --git a/ng-sdk-js/app-node/index.js b/ng-sdk-js/app-node/index.js
index c6b0f1bd..263aad86 100644
--- a/ng-sdk-js/app-node/index.js
+++ b/ng-sdk-js/app-node/index.js
@@ -21,125 +21,198 @@ let config = {
     server_addr: "127.0.0.1:14400"
 };
 
-ng.init_headless(config).then( async() => {
-    let session_id;
+// get your wallet file as an ArrayBuffer and pass it to wallet_read_file  
+
+const fs = require('fs');
+let buffer = fs.readFileSync("/Users/nl/Downloads/wallet-Hr-UITwGtjE1k6lXBoVGzD4FQMiDkM3T6bSeAi9PXt4A.ngw");
+
+ng.wallet_read_file(buffer).then(async (wallet)=>{
+    console.log("start");
     try {
-        //let user_id = await ng.admin_create_user(config);
-        //console.log("user created: ",user_id);
-        
-        let user_id = "sajsOaZWHXNyvhBxWbyj9GFmxuAjsP31gWQ2qZunCr0A";
-        
-        //let base;
-        let session = await ng.session_headless_start(user_id);
-        session_id = session.session_id;
+        let opened_wallet = await ng.wallet_open_with_mnemonic_words(wallet, ["jealous",
+            "during",
+            "elevator",
+            "swallow",
+            "pen",
+            "phone",
+            "like",
+            "employ",
+            "myth",
+            "remember",
+            "question",
+            "lemon"],
+            [2, 3, 2, 3]);
+
+        console.log(opened_wallet);
+
+        let user_id = opened_wallet.V0.personal_site;
+        let wallet_name = opened_wallet.V0.wallet_id;
+
+        console.log(user_id)
+        console.log(wallet_name)
+
+        let _client = await ng.wallet_import(wallet, opened_wallet, true)
+
+        let session = await ng.session_in_memory_start(wallet_name, user_id);
+
+        let session_id = session.session_id;
         console.log(session);
-        
-        let dump = await ng.rdf_dump(session.session_id);
+
+        let protected_repo_id = session.protected_store_id.substr(2,44);
+        console.log("Session started. protected store ID = ", protected_repo_id)
+
+        let info = await ng.client_info();
+        console.log(info);
+        let connection_status = await ng.user_connect(
+            info,
+            user_id
+        );
+
+        console.log(connection_status);
+
+        let dump = await ng.rdf_dump(session_id);
         console.log(dump);
-        let private_store = "did:ng:o:qBzNhlqofXRKbTfTUOq-2Aagh5AgDES5LR4Hsw7caCUA:v:XL7JfZF_8OuRiEN1db3g44sUD2m1aU8Z_Ab1Z6H-AOkA";
-        //let nuri = await ng.doc_create(session.session_id, "Graph", "data:graph", "protected", "B381BvfdAFYPBkdhDrsqnMMg5pnJMWJgJbZobZErXZMA", "store");
-        let nuri = "did:ng:o:FwRgrwtOhli54mRT6xi8J5ZK7X4L7L86lpbwhNVmgbsA:v:cpEgHDobJmdpcB8Z4SP91tBX4wPaasjJuz09GkfP2_UA";
-        console.log("nuri=",nuri);
-        let base = "did:ng:o:FwRgrwtOhli54mRT6xi8J5ZK7X4L7L86lpbwhNVmgbsA";
 
-        console.log("******** UPDATE")
+        let nuri = await ng.doc_create(session_id, "Graph", "data:graph", "protected", protected_repo_id, "store");
+        console.log(nuri);
 
-        //let header_branch = "did:ng:o:b70vk7Bj4eInXgG8pLysrFpEL-YSOiRYEmihPGiM1EsA:v:_0hm2qIpq443C7rMEdCGnhPDhsaWR2XruTIaF-9LKbkA:b:TokczMya9WDpQ-_FYFi7QJVbHmllWS3lD-vjtzHHQa0A";
-        
-        // let sparql_result = await ng.sparql_query(session.session_id, "SELECT ?s ?p ?o WHERE { ?s ?p ?o }", base, header_branch);
-        // console.log(sparql_result);
-        // for (const q of sparql_result.results.bindings) {
-        //     console.log(q);
-        // }
-
-        // await ng.sparql_update(session.session_id, "WITH <"+header_branch+">  \
-        // DELETE { <> <did:ng:x:ng#n> ?n.  } INSERT {<> <did:ng:x:ng#n> \"ddd6\". } WHERE {OPTIONAL { <> <did:ng:x:ng#n> ?n } }",nuri);
-
-        // let history = await ng.branch_history(session.session_id);
-        // for (const h of history.history) {
-        //     console.log(h[0], h[1]);
-        // }
-        // console.log(history.swimlane_state);
-
-        await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:_> <did:ng:i> <did:ng:j3> }");
-        
-        sparql_result = await ng.sparql_query(session.session_id, "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }");
-        console.log("******** CONSTRUCT")
+        // await ng.sparql_update(session_id, 
+        // "INSERT DATA { <did:ng:_> <example:predicate> \"An example value30\". }", nuri );
 
-        for (const r of sparql_result) console.log(r.subject.value, r.predicate.value, r.object.value);
-        
-        
-        // await ng.sparql_update(session.session_id, "DELETE DATA { <did:ng:t:AJQ5gCLoXXjalC9diTDCvxxWu5ZQUcYWEE821nhVRMcE> <did:ng:i> <did:ng:j> }");
-
-        // await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:t:AJQ5gCLoXXjalC9diTDCvxxWu5ZQUcYWEE821nhVRMcE> <did:ng:i> <did:ng:j> }");
-        // await ng.sparql_update(session.session_id, "INSERT { ?s <did:ng:i> <did:ng:k> } WHERE { ?s <did:ng:i> <did:ng:j> } ");
-
-        // await ng.sparql_update(session.session_id, "INSERT DATA {  <did:ng:z> <did:ng:j> <did:ng:t:BJQ5gCLoXXjalC9diTDCvxxWu5ZQUcYWEE821nhVRMcE>. <did:ng:t:BJQ5gCLoXXjalC9diTDCvxxWu5ZQUcYWEE821nhVRMcE> <did:ng:m> <did:ng:n> }");
-        //await ng.sparql_update(session.session_id, "INSERT DATA {  <did:ng:z> <did:ng:j> [ <did:ng:m> <did:ng:n> ]. }");
-        //await ng.sparql_update(session.session_id, "INSERT DATA {  [ <did:ng:m> <did:ng:n> ] <did:ng:ok> <did:ng:v>  . }");
-        //await ng.sparql_update(session.session_id, "INSERT {  ?a <did:ng:ok> <did:ng:v>  . } WHERE { ?a <did:ng:m> <did:ng:n>  } ");
-        //await ng.sparql_update(session.session_id, "INSERT DATA {  <did:ng:z> <did:ng:j> _:1 . _:1 <did:ng:m> <did:ng:n>. }");
-        //await ng.sparql_update(session.session_id, "INSERT DATA {  _:f766ca988268ddc60315ddd5bd621387 <did:ng:o> <did:ng:>. }");
-        //await ng.sparql_update(session.session_id, "INSERT {  _:_ <did:ng:ok> <did:ng:v>  . } WHERE { _:_ <did:ng:m> <did:ng:n>  } ");
-        //await ng.sparql_update(session.session_id, "INSERT DATA {  _:_ <abc:a> <d:a>  .  _:_a <abceee:a> <d:a>  . }");
-        
-        //await ng.sparql_update(session.session_id, "INSERT DATA {  <> <a:selftest> <a:selftest>  . }",base);
-
-        //await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:TEST4>  <did:ng:j> _:_  .   _:_ <did:ng:m> <did:ng:n>  . }");
-        //await ng.sparql_update(session.session_id, "INSERT DATA {  <did:ng:TEST5> <did:ng:j> [ <did:ng:m> <did:ng:n> ]. }");
-
-        // sparql_result = await ng.sparql_query(session.session_id, "SELECT ?a WHERE { ?a <did:ng:j> _:abc. _:abc <did:ng:m> <did:ng:n>  }", base);
-        // console.log(sparql_result);
-        // for (const q of sparql_result.results.bindings) {
-        //     console.log(q);
-        // }
-
-        // sparql_result = await ng.sparql_query(session.session_id, "SELECT ?s ?a WHERE { ?s <did:ng:j> ?a  }", base);
-        // console.log(sparql_result);
-        // for (const q of sparql_result.results.bindings) {
-        //     console.log(q);
-        // }
-
-        // console.log("******** CONSTRUCT2")
-
-        // let quads = await ng.sparql_query(session.session_id, "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }",base);
-        // for (const q of quads) {
-        //     console.log(q.subject.toString(), q.predicate.toString(), q.object.toString(), q.graph.toString())
-        // }
-
-        // let file_nuri = await ng.file_put_to_private_store(session.session_id,"LICENSE-MIT","text/plain");
-        // console.log(file_nuri);
-
-        // //let file_nuri = "did:ng:j:AD_d4njVMAtIDEU1G-RDxfOLIOZyOrB_1Rb7B6XykIEJ:k:APV-_Xtk03PW_Mbl4OaYpLrmEkBDVtn81lpto8sxc_tb";
-        // var bufs = [];
-        // let cancel = await ng.file_get_from_private_store(session.session_id, file_nuri, async (file) => {
-        //     if (file.V0.FileMeta) {
-        //       //skip
-        //     } else if (file.V0.FileBinary) {
-        //       if (file.V0.FileBinary.byteLength > 0) {
-        //         bufs.push(file.V0.FileBinary);
-        //       } 
-        //     } else if (file.V0 == 'EndOfStream') {
-        //         //console.log("end of file");
-        //         var buf = Buffer.concat(bufs);
-        //         // if the file contains some UTF8 text
-        //         console.log(buf.toString('utf8'));
-        //     }
-        // });
-
-        // the 2nd argument `false` means: do not `force_close` the dataset. 
-        // it will be detached, which means it stays in memory even when the session is stopped. 
-        // (not all the dataset is in memory anyway! just some metadata)
-        // if you set this to true, the dataset is closed and removed from memory on the server.
-        // next time you will open a session for this user, the dataset will be loaded again.
-        let res = await ng.session_headless_stop(session.session_id, false);
-        //console.log(res);
+        // cleaning up
+        await ng.user_disconnect(user_id);
+
+        await ng.session_stop(user_id);
+
+        await ng.wallet_close(wallet_name);
 
+        console.log("the end");
     } catch (e) {
         console.error(e);
-        if (session_id) await ng.session_headless_stop(session_id, true);
     }
-})
-.catch(err => {
+}).catch(err => {
     console.error(err);
 });
+
+// ng.init_headless(config).then( async() => {
+//     let session_id;
+//     try {
+//         //let user_id = await ng.admin_create_user(config);
+//         //console.log("user created: ",user_id);
+        
+//         let user_id = "sajsOaZWHXNyvhBxWbyj9GFmxuAjsP31gWQ2qZunCr0A";
+        
+//         //let base;
+//         let session = await ng.session_headless_start(user_id);
+//         session_id = session.session_id;
+//         console.log(session);
+        
+//         let dump = await ng.rdf_dump(session.session_id);
+//         console.log(dump);
+//         let private_store = "did:ng:o:qBzNhlqofXRKbTfTUOq-2Aagh5AgDES5LR4Hsw7caCUA:v:XL7JfZF_8OuRiEN1db3g44sUD2m1aU8Z_Ab1Z6H-AOkA";
+//         //let nuri = await ng.doc_create(session.session_id, "Graph", "data:graph", "protected", "B381BvfdAFYPBkdhDrsqnMMg5pnJMWJgJbZobZErXZMA", "store");
+//         let nuri = "did:ng:o:FwRgrwtOhli54mRT6xi8J5ZK7X4L7L86lpbwhNVmgbsA:v:cpEgHDobJmdpcB8Z4SP91tBX4wPaasjJuz09GkfP2_UA";
+//         console.log("nuri=",nuri);
+//         let base = "did:ng:o:FwRgrwtOhli54mRT6xi8J5ZK7X4L7L86lpbwhNVmgbsA";
+
+//         console.log("******** UPDATE")
+
+//         //let header_branch = "did:ng:o:b70vk7Bj4eInXgG8pLysrFpEL-YSOiRYEmihPGiM1EsA:v:_0hm2qIpq443C7rMEdCGnhPDhsaWR2XruTIaF-9LKbkA:b:TokczMya9WDpQ-_FYFi7QJVbHmllWS3lD-vjtzHHQa0A";
+        
+//         // let sparql_result = await ng.sparql_query(session.session_id, "SELECT ?s ?p ?o WHERE { ?s ?p ?o }", base, header_branch);
+//         // console.log(sparql_result);
+//         // for (const q of sparql_result.results.bindings) {
+//         //     console.log(q);
+//         // }
+
+//         // await ng.sparql_update(session.session_id, "WITH <"+header_branch+">  \
+//         // DELETE { <> <did:ng:x:ng#n> ?n.  } INSERT {<> <did:ng:x:ng#n> \"ddd6\". } WHERE {OPTIONAL { <> <did:ng:x:ng#n> ?n } }",nuri);
+
+//         // let history = await ng.branch_history(session.session_id);
+//         // for (const h of history.history) {
+//         //     console.log(h[0], h[1]);
+//         // }
+//         // console.log(history.swimlane_state);
+
+//         await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:_> <did:ng:i> <did:ng:j3> }");
+        
+//         sparql_result = await ng.sparql_query(session.session_id, "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }");
+//         console.log("******** CONSTRUCT")
+
+//         for (const r of sparql_result) console.log(r.subject.value, r.predicate.value, r.object.value);
+        
+        
+//         // await ng.sparql_update(session.session_id, "DELETE DATA { <did:ng:t:AJQ5gCLoXXjalC9diTDCvxxWu5ZQUcYWEE821nhVRMcE> <did:ng:i> <did:ng:j> }");
+
+//         // await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:t:AJQ5gCLoXXjalC9diTDCvxxWu5ZQUcYWEE821nhVRMcE> <did:ng:i> <did:ng:j> }");
+//         // await ng.sparql_update(session.session_id, "INSERT { ?s <did:ng:i> <did:ng:k> } WHERE { ?s <did:ng:i> <did:ng:j> } ");
+
+//         // await ng.sparql_update(session.session_id, "INSERT DATA {  <did:ng:z> <did:ng:j> <did:ng:t:BJQ5gCLoXXjalC9diTDCvxxWu5ZQUcYWEE821nhVRMcE>. <did:ng:t:BJQ5gCLoXXjalC9diTDCvxxWu5ZQUcYWEE821nhVRMcE> <did:ng:m> <did:ng:n> }");
+//         //await ng.sparql_update(session.session_id, "INSERT DATA {  <did:ng:z> <did:ng:j> [ <did:ng:m> <did:ng:n> ]. }");
+//         //await ng.sparql_update(session.session_id, "INSERT DATA {  [ <did:ng:m> <did:ng:n> ] <did:ng:ok> <did:ng:v>  . }");
+//         //await ng.sparql_update(session.session_id, "INSERT {  ?a <did:ng:ok> <did:ng:v>  . } WHERE { ?a <did:ng:m> <did:ng:n>  } ");
+//         //await ng.sparql_update(session.session_id, "INSERT DATA {  <did:ng:z> <did:ng:j> _:1 . _:1 <did:ng:m> <did:ng:n>. }");
+//         //await ng.sparql_update(session.session_id, "INSERT DATA {  _:f766ca988268ddc60315ddd5bd621387 <did:ng:o> <did:ng:>. }");
+//         //await ng.sparql_update(session.session_id, "INSERT {  _:_ <did:ng:ok> <did:ng:v>  . } WHERE { _:_ <did:ng:m> <did:ng:n>  } ");
+//         //await ng.sparql_update(session.session_id, "INSERT DATA {  _:_ <abc:a> <d:a>  .  _:_a <abceee:a> <d:a>  . }");
+        
+//         //await ng.sparql_update(session.session_id, "INSERT DATA {  <> <a:selftest> <a:selftest>  . }",base);
+
+//         //await ng.sparql_update(session.session_id, "INSERT DATA { <did:ng:TEST4>  <did:ng:j> _:_  .   _:_ <did:ng:m> <did:ng:n>  . }");
+//         //await ng.sparql_update(session.session_id, "INSERT DATA {  <did:ng:TEST5> <did:ng:j> [ <did:ng:m> <did:ng:n> ]. }");
+
+//         // sparql_result = await ng.sparql_query(session.session_id, "SELECT ?a WHERE { ?a <did:ng:j> _:abc. _:abc <did:ng:m> <did:ng:n>  }", base);
+//         // console.log(sparql_result);
+//         // for (const q of sparql_result.results.bindings) {
+//         //     console.log(q);
+//         // }
+
+//         // sparql_result = await ng.sparql_query(session.session_id, "SELECT ?s ?a WHERE { ?s <did:ng:j> ?a  }", base);
+//         // console.log(sparql_result);
+//         // for (const q of sparql_result.results.bindings) {
+//         //     console.log(q);
+//         // }
+
+//         // console.log("******** CONSTRUCT2")
+
+//         // let quads = await ng.sparql_query(session.session_id, "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }",base);
+//         // for (const q of quads) {
+//         //     console.log(q.subject.toString(), q.predicate.toString(), q.object.toString(), q.graph.toString())
+//         // }
+
+//         // let file_nuri = await ng.file_put_to_private_store(session.session_id,"LICENSE-MIT","text/plain");
+//         // console.log(file_nuri);
+
+//         // //let file_nuri = "did:ng:j:AD_d4njVMAtIDEU1G-RDxfOLIOZyOrB_1Rb7B6XykIEJ:k:APV-_Xtk03PW_Mbl4OaYpLrmEkBDVtn81lpto8sxc_tb";
+//         // var bufs = [];
+//         // let cancel = await ng.file_get_from_private_store(session.session_id, file_nuri, async (file) => {
+//         //     if (file.V0.FileMeta) {
+//         //       //skip
+//         //     } else if (file.V0.FileBinary) {
+//         //       if (file.V0.FileBinary.byteLength > 0) {
+//         //         bufs.push(file.V0.FileBinary);
+//         //       } 
+//         //     } else if (file.V0 == 'EndOfStream') {
+//         //         //console.log("end of file");
+//         //         var buf = Buffer.concat(bufs);
+//         //         // if the file contains some UTF8 text
+//         //         console.log(buf.toString('utf8'));
+//         //     }
+//         // });
+
+//         // the 2nd argument `false` means: do not `force_close` the dataset. 
+//         // it will be detached, which means it stays in memory even when the session is stopped. 
+//         // (not all the dataset is in memory anyway! just some metadata)
+//         // if you set this to true, the dataset is closed and removed from memory on the server.
+//         // next time you will open a session for this user, the dataset will be loaded again.
+//         let res = await ng.session_headless_stop(session.session_id, false);
+//         //console.log(res);
+
+//     } catch (e) {
+//         console.error(e);
+//         if (session_id) await ng.session_headless_stop(session_id, true);
+//     }
+// })
+// .catch(err => {
+//     console.error(err);
+// });
diff --git a/ng-sdk-js/app-node/package-lock.json b/ng-sdk-js/app-node/package-lock.json
index 6ae012a3..6626c18b 100644
--- a/ng-sdk-js/app-node/package-lock.json
+++ b/ng-sdk-js/app-node/package-lock.json
@@ -9,13 +9,14 @@
       "version": "0.1.0",
       "license": "(MIT OR Apache-2.0)",
       "dependencies": {
-        "nextgraph": "^0.1.0",
+        "nextgraph": "^0.1.1",
         "ws": "^8.13.0"
       }
     },
     "../pkg-node": {
       "name": "nextgraph",
       "version": "0.1.0",
+      "extraneous": true,
       "license": "MIT/Apache-2.0"
     },
     "node_modules/bufferutil": {
@@ -32,6 +33,11 @@
         "node": ">=6.14.2"
       }
     },
+    "node_modules/nextgraph": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/nextgraph/-/nextgraph-0.1.1.tgz",
+      "integrity": "sha512-hTRfI9YVZ+nBaqBq6k2fUIzoaSQER5pMdz/eOHYo6XSMJS9CQNRo8Ko0eHb3rj4gZR3r5ox+G6t4IaoCiAsxsw=="
+    },
     "node_modules/node-gyp-build": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz",
@@ -90,6 +96,11 @@
         "node-gyp-build": "^4.3.0"
       }
     },
+    "nextgraph": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/nextgraph/-/nextgraph-0.1.1.tgz",
+      "integrity": "sha512-hTRfI9YVZ+nBaqBq6k2fUIzoaSQER5pMdz/eOHYo6XSMJS9CQNRo8Ko0eHb3rj4gZR3r5ox+G6t4IaoCiAsxsw=="
+    },
     "node-gyp-build": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz",
diff --git a/ng-sdk-js/app-node/package.json b/ng-sdk-js/app-node/package.json
index 5108a89f..a9789e79 100644
--- a/ng-sdk-js/app-node/package.json
+++ b/ng-sdk-js/app-node/package.json
@@ -13,7 +13,7 @@
   "author": "Niko PLP <niko@nextgraph.org>",
   "license": "(MIT OR Apache-2.0)",
   "dependencies": {
-    "nextgraph": "^0.1.0",
+    "nextgraph": "^0.1.1",
     "ws": "^8.13.0"
   }
 }
diff --git a/ng-sdk-js/app-web/index.js b/ng-sdk-js/app-web/index.js
index 2df021e5..7e7f2de1 100644
--- a/ng-sdk-js/app-web/index.js
+++ b/ng-sdk-js/app-web/index.js
@@ -9,7 +9,9 @@
 
 import * as ng from "ng-sdk-js";
 
-import test from './test';
-ng.test();
-test();
-console.log(ng.start());
+// import test from './test';
+// ng.test();
+// test();
+//console.log(ng.start());
+
+await ng.wallet_read_file
\ No newline at end of file
diff --git a/ng-sdk-js/app-web/package.json b/ng-sdk-js/app-web/package.json
index c099d4f2..9ff2ace2 100644
--- a/ng-sdk-js/app-web/package.json
+++ b/ng-sdk-js/app-web/package.json
@@ -24,7 +24,7 @@
   },
   "homepage": "https://docs.nextgraph.org",
   "dependencies": {
-    "ng-sdk-js": "^0.1.0"
+    "ng-sdk-js": "^0.1.1"
   },
   "devDependencies": {
     "webpack": "^4.29.3",
diff --git a/ng-sdk-js/app-web/test.js b/ng-sdk-js/app-web/test.js
index 86e6c44c..93780b88 100644
--- a/ng-sdk-js/app-web/test.js
+++ b/ng-sdk-js/app-web/test.js
@@ -2,7 +2,7 @@
 import * as ng from "ng-sdk-js";
 
 function test() {
-    ng.test()
+    //ng.test()
 }
 
 export default test;
\ No newline at end of file
diff --git a/ng-sdk-js/js/node.js b/ng-sdk-js/js/node.js
index 36ad6caa..70126727 100644
--- a/ng-sdk-js/js/node.js
+++ b/ng-sdk-js/js/node.js
@@ -151,6 +151,7 @@ module.exports.upload_file = async ( filename, callback, end) => {
 
 module.exports.client_details = function () {
   const process = require('process');
+  const osnode = require('os');
   let arch = osnode.machine? osnode.machine() : process.arch;
   if (arch=="ia32") {arch="x86"}
   else if (arch=="x64") {arch="x86_64"}
@@ -158,7 +159,6 @@ module.exports.client_details = function () {
   else if (arch=="i686") {arch="x86"}
   else if (arch=="amd64") {arch="x86_64"}
   else if (arch=="arm64") {arch="aarch64"}
-  const osnode = require('os');
   let os = osName(osnode.platform(),osnode.release());
   if (osnode.version) os.uname = osnode.version();
   os.type = osnode.type();
diff --git a/ng-sdk-js/src/lib.rs b/ng-sdk-js/src/lib.rs
index 56175391..24275045 100644
--- a/ng-sdk-js/src/lib.rs
+++ b/ng-sdk-js/src/lib.rs
@@ -258,6 +258,23 @@ pub async fn session_start(wallet_name: String, user_js: JsValue) -> Result<JsVa
     Ok(serde_wasm_bindgen::to_value(&res).unwrap())
 }
 
+#[wasm_bindgen]
+pub async fn session_in_memory_start(
+    wallet_name: String,
+    user_js: JsValue,
+) -> Result<JsValue, String> {
+    let user_id = serde_wasm_bindgen::from_value::<PubKey>(user_js)
+        .map_err(|_| "Deserialization error of user_id")?;
+
+    let config = SessionConfig::new_in_memory(&user_id, &wallet_name);
+    let res: SessionInfoString = nextgraph::local_broker::session_start(config)
+        .await
+        .map_err(|e: NgError| e.to_string())?
+        .into();
+
+    Ok(serde_wasm_bindgen::to_value(&res).unwrap())
+}
+
 #[cfg(wasmpack_target = "nodejs")]
 #[wasm_bindgen]
 pub async fn session_headless_start(user_js: String) -> Result<JsValue, String> {