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

feat: Create new data access to allow for in-memory transactions. #1386

Merged
merged 47 commits into from
Jul 17, 2024

Conversation

aimensahnoun
Copy link
Member

@aimensahnoun aimensahnoun commented Apr 9, 2024

Resolves #1380, Resolves #1331

Description:

  • Create a new NoPersistHttpDataAccess in order to bypass the persistence of a request while it's being created.
  • Add the skipPersistenceboolean to http-request-network to use NoPersistHttpDataAccess instead of the default HttpDataAccess.
  • Add persistTransaction method to RequestNetwork.
  • Add prepareRequestDataForPayment method in order to create a structured request object that can be used for paying the request.

Summary by CodeRabbit

  • New Features

    • Added skipPersistence option in transaction handling, allowing creation without immediate persistence.
    • Enhanced request management with new methods for handling transaction data and preparing payment requests.
    • Introduced inMemoryInfo property for handling in-memory requests and pre-persistence operations.
  • Improvements

    • Increased flexibility in transaction handling with conditional instantiation based on skipPersistence.
    • Enhanced request logic layer with new parameters for in-memory request creation.

Walkthrough by CodeRabbit (copied from comment that got buried in the comments below)

Walkthrough

The recent updates to request-client.js introduce mechanisms enabling payment requests to be created and processed in-memory before being persisted. These changes include the addition of new methods and properties in key classes (RequestNetwork, Request, HttpRequestNetwork) that support the creation, handling, and conditional persistence of in-memory payment requests. The updates aim to optimize user experience by shortening the critical path for payment operations and offering more flexibility in request handling.

Changes

Files/Modules Change Summary
.../src/api/request-network.ts Added prepareRequestDataForPayment and persistRequest methods to RequestNetwork class. Introduced ClientTypes and ExtensionTypes imports. Updated dataAccess property signature.
.../src/api/request.ts Introduced inMemoryInfo property in Request class to handle in-memory requests, including transaction data, topics, and payment request data.
.../src/http-request-network.ts Added skipPersistence parameter in HttpRequestNetwork constructor and conditionally instantiated NoPersistHttpDataAccess based on this parameter. Updated the options interface to include skipPersistence.
.../src/request-logic-types.ts Introduced IInMemoryInfo interface for in-memory request handling, specifying transaction data, topics, and request data.

Sequence Diagram(s)

Omitted because the diagram was incorrect.

Assessment against linked issues

Objective Addressed Explanation
Enable the creation and payment of in-memory requests before persistence (#1380, #1331)
Introduce an InMemoryTransactionManager for handling transactions without immediate persistence (#1380)
Update HttpRequestNetwork to support skipPersistence option (#1380, #1331)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

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 an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • 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/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@aimensahnoun aimensahnoun linked an issue Apr 9, 2024 that may be closed by this pull request
@aimensahnoun aimensahnoun marked this pull request as draft April 9, 2024 13:59
Copy link
Member

@MantisClone MantisClone left a comment

Choose a reason for hiding this comment

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

This looks like the right approach to me! Please add some unit tests in the transaction-manager to show that it works as intended.

@aimensahnoun aimensahnoun marked this pull request as ready for review April 12, 2024 11:47
@aimensahnoun aimensahnoun self-assigned this Apr 12, 2024
Copy link
Member

@MantisClone MantisClone left a comment

Choose a reason for hiding this comment

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

@aimensahnoun I think I lead you to the wrong implementation.

I now believe we should make the InMemoryTransactionManager functions available on the regular TransactionManager.
Reason: I want to persistInMemoryTransaction() from the RequestClient layer.

transaction-manager.ts pseudocode

public async persistTransaction() {
  processTransaction()
  persistTransactionToDataAccess()
}
public async createInMemoryTransaction() {
  processTransaction()
}
public async persistInMemoryTransaction() {
  persistTransactionToDataAccess()
} 

Then, we can make these functions available on the layers above.

request-client.ts & request-logic pseudocode

public async createRequest(bool inMemory?) {
   if inMemory {
     eventually calls createInMemoryTransaction()
   }
   else {
     eventually calls persistTransaction()
   }
}
public async _createEncryptedRequest(bool inMemory?) {
   if inMemory {
     eventually calls createInMemoryTransaction()
   }
   else {
     eventually calls persistTransaction()
   }
}
// Should handle persisting cleartext and encrypted requests
// Should throw error if Request is already persisted.
public async persistInMemoryRequest() {
  eventually calls persistInMemoryTransaction()
}

Context

Originally, I proposed we create an InMemoryTransactionManagerwith a persistTransaction() function that it returns the request, in-memory, without actually persisting it on-chain.

Why not inject InMemoryTransactionManager?

Injecting InMemoryTransactionManager is great for creating an in-memory request because it doesn't require any new functions. But we still must create a new function to persist an in-memory Request. This new function should be available at the request-client.js layer.

We could make the developer interact with the InMemoryTransactionManager instance, but that deviates from convention - where creating and retrieving requests is available at the request-client.js layer without interacting with lower layers.

What happens if someone calls RequestNetwork.persistInMemoryRequest(Request) with a regular TransactionManager instead of an InMemoryTransactionManager? It would fail as "Not Implemented".

In the injected design, the InMemoryTransactionManager.persistTransaction() doesn't actually persist the transaction. This is misleading.

I thought we were moving away from runtime config and towards static composition and dependency injection to reduce download time #1202

The ability to create a Request on the frontend and persist it from the backend is a common request from our builders so enabling it on the normal TransactionManager class makes sense. 🙆
This change won't bloat the download size because the RequestLogic is extracted to utility functions to avoid code duplication.

Update an In-Memory Request?

Should we make it possible to update an in-memory request? Such that when we persist it persists the creation AND subsequent updates?

I'm leaning towards no because I can't think of a use case and I'd rather not bother with that complexity if we don't need to.

Copy link
Member

@alexandre-abrioux alexandre-abrioux left a comment

Choose a reason for hiding this comment

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

Hi, the idea is great! I haven't read through the code yet, but could you explain the need to inject the whole TransactionManager, and not just a custom DataAccess? At Request Finance we handle #1380 and #1331 by injecting our own DataAccess implementation, which does the "write" part asynchronously. Users can pay their request before it exists on the network.

Here is pseudo-code:

/**
 * A DataAccess Writer that publishes transactions in the database
 * It does not wait for them to succeed
 */
export class DatabaseDataWrite implements DataAccessTypes.IDataWrite {
  constructor(
    private dbConnection: Connection,
    private pendingStore: DataAccessTypes.IPendingStore,
  ) {}
  async initialize(): Promise<void> {
    return Promise.resolve();
  }
  async close(): Promise<void> {
    return Promise.resolve();
  }
  async persistTransaction(
    transaction: DataAccessTypes.ITransaction,
    channelId: string,
    topics?: string[],
  ): Promise<DataAccessTypes.IReturnPersistTransaction> {
    const id = uuid.v4();

    // "Fire and forget" the transaction: it will be saved in DB and handled asynchronously
    // We don't listen to the confirmation
    await this.dbConnection.save({
      transaction,
      channelId,
      topics,
    });

    logger.info(`Published message ${id} for ${channelId}`);

    // Return a dummy transaction
    //  in order for the transaction-manager to continue processing successfully
    const transactionRaw: DataAccessTypes.IReturnPersistTransactionRaw = {
      meta: {
        topics,
        // a temporary location ID, to help with debugging
        transactionStorageLocation: id,
        storageMeta: {
          state: StorageTypes.ContentState.PENDING,
          timestamp: Utils.getCurrentTimestampInSecond(),
          ipfs: {
            size: 1,
          },
          storageType: StorageTypes.StorageSystemType.LOCAL,
        },
      },
      result: {},
    };

    // We don't need to confirm the transaction here.
    const storageResult: StorageTypes.IAppendResult = Object.assign(
      new EventEmitter(),
      {
        id,
        content: "",
        meta: transactionRaw.meta.storageMeta,
      } as StorageTypes.IEntry,
    );
    this.pendingStore.add(channelId, {
      topics,
      transaction,
      storageResult,
    });

    return Object.assign(new EventEmitter(), transactionRaw);
  }
}

/** A Data Access that uses a database to create transactions, and a Graph Node to read them */
export class DatabaseDataAccess extends CombinedDataAccess {
  constructor(
    subgraphUrl: string,
    pubsubTopic: string,
    chainName: string,
    dbConnection: Connection,
  ) {
    // this is useful only at creation; the Request Client needs to read
    // the request right after creating it, which would fail or take a long time
    // if using the subgraph.
    const pendingStore = new PendingStore();
    super(
      new TheGraphDataAccess({
        graphql: {
          url: subgraphUrl,
        },
        network: chainName,
        pendingStore,
        logger,
      }),
      new DatabaseDataWrite(dbConnection, pendingStore),
    );
  }

  _getStatus(): Promise<DataAccessTypes.IDataAccessStatus> {
    throw new Error("Method not implemented.");
  }
}

Then, when it's time to persist it, use any IPFS client to submit the transaction. and the EthereumTransactionSubmitter to add it on-chain (no need to install the whole Request Network library for that part, nor instantiate the whole client).

@MantisClone
Copy link
Member

@alexandre-abrioux your comment convinced me we should inject this feature at the DataAccess layer, instead of the TransactionManager layer.

My Goal

  1. RN SDK provides a function to Create and return a request in-memory, without persisting, including signature and encryption, on the front end.
  2. RN SDK provides a function to Persist an in-memory request by sending it to a Request Node, from the backend.

I want a good developer experience for (1) and (2). In my opinion, this means it's accessible via the RequestNetwork Client object.

Proposed Solution

Implement (1) by injecting a not-yet-implemented NoConfirmHttpDataAccess and calling requestNetwork.createRequest()
Implement (2) by injecting an HttpDataAccess and calling not-yet-implemented requestNetwork.persistRequest()

The NoConfirmHttpDataAccess will be very similar to the existing HttpDataAccess except that it will "Fire and Forget" similar to the DatabaseDataWrite pseudocode posted by @alexandre-abrioux

The HttpRequestNetwork will need a new boolean argument skipCreateConfirmation. When true It will instantiate a NoConfirmHttpDataAccess.

The proposed persistRequest() function would be added to the RequestNetwork base class and will call this.dataAccess.persistTransaction() - skipping the RequestLogic and TransactionManager layers.

FYI @aimensahnoun

@aimensahnoun aimensahnoun marked this pull request as draft May 3, 2024 11:51
@aimensahnoun aimensahnoun changed the title feat: create InMemoryTransactionManager class for in memory transac… feat: Create new data access to allow for in-memory transactions. Jun 6, 2024
@aimensahnoun aimensahnoun marked this pull request as ready for review July 17, 2024 13:15
@github-actions github-actions bot requested a review from leoslr July 17, 2024 13:15
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.

Actionable comments posted: 4

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 8e91696 and 8027739.

Files selected for processing (5)
  • packages/request-client.js/src/api/request-network.ts (7 hunks)
  • packages/request-client.js/src/http-request-network.ts (4 hunks)
  • packages/request-client.js/src/no-persist-http-data-access.ts (1 hunks)
  • packages/request-client.js/test/http-request-network.test.ts (1 hunks)
  • packages/request-client.js/test/in-memory-request.test.ts (1 hunks)
Additional context used
Biome
packages/request-client.js/src/no-persist-http-data-access.ts

[error] 3-3: A Node.js builtin module should be imported with the node: protocol.

Using the node: protocol is more explicit and signals that the imported module belongs to Node.js.
Unsafe fix: Add the node: protocol.

(lint/style/useNodejsImportProtocol)

Additional comments not posted (13)
packages/request-client.js/src/no-persist-http-data-access.ts (2)

5-19: Constructor Implementation Review

The constructor of NoPersistHttpDataAccess properly delegates initialization to the superclass HttpDataAccess using the provided configurations. This ensures that any setup done by the superclass is preserved.


21-47: Review of persistTransaction Method

The persistTransaction method is designed to simulate transaction persistence by immediately emitting a 'confirmed' event without actually persisting the data. This fits the requirement for in-memory transaction handling. However, ensure that this behavior is clearly documented to avoid confusion, as it deviates from typical persistence expectations.

packages/request-client.js/test/in-memory-request.test.ts (2)

8-38: Review of Test Setup and Teardown

The setup and teardown methods are appropriately configured to ensure a clean testing environment. The use of mockServer to simulate network responses is a good practice. Additionally, the spyPersistTransaction mock function setup is crucial for verifying that the persistTransaction method is not called unexpectedly.


46-80: Test Coverage for In-Memory Request Handling

The tests cover the creation of a request without persisting it and the expected behavior when attempting to persist such a request. These tests are crucial for validating the new functionality introduced in the PR. Ensure that these tests are included in the continuous integration process to maintain coverage.

packages/request-client.js/test/http-request-network.test.ts (1)

21-21: Review of Test Handler Reset

Replacing mockServer.restoreHandlers() with mockServer.resetHandlers() in the afterEach hook is a good practice. It ensures that each test starts with a clean state, which is crucial for test isolation and reliability.

packages/request-client.js/src/api/request-network.ts (5)

7-7: Addition of ClientTypes:
The addition of ClientTypes appears to be necessary for the new functionality related to handling client-specific data types. Ensure that all new types are properly documented and used consistently throughout the codebase.


12-12: Addition of ExtensionTypes:
The addition of ExtensionTypes is essential for managing different extensions, particularly in the context of payment requests. It's important to ensure that these types are integrated seamlessly with the existing codebase and that they are used correctly in the new methods introduced.


25-25: Import of NoPersistHttpDataAccess:
The import of NoPersistHttpDataAccess is crucial for the new feature allowing requests to be handled in memory. This class should be thoroughly reviewed to ensure it adheres to the expected behaviors of not persisting data.


37-37: Modification of dataAccess declaration:
The modification to make dataAccess a private member is a good practice, enhancing encapsulation. This change should be accompanied by appropriate access methods if external access is required.


194-224: Method persistRequest Review:
The persistRequest method is used to persist in-memory requests. It properly throws errors if the request was not created with skipPersistence or if the data access layer does not support persistence. This is a critical method for the new functionality, ensuring that requests can be transitioned from in-memory to persisted state securely.

The error messages are clear and informative, which is good for user experience. However, ensure that these errors are handled gracefully in the calling code to prevent crashes or unintended behavior.

Verification successful

Error Handling for persistRequest Verified:
The persistRequest method's error handling is verified through tests in in-memory-request.test.ts. These tests ensure that the errors thrown by persistRequest are correctly handled.

  • Tests check for errors using expect(...).rejects.toThrow(...).
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify error handling in calling code for `persistRequest`.

# Test: Search for calls to `persistRequest` and check for error handling.
rg --type python -A 5 $'persistRequest'

Length of output: 69


Script:

#!/bin/bash
# Description: Verify error handling in calling code for `persistRequest`.

# Test: Search for calls to `persistRequest` and check for error handling.
rg --type ts -A 5 'persistRequest'

Length of output: 2355

packages/request-client.js/src/http-request-network.ts (3)

14-14: Import statement for NoPersistHttpDataAccess is correctly placed.


Line range hint 40-49: Review of new parameter skipPersistence in the constructor.

The addition of the skipPersistence parameter is correctly implemented. It's well integrated into the options object with a default value.

Also applies to: 53-53


58-62: Conditional instantiation based on skipPersistence.

The logic to conditionally instantiate NoPersistHttpDataAccess based on the skipPersistence flag is correctly implemented. This allows for flexibility in transaction handling based on the persistence requirement.

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.

Actionable comments posted: 2

Outside diff range comments (1)
packages/request-client.js/src/api/request-network.ts (1)

Line range hint 146-184: Correct spelling and consider refactoring createRequest method.

There's a minor spelling mistake in isSkipingPersistence. It should be isSkippingPersistence. Also, the method's complexity has increased with the new functionality. Consider refactoring to separate the concerns more clearly, perhaps by extracting parts of the logic into smaller, more focused methods.

- const isSkipingPersistence = this.dataAccess instanceof NoPersistHttpDataAccess;
+ const isSkippingPersistence = this.dataAccess instanceof NoPersistHttpDataAccess;

Refactoring suggestion: Extract the logic related to handling in-memory transactions into a separate method to improve readability and maintainability.

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 8027739 and c3b08ad.

Files selected for processing (1)
  • packages/request-client.js/src/api/request-network.ts (7 hunks)
Additional comments not posted (2)
packages/request-client.js/src/api/request-network.ts (2)

Line range hint 225-266: Refer to createRequest method review.

The considerations for error handling, spelling corrections, and potential refactoring in the createRequest method apply here as well. Please refer to the comments made on that method for applicable improvements.


Line range hint 267-317: Method fromRequestId looks good.

This method handles the retrieval of requests by ID effectively, including handling both confirmed and pending states. The implementation is clear and adheres to coding standards.

packages/request-client.js/src/api/request-network.ts Outdated Show resolved Hide resolved
packages/request-client.js/src/api/request-network.ts 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.

Actionable comments posted: 3

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between c3b08ad and 11b3121.

Files selected for processing (1)
  • packages/request-client.js/src/api/request-network.ts (7 hunks)
Additional context used
Learnings (1)
packages/request-client.js/src/api/request-network.ts (2)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:57:39.144Z
Learning: The data passed to the `preparePaymentRequest` method in the `RequestNetwork` class is reliably formatted by the transaction manager, negating the need for additional error handling for data formatting within this method.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:50:20.447Z
Learning: The transaction manager in the Request Network SDK formats the data ensuring its integrity before it reaches methods like `preparePaymentRequest`.
Additional comments not posted (5)
packages/request-client.js/src/api/request-network.ts (5)

7-7: New import added: ClientTypes

This import is necessary for the new features introduced in this PR, specifically for handling client-specific types in the RequestNetwork class.


12-12: New import added: ExtensionTypes

This import is crucial for handling extension-specific types used in the new preparePaymentRequest method.


37-37: Modification to dataAccess property

The dataAccess property has been modified to accommodate instances of both DataAccessTypes.IDataAccess and NoPersistHttpDataDataAccess. This change is essential for the new feature that allows skipping persistence.


62-62: Assignment of dataAccess within constructor

This line is crucial as it ensures that the dataAccess instance passed to the constructor is used throughout the class. This change is aligned with the new feature requirements.


74-145: New method: preparePaymentRequest

This method prepares a payment request structure from transaction data, which is a key part of the new feature allowing payments before persistence. The method appears to handle the data correctly and efficiently, creating a structured request object.

However, there is no error handling for JSON parsing, which could lead to runtime errors if the data is malformed. Given the previous discussions and learnings, it seems the transaction manager ensures data integrity before it reaches this method, making additional error handling redundant.

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.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 11b3121 and 7b71180.

Files selected for processing (2)
  • packages/request-client.js/src/http-request-network.ts (4 hunks)
  • packages/request-client.js/test/in-memory-request.test.ts (1 hunks)
Additional comments not posted (4)
packages/request-client.js/src/http-request-network.ts (3)

29-29: Clarification of skipPersistence option in constructor documentation.

The documentation for the skipPersistence option is clear and aligns with the PR objectives to allow transactions without immediate persistence. This is a good practice as it enhances the understanding for future developers.


49-49: Implementation of conditional data access instantiation.

The implementation correctly handles the skipPersistence flag to conditionally instantiate NoPersistHttpDataDataAccess or HttpDataAccess. This is a crucial feature for enabling transactions without immediate persistence and aligns well with the PR objectives.

Also applies to: 53-53, 58-62


14-14: Consider removing unused import if not needed.

The import of NoPersistHttpDataAccess appears to be used conditionally based on the skipPersistence flag. Ensure that it is indeed utilized and not just imported without a purpose.

Verification successful

The import of NoPersistHttpDataAccess is used and necessary.

The NoPersistHttpDataAccess is utilized in conditional statements within the codebase, confirming that the import is required and should not be removed.

  • packages/request-client.js/src/http-request-network.ts
  • packages/request-client.js/src/api/request-network.ts
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `NoPersistHttpDataAccess` across the codebase.

# Test: Search for the usage of `NoPersistHttpDataAccess`. Expect: Usages in conditional statements.
rg --type python -A 5 $'NoPersistHttpDataAccess'

Length of output: 78


Script:

#!/bin/bash
# Description: Verify the usage of `NoPersistHttpDataAccess` across the codebase.

# Test: Search for the usage of `NoPersistHttpDataAccess`. Expect: Usages in conditional statements.
rg --type typescript -A 5 'NoPersistHttpDataAccess'

Length of output: 86


Script:

#!/bin/bash
# Description: Verify the usage of `NoPersistHttpDataAccess` across the codebase.

# Test: Search for the usage of `NoPersistHttpDataAccess`. Expect: Usages in conditional statements.
rg --type js -A 5 'NoPersistHttpDataAccess'

Length of output: 43


Script:

#!/bin/bash
# Description: Verify the usage of `NoPersistHttpDataAccess` across the codebase.

# Test: Search for the usage of `NoPersistHttpDataAccess` across all file types.
rg -A 5 'NoPersistHttpDataAccess'

Length of output: 4634

packages/request-client.js/test/in-memory-request.test.ts (1)

8-120: Comprehensive test suite for in-memory request handling.

The test suite thoroughly covers the functionalities introduced in the PR, including creating requests without persistence, handling errors when persistence is attempted incorrectly, and persisting in-memory requests properly. This ensures robust handling and error management for in-memory requests, aligning with the PR objectives.

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.

Actionable comments posted: 1

Outside diff range comments (4)
packages/request-client.js/src/api/request-network.ts (4)

Line range hint 146-186: Review of createRequest Method:

The modifications to accommodate in-memory requests are well-implemented. However, the method could benefit from clearer documentation, especially regarding the conditions under which persistence is skipped. Additionally, consider optimizing the creation of the Request object to avoid redundancy in the conditional logic.

+ // Check if persistence should be skipped and handle accordingly
+ const isSkippingPersistence = this.dataAccess instanceof NoPersistHttpDataAccess;
+ if (isSkippingPersistence) {
+   // Handle in-memory request creation
+   // Ensure all necessary data is present
+ }

Line range hint 225-268: Review of _createEncryptedRequest Method:

This method handles the creation of encrypted requests effectively. However, similar to createRequest, it could benefit from clearer documentation and potential optimization in the handling of in-memory requests.

+ // Check if persistence should be skipped and handle accordingly
+ const isSkippingPersistence = this.dataAccess instanceof NoPersistHttpDataAccess;
+ if (isSkippingPersistence) {
+   // Handle in-memory request creation
+   // Ensure all necessary data is present
+ }

Line range hint 293-324: Review of fromRequestId Method:

This method effectively retrieves a request based on its ID. The error handling for non-existent requests is appropriate. Consider adding more detailed logging for debugging purposes, especially when a request is not found.

+ // Log the error for better debugging
+ if (!requestAndMeta.result.request && !requestAndMeta.result.pending) {
+   console.error(localUtils.formatGetRequestFromIdError(requestAndMeta));
+   throw new Error(localUtils.formatGetRequestFromIdError(requestAndMeta));
+ }

Line range hint 350-386: Review of fromMultipleTopics Method:

This method efficiently retrieves an array of request instances based on multiple topics. It handles the creation and refresh of request objects well. Consider adding more detailed logging for debugging purposes, especially when requests are not found.

+ // Log the error for better debugging
+ if (!requestsAndMeta.result.requests.length) {
+   console.error('No requests found for the provided topics');
+ }
Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 7b71180 and a5d9668.

Files selected for processing (1)
  • packages/request-client.js/src/api/request-network.ts (7 hunks)
Additional context used
Learnings (1)
packages/request-client.js/src/api/request-network.ts (2)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:57:39.144Z
Learning: The data passed to the `preparePaymentRequest` method in the `RequestNetwork` class is reliably formatted by the transaction manager, negating the need for additional error handling for data formatting within this method.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:50:20.447Z
Learning: The transaction manager in the Request Network SDK formats the data ensuring its integrity before it reaches methods like `preparePaymentRequest`.
Additional comments not posted (3)
packages/request-client.js/src/api/request-network.ts (3)

Line range hint 269-292: Review of computeRequestId Method:

This method correctly computes the ID of a request. It is straightforward and does not appear to have any issues. Ensure that the parameters are validated before processing to avoid potential errors.


Line range hint 325-349: Review of fromIdentity Method:

This method correctly retrieves an array of request instances based on an identity. Ensure that the identity type is supported before processing to avoid unnecessary errors.


74-145: Review of preparePaymentRequest Method:

This method efficiently structures payment requests from transaction data. However, there are a few improvements and checks needed:

  1. Error Handling: The method assumes the transaction data is always correctly formatted. Considering the transaction data comes from external sources, it would be safer to add error handling around JSON parsing and data manipulation to prevent runtime errors.

  2. Data Integrity: Ensure that all necessary fields in transactionData are present before accessing them. This can prevent potential undefined errors.

  3. Performance: The method iterates over originalExtensionsData to build newExtensions. Consider optimizing this if originalExtensionsData can be large.

- const requestData = JSON.parse(transactionData.data as string).data;
+ try {
+   const requestData = JSON.parse(transactionData.data as string).data;
+ } catch (error) {
+   throw new Error('Invalid transaction data format');
+ }

- const newExtensions: RequestLogicTypes.IExtensionStates = {};
+ const newExtensions: RequestLogicTypes.IExtensionStates = originalExtensionsData.reduce((acc, extension) => {
+   if (extension.id !== ExtensionTypes.OTHER_ID.CONTENT_DATA) {
+     acc[extension.id] = {
+       events: [{
+         name: extension.action,
+         parameters: {
+           paymentAddress: extension.parameters.paymentAddress,
+           salt: extension.parameters.salt,
+         },
+         timestamp: requestData.parameters.timestamp,
+       }],
+       id: extension.id,
+       type: ExtensionTypes.TYPE.PAYMENT_NETWORK,
+       values: {
+         salt: extension.parameters.salt,
+         receivedPaymentAmount: '0',
+         receivedRefundancy: '0',
+         sentPaymentAmount: '0',
+         sentRefundAmount: '0',
+         paymentAddress: extension.parameters.paymentAddress,
+       },
+       version: extension.version,
+     };
+   }
+   return acc;
+ }, {});
Skipped due to learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:57:39.144Z
Learning: The data passed to the `preparePaymentRequest` method in the `RequestNetwork` class is reliably formatted by the transaction manager, negating the need for additional error handling for data formatting within this method.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:50:20.447Z
Learning: The transaction manager in the Request Network SDK formats the data ensuring its integrity before it reaches methods like `preparePaymentRequest`.

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.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between a5d9668 and 422e9e0.

Files selected for processing (1)
  • packages/request-client.js/src/api/request-network.ts (7 hunks)
Additional context used
Learnings (1)
packages/request-client.js/src/api/request-network.ts (2)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:57:39.144Z
Learning: The data passed to the `preparePaymentRequest` method in the `RequestNetwork` class is reliably formatted by the transaction manager, negating the need for additional error handling for data formatting within this method.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:50:20.447Z
Learning: The transaction manager in the Request Network SDK formats the data ensuring its integrity before it reaches methods like `preparePaymentRequest`.
Additional comments not posted (3)
packages/request-client.js/src/api/request-network.ts (3)

121-151: Review of persistRequest Method:

The method correctly handles the persistence of in-memory requests. The error handling for missing inMemoryInfo and unsupported data access instances is appropriate. However, consider enhancing the error messages to provide more context to developers:

- throw new Error('Cannot persist request without inMemoryInfo.');
+ throw new Error('Cannot persist request without inMemoryInfo. Ensure the request was created with skipPersistence enabled.');

- throw new Error(
-   'Cannot persist request when skipPersistence is enabled. To persist the request, create a new instance of RequestNetwork without skipPersistence being set to true.',
- );
+ throw new Error(
+   'Cannot persist request: the current data access instance does not support persistence. Please use a compatible data access instance.',
+ );

489-561: Review of preparePaymentRequest Method:

This method effectively prepares a structured request for payment purposes. It's essential to ensure that all fields are correctly extracted and that error handling is robust, especially given the potential complexity of transaction data parsing:

- const requestData = JSON.parse(transactionData.data as string).data;
+ try {
+   const requestData = JSON.parse(transactionData.data as string).data;
+ } catch (error) {
+   throw new Error('Invalid transaction data format');
+ }

Consider adding validations for transactionData and originalExtensionsData before processing them.


Line range hint 37-62: Review of Constructor Initialization:

The constructor correctly initializes various components and handles optional parameters well. However, it's crucial to ensure that all dependencies like currencyManager and paymentOptions are adequately tested, especially since they have default behaviors and conditional initializations.

Copy link
Member

@MantisClone MantisClone left a comment

Choose a reason for hiding this comment

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

Partial Review, about half way through.

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.

Actionable comments posted: 4

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 422e9e0 and 157530f.

Files selected for processing (4)
  • packages/request-client.js/src/api/request-network.ts (7 hunks)
  • packages/request-client.js/src/api/request.ts (3 hunks)
  • packages/request-client.js/test/in-memory-request.test.ts (1 hunks)
  • packages/types/src/request-logic-types.ts (2 hunks)
Additional context used
Learnings (2)
packages/request-client.js/test/in-memory-request.test.ts (1)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:25-25
Timestamp: 2024-07-17T15:06:14.563Z
Learning: The `persistTransaction()` function in the `no-persist-http-data-access.ts` file is tested in the `in-memory-request.test.ts` file, which is separate from the typical `index.test.ts` file to avoid test interference.
packages/request-client.js/src/api/request-network.ts (3)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:25-25
Timestamp: 2024-07-17T15:06:14.563Z
Learning: The `persistTransaction()` function in the `no-persist-http-data-access.ts` file is tested in the `in-memory-request.test.ts` file, which is separate from the typical `index.test.ts` file to avoid test interference.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:57:39.144Z
Learning: The data passed to the `preparePaymentRequest` method in the `RequestNetwork` class is reliably formatted by the transaction manager, negating the need for additional error handling for data formatting within this method.
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:50:20.447Z
Learning: The transaction manager in the Request Network SDK formats the data ensuring its integrity before it reaches methods like `preparePaymentRequest`.
Additional comments not posted (7)
packages/request-client.js/test/in-memory-request.test.ts (2)

46-60: Comprehensive test for creating a request without persistence.

This test effectively verifies that a request can be created with skipPersistence enabled, and it checks all relevant properties of the request to ensure they are populated correctly. Additionally, it confirms that persistTransaction is not called, which is crucial for the in-memory functionality.


96-119: Validates the persistence of an in-memory request.

This test effectively verifies that a request initially created with skipPersistence can be persisted later using a different instance of RequestNetwork. It correctly asserts that persistTransaction is called and checks the result of the persistence operation.

packages/request-client.js/src/api/request.ts (2)

82-90: Review of the new inMemoryInfo property addition.

The addition of the inMemoryInfo property is well-documented and clearly describes its purpose and usage. This change aligns with the PR's goal to handle requests in memory before persistence, allowing operations like payments to be processed beforehand.

  • Correctness: The property is correctly typed as RequestLogicTypes.IInMemoryInfo | null, which allows for proper handling of both scenarios where the in-memory data is available or not.
  • Documentation: The property is well-documented, with clear descriptions of each sub-property (transactionData, topics, requestData). This helps in understanding the role of each in the context of in-memory requests.

Overall, this addition appears to be well-implemented and serves its intended purpose effectively.


Line range hint 112-123: Review of constructor modifications to handle inMemoryInfo.

The constructor has been updated to accept an optional inMemoryInfo parameter. This is a crucial change as it integrates the in-memory request handling directly into the instantiation process of the Request object.

  • Correctness: The inMemoryInfo is correctly initialized with options?.inMemoryInfo || null, ensuring that it falls back to null if not provided. This is important for backward compatibility and cases where in-memory handling is not required.
  • Integration: The integration of inMemoryInfo into the constructor is seamless and does not interfere with existing parameters or the initialization of other properties.

This change is well-executed and necessary for the feature introduced by this PR. It allows the Request object to be instantiated with in-memory data when needed, supporting the new workflow described in the PR.

packages/types/src/request-logic-types.ts (1)

217-222: Review of the IInMemoryInfo Interface

The new interface IInMemoryInfo is well-defined and aligns with the PR objectives to manage in-memory transactions. It includes necessary fields like transactionData, topics, and requestData which are crucial for handling requests that are not immediately persisted.

However, it would be beneficial to add documentation comments to this interface to explain the purpose of each field and how it is intended to be used. This will improve maintainability and understandability for other developers.

packages/request-client.js/src/api/request-network.ts (2)

25-25: Review of NoPersistHttpDataAccess Import

The import of NoPersistHttpDataAccess is crucial for the new feature of handling in-memory transactions. This class allows the RequestNetwork to handle requests that are not immediately persisted.


121-151: Review of persistRequest Method

The new persistRequest method is crucial for persisting in-memory requests. It correctly checks if the request was created with skipPersistence enabled and throws appropriate errors if conditions are not met.

The method's implementation is clear and aligns with the functionality described in the PR. The error messages are specific and informative, which is good for debugging and developer experience.

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.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

Commits

Files that changed from the base of the PR and between 157530f and 487dffe.

Files selected for processing (1)
  • packages/request-client.js/src/http-request-network.ts (4 hunks)
Additional context used
Learnings (2)
Common learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:74-145
Timestamp: 2024-07-17T13:57:39.144Z
Learning: The data passed to the `preparePaymentRequest` method in the `RequestNetwork` class is reliably formatted by the transaction manager, negating the need for additional error handling for data formatting within this method.
packages/request-client.js/src/http-request-network.ts (1)
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:25-25
Timestamp: 2024-07-17T15:06:14.563Z
Learning: The `persistTransaction()` function in the `no-persist-http-data-access.ts` file is tested in the `in-memory-request.test.ts` file, which is separate from the typical `index.test.ts` file to avoid test interference.
Additional comments not posted (2)
packages/request-client.js/src/http-request-network.ts (2)

14-14: Consider removing unused import.

The import of NoPersistHttpDataAccess is commented out. If this class is not used, it should be removed to keep the code clean. If it's intended for future use, a comment explaining its purpose would be helpful.

Skipped due to learnings
Learnt from: MantisClone
PR: RequestNetwork/requestNetwork#1386
File: packages/request-client.js/src/api/request-network.ts:25-25
Timestamp: 2024-07-17T15:06:14.563Z
Learning: The `persistTransaction()` function in the `no-persist-http-data-access.ts` file is tested in the `in-memory-request.test.ts` file, which is separate from the typical `index.test.ts` file to avoid test interference.

Line range hint 40-62: Review of conditional instantiation logic for data access.

The logic for instantiating NoPersistHttpDataAccess or HttpDataAccess based on the skipPersistence flag is implemented correctly. However, ensure that the NoPersistHttpDataAccess class is fully compatible and tested, as it plays a crucial role in the new functionality.

Also, consider adding error handling or a fallback mechanism if neither useMockStorage nor skipPersistence conditions are met but the required configurations (httpConfig, nodeConnectionConfig) are incomplete or invalid.

@aimensahnoun aimensahnoun enabled auto-merge (squash) July 17, 2024 15:26
@aimensahnoun aimensahnoun merged commit 0320158 into master Jul 17, 2024
24 checks passed
@aimensahnoun aimensahnoun deleted the 1380-pay-before-persist branch July 17, 2024 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants