diff --git a/.gitignore b/.gitignore
index d09eed8950..ba34d50c8a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -78,7 +78,7 @@ cardano-wasm/grpc-example/cardano-wasm.wasm
cardano-wasm/grpc-example/cardano-wasm.js
cardano-wasm/grpc-example/cardano-api.d.ts
cardano-wasm/grpc-example/cardano-api.js
-cardano-wasm/grpc-example/node_grpc_web_pb.js
+cardano-wasm/grpc-example/cardano_node_grpc_web_pb.js
cardano-wasm/example/cardano-wasm.wasm
cardano-wasm/example/cardano-wasm.js
cardano-wasm/example/cardano-api.d.ts
diff --git a/cardano-wasm/README.md b/cardano-wasm/README.md
index abf53f35f8..798ba18407 100644
--- a/cardano-wasm/README.md
+++ b/cardano-wasm/README.md
@@ -239,19 +239,8 @@ To run the example in the `example` subfolder:
To run the example in the `grpc-example` subfolder:
1. Run an instance of the `cardano-node` with the GRPC server enabled and put the socket file for the GRPC server in the root folder of this repo with the name `rpc.socket`. (You can put it somewhere else, but you will have to update the `envoy-conf.yaml` function later.)
-2. Generate the JS GRPC client bundle `node_grpc_web_pb.js` from the GRPC server proto files by either:
- - Running `nix build .#proto-js-bundle`. (This will generate it under the `result` folder.)
- - Or using `protoc`, `npm` and `browserify`:
- ```
- protoc -I../../cardano-rpc/proto --js_out=import_style=commonjs,binary:./ --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. ../../cardano-rpc/proto/cardano/rpc/node.proto
-
- npm install grpc-web
-
- npm install google-protobuf
-
- browserify --standalone grpc cardano/rpc/node_grpc_web_pb.js > node_grpc_web_pb.js
- ```
-3. Copy the generated `node_grpc_web_pb.js` file to the `grpc-example` subfolder.
+2. Generate the JS GRPC client bundle `cardano_node_grpc_web_pb.js` from the GRPC server proto files by running `nix build .#proto-js-bundle`. (This will generate it under the `result` folder.)
+3. Copy the generated `cardano_node_grpc_web_pb.js` file to the `grpc-example` subfolder.
4. Copy the generated `cardano-wasm.wasm` file to the `grpc-example` subfolder. You can find its location using:
```console
echo "$(env -u CABAL_CONFIG wasm32-wasi-cabal list-bin exe:cardano-wasm | tail -n1)"
diff --git a/cardano-wasm/grpc-example/envoy-conf.yaml b/cardano-wasm/grpc-example/envoy-conf.yaml
index 38a3efe700..c2702b8874 100644
--- a/cardano-wasm/grpc-example/envoy-conf.yaml
+++ b/cardano-wasm/grpc-example/envoy-conf.yaml
@@ -93,7 +93,7 @@ static_resources:
body:
filename: "./example.js"
- match:
- path: "/node_grpc_web_pb.js"
+ path: "/cardano_node_grpc_web_pb.js"
response_headers_to_add:
- header:
key: "Content-Type"
@@ -101,7 +101,7 @@ static_resources:
direct_response:
status: 200
body:
- filename: "./node_grpc_web_pb.js"
+ filename: "./cardano_node_grpc_web_pb.js"
http_filters:
- name: envoy.filters.http.grpc_web
typed_config:
diff --git a/cardano-wasm/grpc-example/index.html b/cardano-wasm/grpc-example/index.html
index ec13bf9915..fc83897fd6 100644
--- a/cardano-wasm/grpc-example/index.html
+++ b/cardano-wasm/grpc-example/index.html
@@ -3,7 +3,7 @@
cardano-wasm test
-
+
Test output
diff --git a/cardano-wasm/src/Cardano/Wasm/Internal/JavaScript/GRPC.hs b/cardano-wasm/src/Cardano/Wasm/Internal/JavaScript/GRPC.hs
index a1445683a7..14b9bcb595 100644
--- a/cardano-wasm/src/Cardano/Wasm/Internal/JavaScript/GRPC.hs
+++ b/cardano-wasm/src/Cardano/Wasm/Internal/JavaScript/GRPC.hs
@@ -9,14 +9,16 @@ module Cardano.Wasm.Internal.JavaScript.GRPC (js_newWebGrpcClient, js_getEra) wh
import GHC.Wasm.Prim
-- | Create a GRPC-web client for the Cardano API.
-foreign import javascript safe "new grpc.NodePromiseClient($1, null, null)"
+foreign import javascript safe "{ node: new cardano_node.node.NodePromiseClient($1, null, null), \
+ query: new cardano_node.query.QueryServicePromiseClient($1, null, null) \
+ }"
js_newWebGrpcClientImpl :: JSString -> IO JSVal
js_newWebGrpcClient :: String -> IO JSVal
js_newWebGrpcClient = js_newWebGrpcClientImpl . toJSString
-- | Get the era from the Cardano API using a GRPC-web client.
-foreign import javascript safe "($1).getEra(new proto.Empty(), {})"
+foreign import javascript safe "($1).node.getEra(new proto.Empty(), {})"
js_getEra :: JSVal -> IO Int
#endif
diff --git a/nix/proto-to-js.nix b/nix/proto-to-js.nix
index e1f7c1efff..b990b87650 100644
--- a/nix/proto-to-js.nix
+++ b/nix/proto-to-js.nix
@@ -43,8 +43,9 @@ in pkgs.stdenv.mkDerivation {
mkdir -p "$GEN_JS_PATH"
mkdir -p "$BUNDLE_PATH"
- echo "--- Compiling .proto file: $PROTO_FILE ---"
+ echo "--- Compiling .proto files in $PROTO_INCLUDE_PATH ---"
+ # Find all .proto files and compile them.
for PROTO_FILE in `find "$PROTO_INCLUDE_PATH" -type f -name "*.proto"`
do
protoc \
@@ -57,32 +58,55 @@ in pkgs.stdenv.mkDerivation {
echo "--- Compilation finished. Generated files are in $GEN_JS_PATH ---"
ls -R "$GEN_JS_PATH"
- # Check if there are any files in the top-level generated directory
- if [ ! "$(ls -1 "$GEN_JS_PATH" | head -n 1)" ]; then
- echo "Error: protoc did not generate any gRPC-Web files!"
- exit 1
- fi
+ # Generate JS file that imports the generated files for Browserify
+ ENTRYPOINT_FILE=$GEN_JS_PATH/index.js
+ echo "--- Creating browserify entrypoint: $ENTRYPOINT_FILE ---"
+
+ # Ensure the entrypoint file is empty before we start.
+ rm -f $ENTRYPOINT_FILE
+ touch "$ENTRYPOINT_FILE"
+
+ # Find all *_grpc_web_pb.js files and build the entrypoint content.
+ for JS_FULLPATH in `find "$GEN_JS_PATH" -type f -name "*_grpc_web_pb.js"`
+ do
+ # Get the filename, e.g., "node_grpc_web_pb.js"
+ JS_FILENAME=$(basename "$JS_FULLPATH")
+
+ # Extract the module name by removing the suffix
+ MODULE_NAME=''${JS_FILENAME%_grpc_web_pb.js}
+
+ # Get the path relative to GEN_JS_PATH for the require() statement.
+ RELATIVE_PATH=''${JS_FULLPATH#$GEN_JS_PATH/}
+
+ echo "Adding module '$MODULE_NAME' from './$RELATIVE_PATH' to bundle."
+ # Append the export line to our entrypoint file.
+ # This creates the desired submodule structure.
+ echo "exports.$MODULE_NAME = require('./$RELATIVE_PATH');" >> "$ENTRYPOINT_FILE"
+ done
+
+ echo "--- Generated entrypoint content: ---"
+ cat "$ENTRYPOINT_FILE"
echo "--- Setting up node_modules for browserify ---"
ln -s ${node-deps}/node_modules ./node_modules
- echo "--- Bundling generated JS with browserify ---"
+ echo "--- Bundling all generated JS gRPC modules with browserify ---"
- for GENERATED_GRPC_FILE in `find "$GEN_JS_PATH" -type f -name "*.js"`
- do
- browserify --standalone grpc "$GENERATED_GRPC_FILE" > "$BUNDLE_PATH/$(basename $GENERATED_GRPC_FILE)"
- done
+ # Bundle the entrypoint file into a single standalone module.
+ # The --standalone flag exposes the exports under the 'cardano_node' global variable.
+ browserify "$ENTRYPOINT_FILE" --standalone cardano_node > "$BUNDLE_PATH/cardano_node_grpc_web_pb.js"
- echo "--- Bundling complete. Final files are in $BUNDLE_PATH ---"
- ls "$BUNDLE_PATH"
+ echo "--- Bundling complete. Final file is in $BUNDLE_PATH ---"
+ ls -l "$BUNDLE_PATH"
runHook postBuild
'';
installPhase = ''
runHook preInstall
- mkdir -p "$out"
- cp ./bundled-js/*_grpc_web_pb.js "$out/"
+ mkdir -p $out
+ # Copy the final, correctly named bundle to the output directory.
+ cp ./bundled-js/cardano_node_grpc_web_pb.js $out/
runHook postInstall
'';