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

Web browser API implementation #701

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,19 @@ jobs:
with:
name: java-doc
path: java/target/site/apidocs/

web:
runs-on: ubuntu-22.04
name: Web documentation
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Generate documentation
run: make generate-docs-web
- name: Upload documentation
uses: actions/upload-artifact@v4
with:
name: web-doc
path: web/apidocs/
17 changes: 17 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,20 @@ jobs:
run: make pull-latest-peer
- name: Run scenario tests
run: make scenario-test-java

web_unit:
needs: verify-versions
runs-on: ubuntu-22.04
name: Unit test Web
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Run unit tests
run: make unit-test-web
- name: Upload bundle
uses: actions/upload-artifact@v4
with:
name: web-bundle
path: web/fabric-gateway-web.js
18 changes: 18 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ base_dir := $(patsubst %/,%,$(dir $(realpath $(lastword $(MAKEFILE_LIST)))))
go_dir := $(base_dir)/pkg
node_dir := $(base_dir)/node
java_dir := $(base_dir)/java
web_dir := $(base_dir)/web
scenario_dir := $(base_dir)/scenario

go_bin_dir := $(shell go env GOPATH)/bin
Expand Down Expand Up @@ -49,6 +50,12 @@ build-java:
cd "$(java_dir)" && \
mvn -DskipTests install

.PHONEY: build-web
build-web:
cd "$(web_dir)" && \
npm install && \
npm run build

.PHONEY: unit-test
unit-test: generate lint unit-test-go unit-test-node unit-test-java

Expand All @@ -72,6 +79,11 @@ unit-test-java:
cd "$(java_dir)" && \
mvn test

.PHONEY: unit-test-web
unit-test-web: build-web
cd "$(web_dir)" && \
npm test

.PHONEY: lint
lint: staticcheck golangci-lint

Expand Down Expand Up @@ -214,6 +226,12 @@ generate-docs-java:
cd "$(java_dir)" && \
mvn javadoc:javadoc

.PHONEY: generate-docs-web
generate-docs-web:
cd "$(web_dir)" && \
npm install && \
npm run generate-apidoc

.PHONEY: test
test: shellcheck unit-test scenario-test

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ The following Makefile targets are available:
- `make unit-test-go-pkcs11` - run unit tests for the Go client API, including HSM tests
- `make unit-test-node` - run unit tests for the Node client API
- `make unit-test-java` - run unit tests for the Java client API
- `make unit-test-web` - run unit tests for the Web client API
- `make unit-test` - run unit tests for all client language implementations
- `make pull-latest-peer` - fetch the latest peer docker image containing the gateway server
- `make scenario-test-go` - run the scenario (end to end integration) tests for Go client API, including HSM tests
Expand Down
7 changes: 3 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ require (
github.com/stretchr/testify v1.9.0
go.uber.org/mock v0.4.0
golang.org/x/crypto v0.21.0
google.golang.org/grpc v1.62.1
google.golang.org/grpc v1.63.0
google.golang.org/protobuf v1.33.0
)

Expand All @@ -19,14 +19,13 @@ require (
github.com/cucumber/messages/go/v21 v21.0.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-memdb v1.3.4 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
14 changes: 6 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx
github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
Expand Down Expand Up @@ -58,16 +56,16 @@ go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8 h1:IR+hp6ypxjH24bkMfEJ0yHR21+gwPWdV+/IBrPQyn3k=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240304212257-790db918fca8/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs=
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8=
google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
4 changes: 2 additions & 2 deletions java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.14.2</version>
<version>10.15.0</version>
</dependency>
</dependencies>
</plugin>
Expand All @@ -387,7 +387,7 @@
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>9.0.10</version>
<version>9.1.0</version>
<configuration>
<skipProvidedScope>true</skipProvidedScope>
<skipTestScope>true</skipTestScope>
Expand Down
12 changes: 6 additions & 6 deletions node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@
"pkcs11js": "^2.1.0"
},
"devDependencies": {
"@cyclonedx/cyclonedx-npm": "^1.16.1",
"@tsconfig/node18": "^18.2.2",
"@cyclonedx/cyclonedx-npm": "^1.16.2",
"@tsconfig/node18": "^18.2.4",
"@types/google-protobuf": "^3.15.12",
"@types/jest": "^29.5.12",
"@types/node": "^18.19.22",
"@typescript-eslint/eslint-plugin": "~7.3.1",
"@typescript-eslint/parser": "~7.3.1",
"@types/node": "^18.19.29",
"@typescript-eslint/eslint-plugin": "~7.5.0",
"@typescript-eslint/parser": "~7.5.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jest": "^27.9.0",
Expand All @@ -58,6 +58,6 @@
"prettier": "^3.2.5",
"ts-jest": "^29.1.2",
"typedoc": "^0.25.11",
"typescript": "~5.4.2"
"typescript": "~5.4.3"
}
}
4 changes: 2 additions & 2 deletions node/src/signingidentity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { Signer } from './identity/signer';
export const undefinedSignerMessage = 'No signing implementation';

const undefinedSigner: Signer = () => {
throw new Error(undefinedSignerMessage);
return Promise.reject(new Error(undefinedSignerMessage));
};

type SigningIdentityOptions = Pick<ConnectOptions, 'identity' | 'signer' | 'hash'>;
Expand Down Expand Up @@ -55,7 +55,7 @@ export class SigningIdentity {
return this.#hash(message);
}

async sign(digest: Uint8Array): Promise<Uint8Array> {
sign(digest: Uint8Array): Promise<Uint8Array> {
return this.#sign(digest);
}
}
2 changes: 1 addition & 1 deletion pkg/client/example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func NewGrpcConnection() (*grpc.ClientConn, error) {
certPool.AddCert(tlsCertificate)
transportCredentials := credentials.NewClientTLSFromCert(certPool, "")

return grpc.Dial("gateway.example.org:1337", grpc.WithTransportCredentials(transportCredentials))
return grpc.NewClient("dns:///gateway.example.org:1337", grpc.WithTransportCredentials(transportCredentials))
}

// NewIdentity creates a client identity for this Gateway connection using an X.509 certificate.
Expand Down
4 changes: 4 additions & 0 deletions scenario/fixtures/rest/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
dist/
coverage/
package-lock.json
33 changes: 33 additions & 0 deletions scenario/fixtures/rest/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "fabric-gateway-rest",
"version": "0.0.1",
"description": "REST server for fabric-gateway-web clients",
"main": "dist/index.js",
"engines": {
"node": ">=18.12.0"
},
"scripts": {
"format": "prettier '**/*.{ts,js}' --check",
"format:fix": "prettier '**/*.{ts,js}' --write",
"lint": "eslint .",
"postinstall": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"license": "Apache-2.0",
"dependencies": {
"@grpc/grpc-js": "^1.10.4",
"@hyperledger/fabric-gateway": "file:../../../node/fabric-gateway-dev.tgz",
"express": "^4.19.2"
},
"devDependencies": {
"@tsconfig/node18": "^18.2.2",
"@types/express": "^4.17.21",
"@types/node": "^18.19.22",
"@typescript-eslint/eslint-plugin": "~7.3.1",
"@typescript-eslint/parser": "~7.3.1",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"prettier": "^3.2.5",
"typescript": "~5.4.2"
}
}
37 changes: 37 additions & 0 deletions scenario/fixtures/rest/src/gateway.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Gateway } from '@hyperledger/fabric-gateway';
import express, { Express } from 'express';
import { Server } from './server';

const REST_PORT = 3000;

export interface GatewayServerOptions {
port: number;
gateway: Gateway;
}

export class GatewayServer {
#gateway: Gateway;
#server: Server;

constructor(options: GatewayServerOptions) {
this.#gateway = options.gateway;
this.#server = new Server({
port: options.port,
handlers: [this.#evaluate],
});
}

start(): Promise<void> {
return this.#server.start();
}

stop(): Promise<void> {
return this.#server.stop();
}

#evaluate(app: Express): void {
app.post('/evaluate', express.json(), (request, response) => {
request.body.proposal;
});
}
}
Empty file.
28 changes: 28 additions & 0 deletions scenario/fixtures/rest/src/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import express, { Express } from 'express';
import * as http from 'node:http';

export interface ServerOptions {
port: number;
handlers: ((app: Express) => void)[];
}

export class Server {
readonly #app = express();
readonly #port: number;
#server?: http.Server;

constructor(options: ServerOptions) {
this.#port = options.port;
options.handlers.forEach((handler) => handler(this.#app));
}

start(): Promise<void> {
return new Promise((resolve) => {
this.#server = this.#app.listen(this.#port, resolve);
});
}

stop(): Promise<void> {
return new Promise((resolve, reject) => this.#server?.close((err) => (err ? resolve() : reject(err))));
}
}
15 changes: 15 additions & 0 deletions scenario/fixtures/rest/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/node18/tsconfig.json",
"compilerOptions": {
"declaration": false,
"sourceMap": true,
"outDir": "dist",
"rootDir": "src",
"strict": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/"]
}
5 changes: 2 additions & 3 deletions scenario/go/scenario_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"fmt"
"os"
"reflect"
"strconv"
"strings"

"github.com/cucumber/godog"
Expand Down Expand Up @@ -180,10 +179,10 @@ func connectGateway(peer string) error {
certPool := x509.NewCertPool()
certPool.AddCert(certificate)

url := conn.host + ":" + strconv.FormatUint(uint64(conn.port), 10)
url := fmt.Sprintf("dns:///%s:%d", conn.host, conn.port)

transportCredentials := credentials.NewClientTLSFromCert(certPool, conn.serverNameOverride)
clientConn, err := grpc.Dial(url, grpc.WithTransportCredentials(transportCredentials))
clientConn, err := grpc.NewClient(url, grpc.WithTransportCredentials(transportCredentials))
if err != nil {
return err
}
Expand Down
12 changes: 6 additions & 6 deletions scenario/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@
"@hyperledger/fabric-protos": "^0.3.0"
},
"devDependencies": {
"@cucumber/cucumber": "^10.3.1",
"@tsconfig/node18": "^18.2.2",
"@types/node": "^18.19.22",
"@typescript-eslint/eslint-plugin": "~7.3.1",
"@typescript-eslint/parser": "~7.3.1",
"@cucumber/cucumber": "^10.3.2",
"@tsconfig/node18": "^18.2.4",
"@types/node": "^18.19.29",
"@typescript-eslint/eslint-plugin": "~7.5.0",
"@typescript-eslint/parser": "~7.5.0",
"cucumber-console-formatter": "^1.0.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"expect": "^29.7.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.2.5",
"typescript": "~5.4.2"
"typescript": "~5.4.3"
}
}
Loading