Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable TypeScript/JavaScript implementation to be used in a browser #609

Open
bestbeforetoday opened this issue Jun 28, 2023 · 2 comments · May be fixed by #701
Open

Enable TypeScript/JavaScript implementation to be used in a browser #609

bestbeforetoday opened this issue Jun 28, 2023 · 2 comments · May be fixed by #701
Assignees
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@bestbeforetoday
Copy link
Member

bestbeforetoday commented Jun 28, 2023

As a front-end developer
I want to use the client API directly from the browser
So that a back-end Node.js server is not required as an intermediary

The key issues are the use of Node packages in the implementation, and some exposure of Node packages in the public API. This includes:

The core of the implementation either is or can be implemented without using any Node-specific packages. A workable approach seems to be to split this core capability out into a separate package, which can be depended on by the fabric-gateway package. The fabric-gateway package will then only contain Node-specific additions, such as the default signer, hash and checkpointer implementations. @noble/hashes should provide secure random and hash implementations required by the core package (for transactioncontext.ts) without any dependency on Node.js.

The alternatives available with the existing implementation are:

  1. Use a Node.js back-end server do interact with Fabric on behalf of the browser using the fabric-gateway API, and the off-line signing flow to enable the browser to handle signing using the signing credentials held there.
  2. Use the Gateway gRPC service directly using the @hyperledger/fabric-protos package.
@bestbeforetoday bestbeforetoday added the enhancement New feature or request label Jun 28, 2023
@bestbeforetoday
Copy link
Member Author

I created a prototype implementation by:

  1. Move all the Node client code that can be implemented without using Node standard packages into a node/src/core sub-directory. This required:
    1. Implement a simple alternative to a usage of util.inspect in transactionparser.ts.
    2. Use @noble/hashes/sha256 for SHA-256 hash in signingidentity.ts and transactioncontext.ts.
    3. Use @noble/hashes/utils for randomBytes in transactioncontext.ts.
    4. The few files and index.ts remaining in the top-level node/src import (and export) node/src/core as required.
  2. Add an node/src/core/index.ts file to act as a single entry point to all the pure JavaScript code.
  3. Use esbuild to generate a single bundle.js file from all the content in node/dist/core.

The restructuring of the code seems to be successful but the bundling process highlighted that @grpc/grpc-js itself relies on several built-in Node packages. These can be polyfilled but whether or not it will work with these polyfills is uncertain. A fully browser-compatible (no polyfill) implementation would probably need grpc-web to be used instead of @grpc/grpc-js. This appears at first look to be impractical since:

  1. grpc-web currently does not provide all the required gRPC capability. Bi-directional streaming (used for block eventing) is not supported.
  2. The fabric-gateway API accepts a grpc-js Client object as the gRPC connection to use.

@bestbeforetoday
Copy link
Member Author

bestbeforetoday commented Oct 6, 2023

My current thinking is that refactoring the current Node implementation so that it (or parts of it) can be run in a browser environment is impractical. It probably makes sense to make use of the WebCrypto (SubtleCrypto) API, and the digest() function it provides is asynchronous. This would cause a breaking change to the synchronous getDigest() and (to a lesser extent) Hash functions exposed by the Fabric Gateway client API.

Since the primary use case is to modify the off-line signing flow by both generating and signing request messages at the client to avoid the need for the server to generate messages and return them to the client for signing, a more practical approach might be to lift and refactor a subset of the existing code out into a separate browser package. This would include capability to:

  • Directly build cut-down variants of the Proposal, Transaction, Commit and ChaincodeEventsRequest objects.
  • The built objects would only provide capability to:
    • Serialize themselves - equivalent of getBytes().
    • Return the full message content to be signed - equivalent of getDigest() when the none hash is used to pass back the message unaltered.

An optional addition would be to directly build similar, cut-down variants of the block event request objects: FilteredBlockEventsRequest, BlockEventsRequest and BlockAndPrivateDataEventsRequest.

The fabric-protos package also has a dependency on @grpc/grpc-js since it includes gRPC service stubs. As described in previous comments, @grpc/grpc-js has dependencies on many standard Node packages. It might be necessary to build and package within this browser package a subset of the fabric-protos, including only the ones needed to build the objects described above, and excluding gRPC services. Since the browser environment would only interact with the Fabric Gateway client API indirectly by passing serialised protocol buffer messages, this should not present a compatibility problem, since wire-level interoperability of serialized protocol buffer messages is robust.

@bestbeforetoday bestbeforetoday added the help wanted Extra attention is needed label Jan 13, 2024
@bestbeforetoday bestbeforetoday self-assigned this Apr 4, 2024
@bestbeforetoday bestbeforetoday linked a pull request Apr 4, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant