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

Initial commit for basic gateway package #1619

Merged
merged 6 commits into from
Oct 24, 2023

Conversation

otherview
Copy link
Contributor

Why this change is needed

https://github.com/obscuronet/obscuro-internal/issues/2321

This PR adds a gateway.js package that allows for the centralization of js operations that were being copied and duplicated in a few upcoming tools. Also adds tooling so that the js can be published and other tools can include it.
Tools can now include it as an NPM package or directly import it.

  • Adds gateway.js with the core operations
  • Adds gateway.test.js to test core logic (pretty simple at this stage)
  • Adds flows to build and deploy the js package

It's still missing the update to the wallet extension FE, but that will only work after the js is deployed as WE is a pure FE without Nodejs packaging.

@coderabbitai
Copy link

coderabbitai bot commented Oct 23, 2023

Walkthrough

This pull request introduces a new JavaScript library, "Obscuro Gateway JS", for interacting with the Obscuro network. It includes the addition of a Gateway class with methods for joining and registering an account, unit tests for these methods, and the necessary GitHub Actions workflows for building and deploying the library. The library is designed for easy consumption and seamless connection to the Obscuro network.

Changes

File(s) Summary
.github/workflows/build-gateway-lib.yml,
.github/workflows/deploy-gateway-lib.yml
Adds GitHub Actions workflows for building, testing, and deploying the JavaScript library.
tools/gateway-js/gateway-lib/.eslintrc.js Adds an ESLint configuration file for maintaining code quality.
tools/gateway-js/gateway-lib/webpack.config.js Adds a Webpack configuration file for bundling the JavaScript library.
tools/gateway-js/gateway-lib/gateway.js Introduces the Gateway class with methods for interacting with the Obscuro network.
tools/gateway-js/gateway-lib/gateway.test.js Adds unit tests for the Gateway class, covering both successful and unsuccessful scenarios.
tools/gateway-js/gateway-lib/dist/gateway.bundle.js Includes changes to the Gateway module, introducing new classes and modifying existing ones.
tools/gateway-js/gateway-lib/README.md Adds a README file with installation instructions, usage examples, and build commands for the new library.

Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • If you reply to a review comment from CodeRabbit, the bot will automatically respond.
  • To engage with CodeRabbit bot directly around the specific lines of code in the PR, mention @coderabbitai in your review comment
  • Note: Review comments are made on code diffs or files, not on the PR overview.
  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai help to get help.

Note: For conversation with the bot, please use the review comments on code diffs or files.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.json

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 8
Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 8f89805 and fcedafe.
Files ignored due to filter (2)
  • tools/gateway-js/gateway-lib/package-lock.json
  • tools/gateway-js/gateway-lib/package.json
Files selected for processing (7)
  • .github/workflows/build-gateway-lib.yml (1 hunks)
  • .github/workflows/deploy-gateway-lib.yml (1 hunks)
  • tools/gateway-js/gateway-lib/.eslintrc.js (1 hunks)
  • tools/gateway-js/gateway-lib/dist/gateway.bundle.js (1 hunks)
  • tools/gateway-js/gateway-lib/gateway.js (1 hunks)
  • tools/gateway-js/gateway-lib/gateway.test.js (1 hunks)
  • tools/gateway-js/gateway-lib/webpack.config.js (1 hunks)
Files skipped from review due to trivial changes (4)
  • .github/workflows/build-gateway-lib.yml
  • .github/workflows/deploy-gateway-lib.yml
  • tools/gateway-js/gateway-lib/.eslintrc.js
  • tools/gateway-js/gateway-lib/dist/gateway.bundle.js (diff too large)
Additional comments (Suppressed): 4
tools/gateway-js/gateway-lib/gateway.js (4)
  • 1-3: The axios library is used for HTTP requests. This is a good choice as it provides a wide range of features and is widely used in the JavaScript community. However, it's important to ensure that the version of axios being used is up-to-date and free of known vulnerabilities.

  • 40-42: The method checks if the signature is -1 and returns "Signing failed" if it is. This seems to be a specific error condition, but it's not clear why -1 would indicate a failure. It would be helpful to add a comment explaining this.

  • 63-73: The userID, http, and ws methods are simple getter methods that return the user ID, HTTP URL, and WebSocket URL, respectively. These are straightforward and don't seem to have any issues.

  • 76-76: The Gateway class is exported as a module. This allows it to be imported and used in other parts of the codebase. This is a good practice for modularity and code reuse.

tools/gateway-js/gateway-lib/gateway.test.js Outdated Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.test.js Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.test.js Outdated Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.js Outdated Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.js Outdated Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.js Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0
Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between fcedafe and d981d50.
Files selected for processing (1)
  • tools/gateway-js/gateway-lib/gateway.test.js (1 hunks)
Additional comments (Suppressed): 6
tools/gateway-js/gateway-lib/gateway.test.js (6)
  • 16-18: The beforeEach block is still being used to initialize a new Gateway instance before each test. However, in the tests for registerAccount (lines 42 and 52), a new Gateway instance is created again with a mocked provider. This redundancy has not been addressed yet. Consider moving the provider mock to the beforeEach block and remove the additional Gateway instance creation in the registerAccount tests.

  • 38-40: The fetch mock is still set to resolve with an object that has a text method, which is also a mock that resolves with 'Account registered'. This simulates the behavior of the fetch API, which returns a Promise that resolves with a Response object, and the text method of the Response object also returns a Promise. However, it would be more accurate to simulate a real Response object by including a status property in the mock. This would also allow you to write tests for different HTTP status codes.

  • 20-29: The test 'should join successfully' mocks the axios.get method to resolve with a status of 200 and a data of 'testUserID'. It then calls the join method of the Gateway instance and checks if the userID property of the Gateway instance is set to 'testUserID'. This is a good test for the successful execution of the join method.

  • 31-35: The test 'should throw error on unsuccessful join' mocks the axios.get method to reject with a 'Network error'. It then calls the join method of the Gateway instance and checks if it throws the expected error. This is a good test for the error handling in the join method.

  • 37-49: The test 'should register account successfully' mocks the fetch method and the request method of the provider to resolve with 'Account registered' and 'mockSignature' respectively. It then calls the registerAccount method of the Gateway instance and checks if it returns 'Account registered'. This is a good test for the successful execution of the registerAccount method.

  • 51-57: The test 'should throw error on unsuccessful account registration' mocks the request method of the provider to reject with a 'Signature error'. It then calls the registerAccount method of the Gateway instance and checks if it throws the expected error. This is a good test for the error handling in the registerAccount method.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 6
Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between d981d50 and d914756.
Files selected for processing (4)
  • tools/gateway-js/gateway-lib/README.md (1 hunks)
  • tools/gateway-js/gateway-lib/dist/gateway.bundle.js (1 hunks)
  • tools/gateway-js/gateway-lib/gateway.js (1 hunks)
  • tools/gateway-js/gateway-lib/gateway.test.js (1 hunks)
Files skipped from review due to trivial changes (2)
  • tools/gateway-js/gateway-lib/README.md
  • tools/gateway-js/gateway-lib/dist/gateway.bundle.js (diff too large)
Additional comments (Suppressed): 4
tools/gateway-js/gateway-lib/gateway.test.js (1)
  • 16-18: The previous comment about redundancy in creating new Gateway instances in the registerAccount tests still stands. Consider refactoring the beforeEach block to include a mocked provider and remove the additional Gateway instance creation in the registerAccount tests.
-    beforeEach(() => {
-        gateway = new Gateway(httpURL, wsURL, provider);
-    });
+    beforeEach(() => {
+        provider = {
+            request: jest.fn().mockResolvedValue("mockSignature")
+        };
+        gateway = new Gateway(httpURL, wsURL, provider);
+    });
tools/gateway-js/gateway-lib/gateway.js (3)
  • 1-3: The axios library is being used for HTTP requests. This is a popular choice due to its promise-based nature and ease of use. However, it's important to ensure that the version of axios being used is up-to-date and free of known vulnerabilities. Please verify this.

  • 62-72: The userID, http, and ws methods are used to retrieve the user ID and the HTTP and WebSocket URLs. These are simple getter methods and seem to be implemented correctly.

  • 75-75: The Gateway class is being exported as a module. This allows it to be imported and used in other parts of the application. This is a standard practice in Node.js and seems to be implemented correctly.

tools/gateway-js/gateway-lib/gateway.test.js Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.test.js Outdated Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.js Outdated Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.js Outdated Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.js Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.js Outdated Show resolved Hide resolved
Copy link
Contributor

@0xjba 0xjba left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upon initial review, it LGTM and could enhance the gateway's integration into projects without requiring a UI.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 4

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between d914756 and e6c941e.
Files selected for processing (3)
  • tools/gateway-js/gateway-lib/dist/gateway.bundle.js (1 hunks)
  • tools/gateway-js/gateway-lib/gateway.js (1 hunks)
  • tools/gateway-js/gateway-lib/gateway.test.js (1 hunks)
Files skipped from review due to trivial changes (2)
  • tools/gateway-js/gateway-lib/dist/gateway.bundle.js
  • tools/gateway-js/gateway-lib/gateway.test.js
Additional comments: 1
tools/gateway-js/gateway-lib/gateway.js (1)
  • 42-44: The check for signature === -1 is still unclear. It would be helpful to add a comment explaining why this specific value indicates a failure, as it's not immediately clear from the context.

tools/gateway-js/gateway-lib/gateway.js Show resolved Hide resolved
tools/gateway-js/gateway-lib/gateway.js Show resolved Hide resolved
Comment on lines +28 to +63
async registerAccount(address) {
const message = `Register ${this.userID} for ${address.toLowerCase()}`;
let signature = ""

try {
signature = await this.provider.request({
method: "personal_sign",
params: [message, address]
})
} catch (err) {
throw new Error(`Failed to sign message. ${err}`);
}

// todo make further checks on the data
if (signature === -1) {
return "Signing failed"
}

try {
const authenticateUserURL = pathAuthenticate+"?u="+this.userId
const authenticateFields = {"signature": signature, "message": message}
const authenticateResp = await axios.post(
authenticateUserURL,
authenticateFields,
{
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
}
}
);
// todo make further checks on the data
return await authenticateResp.text()
} catch (error) {
throw new Error(`Failed to register account. ${error}`);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The registerAccount method constructs a message and signs it using the provider, but it does not handle the case where the provider fails to sign the message. This could lead to unexpected behavior or errors later on. Consider adding a check to ensure that signature is not null or empty before proceeding with the authentication request.

Comment on lines +66 to +76
userID() {
return this.userId;
}

http() {
return `${this.httpURL}/v1/?u=${this.userId}`;
}

ws() {
return `${this.wsURL}/v1/?u=${this.userId}`;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The userID, http, and ws methods return values derived from this.userId, but do not handle the case where this.userId is null or empty. This could lead to unexpected behavior or errors later on. Consider adding checks to ensure that this.userId is not null or empty before returning these values.

const axios = require("axios");

class Gateway {
    constructor(httpURL, wsURL, provider, obscuroGatewayVersion = "v1") {
        this.httpURL = httpURL;
        this.wsURL = wsURL;
        this.userId = '';
        this.provider = provider;
        this.pathJoin = obscuroGatewayVersion + "/join/";
       this.pathAuthenticate = obscuroGatewayVersion + "/authenticate/";
   }

   async join() {
       try {
           const response = await axios.get(`${this.httpURL}${this.pathJoin}`);
           if (response.status !== 200 || !response.data) {
               throw new Error(`Failed to get userID. Status code: ${response.status}`);
           }
           // todo make further checks on the data
           this.userId = response.data;
       } catch (error) {
           throw new Error(`Failed to get userID. ${error}`);
       }
   }

   async registerAccount(address) {
       const message = `Register ${this.userID} for ${address.toLowerCase()}`;
       let signature = ""

       try {
               signature = await this.provider.request({
                   method: "personal_sign",
                   params: [message, address]
               })
           } catch (err) {
               throw new Error(`Failed to sign message. ${err}`);
           }

       // todo make further checks on the data
       if (signature === -1 || !signature) {
           return "Signing failed"
       }

       try {
           const authenticateUserURL = this.pathAuthenticate+"?u="+this.userId
           const authenticateFields = {"signature": signature, "message": message}
           const authenticateResp = await axios.post(
               authenticateUserURL,
               authenticateFields,
               {
                   headers: {
                       "Accept": "application/json",
                       "Content-Type": "application/json"
                   }
               }
           );
           // todo make further checks on the data
           return await authenticateResp.text()
       } catch (error) {
           throw new Error(`Failed to register account. ${error}`);
       }
   }

   userID() {
       if (!this.userId) {
           throw new Error("User ID is not set.");
       }
       return this.userId;
   }

   http() {
       if (!this.userId) {
           throw new Error("User ID is not set.");
       }
       return `${this.httpURL}/v1/?u=${this.userId}`;
   }

   ws() {
       if (!this.userId) {
           throw new Error("User ID is not set.");
       }
       return `${this.wsURL}/v1/?u=${this.userId}`;
   }
}

module.exports = Gateway;
Committable suggestion (Beta)
Suggested change
userID() {
return this.userId;
}
http() {
return `${this.httpURL}/v1/?u=${this.userId}`;
}
ws() {
return `${this.wsURL}/v1/?u=${this.userId}`;
}
const axios = require("axios");
class Gateway {
constructor
<!-- This is an auto-generated comment by CodeRabbit -->

@otherview otherview merged commit a140f35 into main Oct 24, 2023
2 checks passed
@otherview otherview deleted the pedro/add_base_gateway_js_package branch October 24, 2023 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants