Skip to content

Feat/permissions module support#364

Merged
aarmoa merged 7 commits intodevfrom
feat/permissions_module_support
Jan 20, 2025
Merged

Feat/permissions module support#364
aarmoa merged 7 commits intodevfrom
feat/permissions_module_support

Conversation

@aarmoa
Copy link
Collaborator

@aarmoa aarmoa commented Dec 5, 2024

  • Updated all queries and messages for the Permissions module to support the new module version.
  • Updated unit tests
  • Fixed tests failing because of new fields in other gRPC queries and messages

NOTE: Do NOT merge this PR until the final version of proto definitions is available

Solves CHAIN-254

Summary by CodeRabbit

I'll craft concise release notes focusing on the key user-facing changes in version 1.9.0.

Release Notes for PyInjective v1.9.0

🌟 New Features

  • Added support for retrieving L3 orderbooks for both derivative and spot markets
  • Introduced market balance and denomination minimum notional queries
  • Enhanced permissions module with more granular role and policy management
  • Added new trading strategy and market statistics endpoints
  • Expanded token factory functionality with admin burn controls

🔧 Improvements

  • Updated trade and position streaming methods
  • Improved fee recipient tracking for trades
  • Enhanced error handling and API flexibility
  • Updated protocol buffer definitions for better compatibility

🔒 Breaking Changes

  • Renamed and restructured some permissions-related API methods
  • Modified some query and streaming method signatures

📦 Dependency Updates

  • Updated Injective indexer and core dependencies
  • Upgraded protocol buffer definitions

🚀 Recommended Upgrade

Users are advised to review the documentation and update their code to align with the new method signatures and features.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 5, 2024

Walkthrough

This pull request introduces significant updates to the PyInjective library, focusing on enhancing the permissions module, adding new market-related queries, and expanding the functionality of various API endpoints. The changes span across multiple components of the library, including protocol buffer definitions, client APIs, example scripts, and test suites. Key additions include support for new market balance queries, L3 orderbook retrieval, denomination minimum notional values, and a comprehensive overhaul of the permissions module's role and policy management capabilities.

Changes

File/Path Change Summary
CHANGELOG.md Added version 1.9.0 entry with new features and changes
Makefile Updated injective-indexer repository branch to v1.13.117_RC1
buf.gen.yaml Updated repository tags and added new repository entry
examples/chain_client/exchange/ Added new query examples for L3 orderbooks, market balances, and denomination minimum notionals
examples/chain_client/permissions/ Restructured permissions module examples with new role and policy management
pyinjective/async_client.py Added new methods for market balances, L3 orderbooks, and permissions queries
pyinjective/composer.py Enhanced permissions-related method signatures and added new composition methods
pyinjective/proto/ Extensive updates to protocol buffer definitions across multiple modules
tests/ Added and updated test cases to cover new functionalities

Sequence Diagram

sequenceDiagram
    participant Client
    participant AsyncClient
    participant ChainGrpcExchangeApi
    participant ChainGrpcPermissionsApi

    Client->>AsyncClient: fetch_l3_derivative_orderbook(market_id)
    AsyncClient->>ChainGrpcExchangeApi: L3DerivativeOrderBook
    ChainGrpcExchangeApi-->>AsyncClient: Orderbook Response
    AsyncClient-->>Client: Detailed Orderbook

    Client->>AsyncClient: fetch_permissions_namespace(denom)
    AsyncClient->>ChainGrpcPermissionsApi: Namespace
    ChainGrpcPermissionsApi-->>AsyncClient: Namespace Details
    AsyncClient-->>Client: Namespace with Roles and Policies
Loading

Poem

🐰 A Rabbit's Ode to PyInjective's Growth 🌱

In lines of code, a new version springs,
Permissions dance, and market balance sings!
L3 orderbooks unfurl their might,
With roles and policies shining bright 🌟

Hop along, dear developer's friend! 🚀


🪧 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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 using 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 generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

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.

…used for the v1.14 Testnet upgrade. Included the new fields and endpoints in the SDK API components and updated the example scripts
@aarmoa aarmoa marked this pull request as ready for review January 20, 2025 13:31
Copy link
Contributor

@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: 12

🧹 Nitpick comments (43)
tests/client/indexer/stream_grpc/test_indexer_grpc_derivative_stream.py (2)

818-820: Convert lambda callbacks to regular functions.

Instead of using lambda expressions for callbacks, define them as regular functions for better readability and maintainability.

-        callback = lambda update: positions.put_nowait(update)
-        error_callback = lambda exception: pytest.fail(str(exception))
-        end_callback = lambda: end_event.set()
+        def callback(update):
+            positions.put_nowait(update)
+            
+        def error_callback(exception):
+            pytest.fail(str(exception))
+            
+        def end_callback():
+            end_event.set()
🧰 Tools
🪛 Ruff (0.8.2)

818-818: Do not assign a lambda expression, use a def

Rewrite callback as a def

(E731)


819-819: Do not assign a lambda expression, use a def

Rewrite error_callback as a def

(E731)


820-820: Do not assign a lambda expression, use a def

Rewrite end_callback as a def

(E731)


853-854: Remove redundant comment.

The comment "Optional: cancel the task if needed" is redundant since the code clearly shows the intention.

-        # Optional: cancel the task if needed
         stream_task.cancel()
tests/client/chain/grpc/test_chain_grpc_auction_api.py (2)

26-30: Add documentation for the magic number.

Consider adding a comment explaining what the inj_basket_max_cap value "1000000000000000000000" represents (e.g., if it's in wei/atto units) to improve test readability.

 params = auction_pb.Params(
     auction_period=604800,
     min_next_bid_increment_rate="2500000000000000",
+    # 1000 INJ in atto/wei units (10^18)
     inj_basket_max_cap="1000000000000000000000",
 )

98-102: Consider using constants for test values.

To improve maintainability and reduce duplication, consider extracting common test values into class-level constants:

 class TestChainGrpcAuctionApi:
+    # Test constants
+    AUCTION_PERIOD = 604800
+    MIN_BID_INCREMENT = "2500000000000000"
+    INJ_BASKET_MAX_CAP = "1000000000000000000000"
+    AUCTION_ROUND = 50
+    AUCTION_TIMESTAMP = 1687504387

Then use these constants in the test methods:

 params = auction_pb.Params(
-    auction_period=604800,
-    min_next_bid_increment_rate="2500000000000000",
-    inj_basket_max_cap="1000000000000000000000",
+    auction_period=self.AUCTION_PERIOD,
+    min_next_bid_increment_rate=self.MIN_BID_INCREMENT,
+    inj_basket_max_cap=self.INJ_BASKET_MAX_CAP,
 )

Also applies to: 115-116

pyinjective/client/indexer/grpc_stream/indexer_grpc_derivative_stream.py (1)

242-242: Add method documentation

Consider adding a docstring to document the method's purpose, parameters, and usage examples. This would help users understand the differences between V1 and V2 versions of position streaming.

Example documentation:

async def stream_positions_v2(
    self,
    callback: Callable,
    on_end_callback: Optional[Callable] = None,
    on_status_callback: Optional[Callable] = None,
    subaccount_id: Optional[str] = None,
    market_id: Optional[str] = None,
    market_ids: Optional[List[str]] = None,
    subaccount_ids: Optional[List[str]] = None,
    account_address: Optional[str] = None,
) -> None:
    """
    Stream derivative positions using V2 API.

    Args:
        callback (Callable): Function to handle position updates
        on_end_callback (Optional[Callable], optional): Function called when stream ends
        on_status_callback (Optional[Callable], optional): Function to handle status updates
        subaccount_id (Optional[str], optional): Filter by specific subaccount
        market_id (Optional[str], optional): Filter by specific market
        market_ids (Optional[List[str]], optional): Filter by multiple markets
        subaccount_ids (Optional[List[str]], optional): Filter by multiple subaccounts
        account_address (Optional[str], optional): Filter by account address

    Note:
        This V2 version supports additional filtering by account_address compared to V1
    """
pyinjective/client/indexer/grpc_stream/indexer_grpc_spot_stream.py (2)

122-122: Add docstring and parameter validation for fee_recipient.

The new fee_recipient parameter needs documentation to explain its purpose and expected format. Consider adding input validation if specific address formats are required.

     def stream_trades(
         self,
         callback: Callable,
         on_end_callback: Optional[Callable] = None,
         on_status_callback: Optional[Callable] = None,
         market_ids: Optional[List[str]] = None,
         subaccount_ids: Optional[List[str]] = None,
         execution_side: Optional[str] = None,
         direction: Optional[str] = None,
         execution_types: Optional[List[str]] = None,
         trade_id: Optional[str] = None,
         account_address: Optional[str] = None,
         cid: Optional[str] = None,
         fee_recipient: Optional[str] = None,
         pagination: Optional[PaginationOption] = None,
     ):
+        """Stream trades with optional filtering.
+        
+        Args:
+            ...
+            fee_recipient: Optional[str] - Address of the fee recipient to filter trades by
+            ...
+        """

192-192: Add docstring and parameter validation for fee_recipient.

Similar to stream_trades, the fee_recipient parameter in stream_trades_v2 needs documentation to explain its purpose and expected format. Consider adding input validation if specific address formats are required.

     def stream_trades_v2(
         self,
         callback: Callable,
         on_end_callback: Optional[Callable] = None,
         on_status_callback: Optional[Callable] = None,
         market_ids: Optional[List[str]] = None,
         subaccount_ids: Optional[List[str]] = None,
         execution_side: Optional[str] = None,
         direction: Optional[str] = None,
         execution_types: Optional[List[str]] = None,
         trade_id: Optional[str] = None,
         account_address: Optional[str] = None,
         cid: Optional[str] = None,
         fee_recipient: Optional[str] = None,
         pagination: Optional[PaginationOption] = None,
     ):
+        """Stream trades with optional filtering using V2 API.
+        
+        Args:
+            ...
+            fee_recipient: Optional[str] - Address of the fee recipient to filter trades by
+            ...
+        """
examples/chain_client/permissions/1_MsgCreateNamespace.py (2)

51-57: Replace placeholder actor addresses with valid addresses.

The actor addresses "inj1specificactoraddress" and "inj1anotheractoraddress" appear to be placeholders. Ensure they are replaced with valid Injective addresses before deployment to prevent errors.


85-86: Consider specifying a contract hook if required.

The contract_hook parameter is currently an empty string. If a contract hook is needed for the namespace, provide the appropriate contract address; otherwise, confirm that leaving it empty is acceptable.

pyinjective/composer.py (2)

105-111: Simplify dictionary iteration by removing .keys().

When iterating over a dictionary, you can omit .keys() because iterating over the dictionary itself yields its keys. Simplify the code as follows:

109-                for permission_name in injective_permissions_pb.Action.keys()
109+                for permission_name in injective_permissions_pb.Action
🧰 Tools
🪛 Ruff (0.8.2)

109-109: Use key in dict instead of key in dict.keys()

Remove .keys()

(SIM118)


2048-2050: Consistent naming for burn_from_address parameter.

In the msg_burn method, the parameter burn_from_address is mapped to burnFromAddress in the message. Ensure that the field name matches the expected naming convention and protobuf specification.

Apply this diff to correct the parameter mapping if needed:

2050-    return token_factory_tx_pb.MsgBurn(sender=sender, amount=amount, burnFromAddress=burn_from_address)
2050+    return token_factory_tx_pb.MsgBurn(sender=sender, amount=amount, burn_from_address=burn_from_address)
examples/chain_client/permissions/query/1_NamespaceDenoms.py (1)

1-16: Add documentation to explain the example's purpose.

While the code structure is clean, adding a docstring and comments would help users understand:

  • The purpose of this example
  • What permissions namespace denoms represent
  • Expected output format

Add documentation like this:

 import asyncio
 
 from pyinjective.async_client import AsyncClient
 from pyinjective.core.network import Network
 
+"""
+Example demonstrating how to fetch all permission namespace denominations.
+
+This script shows how to:
+1. Connect to the testnet
+2. Query all permission namespace denominations
+3. Display the results
+"""
 
 async def main() -> None:
+    # Initialize network and client
     network = Network.testnet()
     client = AsyncClient(network)
 
+    # Fetch all permission namespace denominations
     namespaces = await client.fetch_permissions_namespace_denoms()
     print(namespaces)
examples/chain_client/permissions/query/5_ActorsByRole.py (1)

11-12: Use a realistic role name in the example.

The hardcoded value "roleName" should be replaced with a realistic role name to make the example more meaningful.

     denom = "inj"
-    role = "roleName"
+    role = "market_admin"  # Example: Use an actual role name from the system
examples/chain_client/permissions/query/10_Vouchers.py (1)

16-17: Update to modern asyncio pattern.

The current asyncio pattern is deprecated. Use asyncio.run() instead of manually creating and running the event loop.

 if __name__ == "__main__":
-    asyncio.get_event_loop().run_until_complete(main())
+    asyncio.run(main())
examples/chain_client/permissions/query/6_RoleManagers.py (1)

16-17: Update to modern asyncio pattern.

The current asyncio pattern is deprecated. Use asyncio.run() instead of manually creating and running the event loop.

 if __name__ == "__main__":
-    asyncio.get_event_loop().run_until_complete(main())
+    asyncio.run(main())
examples/chain_client/permissions/query/8_PolicyStatuses.py (1)

16-17: Update to modern asyncio pattern.

The current asyncio pattern is deprecated. Use asyncio.run() instead of manually creating and running the event loop.

 if __name__ == "__main__":
-    asyncio.get_event_loop().run_until_complete(main())
+    asyncio.run(main())
examples/chain_client/permissions/query/4_RolesByActor.py (3)

1-5: Add module docstring to explain the purpose and usage of this example.

As this is an example script, it should include documentation explaining its purpose, expected output, and how to use it.

Add a docstring at the module level:

+"""
+Example script demonstrating how to fetch roles associated with a specific actor in the Permissions module.
+
+This script connects to the testnet and retrieves all roles assigned to a given actor for a specific denomination.
+"""

11-13: Add comments explaining the input parameters.

The hardcoded values for denom and actor need explanation for users trying to understand and modify the example.

-    denom = "inj"
-    actor = "actor"
+    # The denomination to query roles for (e.g., "inj" for the native token)
+    denom = "inj"
+    # The address of the actor whose roles we want to fetch
+    actor = "actor"

7-15: Add error handling and improve the main function.

The function lacks error handling and proper documentation.

 async def main() -> None:
+    """
+    Fetch and display roles associated with a specific actor.
+    
+    This example demonstrates querying the permissions module to retrieve
+    all roles assigned to an actor for a given denomination.
+    """
     network = Network.testnet()
     client = AsyncClient(network)
 
     denom = "inj"
     actor = "actor"
-    roles = await client.fetch_permissions_roles_by_actor(denom=denom, actor=actor)
-    print(roles)
+    try:
+        roles = await client.fetch_permissions_roles_by_actor(denom=denom, actor=actor)
+        print(f"Roles for actor {actor} with denom {denom}:")
+        print(roles)
+    except Exception as e:
+        print(f"Error fetching roles: {e}")
examples/chain_client/permissions/query/7_RoleManager.py (1)

1-18: Maintain consistency with other example scripts.

This script follows the same pattern as other examples but needs similar improvements for consistency.

Apply similar improvements as the previous file:

  1. Add module docstring
  2. Add function docstring
  3. Add error handling
  4. Add parameter documentation
+"""
+Example script demonstrating how to fetch role manager information in the Permissions module.
+
+This script connects to the testnet and retrieves manager information for a specific denomination.
+"""
 import asyncio
 
 from pyinjective.async_client import AsyncClient
 from pyinjective.core.network import Network
 
 
 async def main() -> None:
+    """Fetch and display role manager information."""
     network = Network.testnet()
     client = AsyncClient(network)
 
+    # The denomination to query manager for
     denom = "inj"
+    # The address of the manager to query
     manager = "manager"
-    managers = await client.fetch_permissions_role_manager(denom=denom, manager=manager)
-    print(managers)
+    try:
+        managers = await client.fetch_permissions_role_manager(denom=denom, manager=manager)
+        print(f"Manager information for {manager} with denom {denom}:")
+        print(managers)
+    except Exception as e:
+        print(f"Error fetching manager information: {e}")
examples/chain_client/permissions/query/9_PolicyManagerCapabilities.py (1)

Line range hint 1-18: Maintain consistency with other example scripts.

This script follows the same pattern but needs similar improvements for consistency.

Apply similar improvements:

+"""
+Example script demonstrating how to fetch policy manager capabilities in the Permissions module.
+
+This script connects to the testnet and retrieves policy manager capabilities for a specific denomination.
+"""
 import asyncio
 
 from pyinjective.async_client import AsyncClient
 from pyinjective.core.network import Network
 
 
 async def main() -> None:
+    """Fetch and display policy manager capabilities."""
     network = Network.testnet()
     client = AsyncClient(network)
 
+    # The denomination to query capabilities for
     denom = "inj"
-    policy_manager_capabilities = await client.fetch_permissions_policy_manager_capabilities(denom=denom)
-    print(policy_manager_capabilities)
+    try:
+        capabilities = await client.fetch_permissions_policy_manager_capabilities(denom=denom)
+        print(f"Policy manager capabilities for denom {denom}:")
+        print(capabilities)
+    except Exception as e:
+        print(f"Error fetching capabilities: {e}")
examples/chain_client/exchange/query/57_L3SpotOrderBook.py (2)

14-17: Add documentation for the market ID parameter.

The market ID is a crucial parameter but lacks explanation of its format and how to obtain it.

+    # Market ID for the spot market to fetch the orderbook for
+    # Format: 32-byte hex string
+    # You can get the market ID from the Markets page in the Hub
     orderbook = await client.fetch_l3_spot_orderbook(
         market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
     )

7-18: Add error handling and improve consistency with other examples.

The script should handle potential errors and maintain consistency with other example scripts.

 async def main() -> None:
+    """
+    Fetch and display the L3 spot orderbook for a specific market.
+    
+    This example demonstrates how to retrieve detailed orderbook information
+    including all individual orders at each price level.
+    """
     # select network: local, testnet, mainnet
     network = Network.testnet()
 
     # initialize grpc client
     client = AsyncClient(network)
 
-    orderbook = await client.fetch_l3_spot_orderbook(
-        market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
-    )
-    print(orderbook)
+    try:
+        orderbook = await client.fetch_l3_spot_orderbook(
+            market_id="0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe",
+        )
+        print("L3 Spot Orderbook:")
+        print(orderbook)
+    except Exception as e:
+        print(f"Error fetching orderbook: {e}")
examples/exchange_client/auctions_rpc/4_InjBurntEndpoint.py (1)

7-22: Add docstring and ensure client cleanup.

The error handling is good, but the example needs:

  1. A docstring explaining the purpose and expected output
  2. Proper cleanup of client resources
 async def main():
+    """
+    Example demonstrating how to fetch the total amount of INJ tokens that have been burnt.
+    
+    Returns the total amount of INJ tokens that have been removed from circulation through burning.
+    """
     # Select network: testnet, mainnet, or local
     network = Network.testnet()
 
     # Initialize AsyncClient
     client = AsyncClient(network)
 
     try:
         # Fetch INJ burnt amount
         inj_burnt_response = await client.fetch_inj_burnt()
         print("INJ Burnt Endpoint Response:")
         print(inj_burnt_response)
 
     except Exception as e:
         print(f"Error fetching INJ burnt amount: {e}")
+    finally:
+        await client.close()
examples/chain_client/exchange/query/59_MarketBalances.py (1)

17-25: Ensure client cleanup.

Add cleanup of client resources in the finally block to prevent resource leaks.

     try:
         # Fetch market balances
         market_balances = await client.fetch_market_balances()
         print("Market Balances:")
         print(market_balances)
 
     except Exception as ex:
         print(f"Error occurred: {ex}")
+    finally:
+        await client.close()
examples/chain_client/exchange/query/61_DenomMinNotionals.py (3)

18-19: Fix incorrect comment.

The comment doesn't match the actual operation being performed.

-        # Fetch market balance
+        # Fetch minimum notionals for all denominations
         min_notionals = await client.fetch_denom_min_notionals()

17-25: Ensure client cleanup.

Add cleanup of client resources in the finally block to prevent resource leaks.

     try:
         # Fetch minimum notionals for all denominations
         min_notionals = await client.fetch_denom_min_notionals()
         print("Min Notionals:")
         print(min_notionals)
 
     except Exception as ex:
         print(f"Error occurred: {ex}")
+    finally:
+        await client.close()

1-1: Consider standardizing example patterns.

All example scripts would benefit from following a consistent pattern for:

  1. Documentation (docstrings with purpose and expected output)
  2. Error handling (try-except-finally blocks)
  3. Resource cleanup (client.close() in finally blocks)
  4. Network selection comments

This would make the examples more maintainable and easier to understand.

examples/chain_client/exchange/query/60_DenomMinNotional.py (2)

8-10: Enhance docstring with return value format and parameters.

The docstring should include details about the expected return value format and parameter requirements to help users understand the API better.

 """
 Demonstrate fetching denom min notional using AsyncClient.
+
+Args:
+    None
+
+Returns:
+    Prints the minimum notional value for the specified denomination.
+    Format: {amount: str, denom: str}
 """

19-19: Consider making the denom value configurable.

The hardcoded denom value might not be useful for all users. Consider making it configurable through environment variables or command-line arguments.

-        denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"
+        denom = os.getenv("INJECTIVE_DENOM", "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test")
examples/chain_client/exchange/query/58_MarketBalance.py (2)

8-10: Enhance docstring with return value format and parameters.

The docstring should include details about the expected return value format and parameter requirements.

 """
 Demonstrate fetching market balance using AsyncClient.
+
+Args:
+    None
+
+Returns:
+    Prints the market balance information.
+    Format: {total_deposits: str, total_withdrawals: str}
 """

19-19: Add documentation for the market ID format.

The hardcoded market ID needs documentation about its format and how users can obtain valid market IDs for their use case.

-        # Example market ID (replace with an actual market ID from the network)
+        # Example market ID in hex format (32 bytes)
+        # Users can obtain market IDs by:
+        # 1. Using the Markets API
+        # 2. Checking the Injective Explorer
+        # 3. Using the spot_markets or derivative_markets queries
examples/chain_client/tokenfactory/1_CreateDenom.py (1)

35-35: Document the new allow_admin_burn parameter.

The new parameter needs documentation to explain its purpose and security implications.

Add a comment above the message composition:

+    # Set allow_admin_burn to False to prevent the admin from burning tokens
+    # This is a security measure to protect token holders
     message = composer.msg_create_denom(
tests/client/indexer/configurable_auction_query_servicer.py (2)

27-28: Add type hints and docstring for the new method.

The new InjBurntEndpoint method should include proper type hints and documentation.

-    async def InjBurntEndpoint(self, request: exchange_auction_pb.InjBurntEndpointRequest, context=None, metadata=None):
+    async def InjBurntEndpoint(
+        self,
+        request: exchange_auction_pb.InjBurntEndpointRequest,
+        context=None,
+        metadata=None
+    ) -> exchange_auction_pb.InjBurntEndpointResponse:
+        """Handle InjBurntEndpoint requests in tests.
+
+        Args:
+            request: The InjBurntEndpoint request message
+            context: Optional gRPC context
+            metadata: Optional gRPC metadata
+
+        Returns:
+            The next pre-configured InjBurntEndpoint response
+        """
         return self.inj_burnt_responses.pop()

15-15: Add type hint for the new response queue.

The new inj_burnt_responses deque should include a type hint.

-        self.inj_burnt_responses = deque()  # Add this line to store InjBurntEndpoint responses
+        self.inj_burnt_responses: deque[exchange_auction_pb.InjBurntEndpointResponse] = deque()
examples/chain_client/tokenfactory/3_MsgBurn.py (1)

34-34: Consider using environment variables for addresses

The hardcoded address should be moved to an environment variable for better maintainability and to demonstrate best practices in the example.

-        burn_from_address="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
+        burn_from_address=os.getenv("BURN_FROM_ADDRESS"),
examples/chain_client/tokenfactory/2_MsgMint.py (1)

34-34: Consider using environment variables for addresses

Similar to the MsgBurn example, the hardcoded receiver address should be moved to an environment variable for better maintainability and consistency across examples.

-        receiver="inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r",
+        receiver=os.getenv("RECEIVER_ADDRESS"),
examples/exchange_client/derivative_exchange_rpc/9_StreamPositions.py (1)

Line range hint 30-36: Consider documenting v2 API changes and using environment variables

  1. The upgrade to v2 API might introduce breaking changes. Consider adding a comment explaining the differences between v1 and v2.
  2. The hardcoded market_ids and subaccount_ids should be moved to environment variables.
+    # V2 API provides enhanced position tracking with X, Y, Z improvements
     task = asyncio.get_event_loop().create_task(
         client.listen_derivative_positions_v2_updates(
             callback=positions_event_processor,
             on_end_callback=stream_closed_processor,
             on_status_callback=stream_error_processor,
-            market_ids=["0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"],
-            subaccount_ids=["0xea98e3aa091a6676194df40ac089e40ab4604bf9000000000000000000000000"],
+            market_ids=[os.getenv("MARKET_ID")],
+            subaccount_ids=[os.getenv("SUBACCOUNT_ID")],
         )
     )
pyinjective/client/indexer/grpc/indexer_grpc_auction_api.py (1)

30-34: Add docstring and consider more specific return type

The new method should include a docstring explaining its purpose and return type could be more specific than Dict[str, Any].

     async def fetch_inj_burnt(self) -> Dict[str, Any]:
+        """
+        Fetches the total amount of INJ tokens that have been burnt.
+        
+        Returns:
+            Dict containing the total amount of INJ tokens burnt
+        """
         request = exchange_auction_pb.InjBurntEndpointRequest()
         response = await self._execute_call(call=self._stub.InjBurntEndpoint, request=request)
 
         return response
examples/chain_client/exchange/3_MsgInstantSpotMarketLaunch.py (1)

46-47: Add comments explaining the decimal parameters.

The hardcoded decimal values (18 for base and 6 for quote) should be documented to explain their significance in market creation. Consider adding comments or making these values configurable to make the example more educational.

+    # Set decimal precision for the trading pair
+    # INJ uses 18 decimals (common for ERC20 tokens)
+    # USDC uses 6 decimals (standard for stablecoins)
     base_decimals=18,
     quote_decimals=6,
pyinjective/ofac.py (1)

8-9: Consider adding security enhancements for OFAC list retrieval.

The OFAC list is security-critical. Consider implementing:

  1. Version checking to ensure list freshness
  2. Hash verification of downloaded content
  3. Fallback URL in case the primary source is unavailable
examples/chain_client/permissions/2_MsgUpdateNamespace.py (1)

59-63: Review policy manager capabilities.

The policy manager address "inj1policymanageraddress" appears to be a placeholder. Additionally, consider documenting the implications of the capability settings.

Add comments explaining:

  • The impact of can_disable=True
  • The implications of can_seal=False
CHANGELOG.md (1)

5-8: Consider adding more details to the changelog entry.

The changelog entry could be more descriptive about the specific changes and improvements made to the Permissions module. Consider including:

  • What types of queries and messages were added
  • Any breaking changes or migrations required
  • Impact on existing implementations
🧰 Tools
🪛 LanguageTool

[duplication] ~6-~6: Possible typo: you repeated a word.
Context: ...this file. ## [1.9.0] - 9999-99-99 ### Added - Added support for all new queries and message...

(ENGLISH_WORD_REPEAT_RULE)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cd67089 and 2c4239d.

📒 Files selected for processing (110)
  • CHANGELOG.md (1 hunks)
  • Makefile (1 hunks)
  • buf.gen.yaml (1 hunks)
  • examples/chain_client/exchange/3_MsgInstantSpotMarketLaunch.py (1 hunks)
  • examples/chain_client/exchange/query/56_L3DerivativeOrderBook.py (1 hunks)
  • examples/chain_client/exchange/query/57_L3SpotOrderBook.py (1 hunks)
  • examples/chain_client/exchange/query/58_MarketBalance.py (1 hunks)
  • examples/chain_client/exchange/query/59_MarketBalances.py (1 hunks)
  • examples/chain_client/exchange/query/60_DenomMinNotional.py (1 hunks)
  • examples/chain_client/exchange/query/61_DenomMinNotionals.py (1 hunks)
  • examples/chain_client/permissions/1_MsgCreateNamespace.py (1 hunks)
  • examples/chain_client/permissions/2_MsgDeleteNamespace.py (0 hunks)
  • examples/chain_client/permissions/2_MsgUpdateNamespace.py (1 hunks)
  • examples/chain_client/permissions/3_MsgUpdateActorRoles.py (1 hunks)
  • examples/chain_client/permissions/3_MsgUpdateNamespace.py (0 hunks)
  • examples/chain_client/permissions/5_MsgRevokeNamespaceRoles.py (0 hunks)
  • examples/chain_client/permissions/query/10_Vouchers.py (1 hunks)
  • examples/chain_client/permissions/query/11_Voucher.py (1 hunks)
  • examples/chain_client/permissions/query/12_PermissionsModuleState.py (1 hunks)
  • examples/chain_client/permissions/query/1_NamespaceDenoms.py (1 hunks)
  • examples/chain_client/permissions/query/2_Namespaces.py (1 hunks)
  • examples/chain_client/permissions/query/3_Namespace.py (1 hunks)
  • examples/chain_client/permissions/query/4_RolesByActor.py (1 hunks)
  • examples/chain_client/permissions/query/5_ActorsByRole.py (1 hunks)
  • examples/chain_client/permissions/query/6_RoleManagers.py (1 hunks)
  • examples/chain_client/permissions/query/7_RoleManager.py (1 hunks)
  • examples/chain_client/permissions/query/8_PolicyStatuses.py (1 hunks)
  • examples/chain_client/permissions/query/9_PolicyManagerCapabilities.py (1 hunks)
  • examples/chain_client/tokenfactory/1_CreateDenom.py (1 hunks)
  • examples/chain_client/tokenfactory/2_MsgMint.py (1 hunks)
  • examples/chain_client/tokenfactory/3_MsgBurn.py (1 hunks)
  • examples/exchange_client/auctions_rpc/4_InjBurntEndpoint.py (1 hunks)
  • examples/exchange_client/derivative_exchange_rpc/9_StreamPositions.py (1 hunks)
  • pyinjective/async_client.py (13 hunks)
  • pyinjective/client/chain/grpc/chain_grpc_exchange_api.py (1 hunks)
  • pyinjective/client/chain/grpc/chain_grpc_permissions_api.py (1 hunks)
  • pyinjective/client/indexer/grpc/indexer_grpc_auction_api.py (1 hunks)
  • pyinjective/client/indexer/grpc/indexer_grpc_derivative_api.py (4 hunks)
  • pyinjective/client/indexer/grpc/indexer_grpc_spot_api.py (4 hunks)
  • pyinjective/client/indexer/grpc_stream/indexer_grpc_derivative_stream.py (5 hunks)
  • pyinjective/client/indexer/grpc_stream/indexer_grpc_spot_stream.py (4 hunks)
  • pyinjective/composer.py (6 hunks)
  • pyinjective/ofac.json (1 hunks)
  • pyinjective/ofac.py (1 hunks)
  • pyinjective/proto/cosmwasm/wasm/v1/ibc_pb2.py (2 hunks)
  • pyinjective/proto/cosmwasm/wasm/v1/query_pb2.py (2 hunks)
  • pyinjective/proto/exchange/event_provider_api_pb2.py (2 hunks)
  • pyinjective/proto/exchange/event_provider_api_pb2_grpc.py (4 hunks)
  • pyinjective/proto/exchange/health_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_archiver_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_archiver_rpc_pb2_grpc.py (4 hunks)
  • pyinjective/proto/exchange/injective_auction_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_auction_rpc_pb2_grpc.py (4 hunks)
  • pyinjective/proto/exchange/injective_campaign_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_chart_rpc_pb2.py (1 hunks)
  • pyinjective/proto/exchange/injective_chart_rpc_pb2_grpc.py (1 hunks)
  • pyinjective/proto/exchange/injective_derivative_exchange_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_derivative_exchange_rpc_pb2_grpc.py (4 hunks)
  • pyinjective/proto/exchange/injective_exchange_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_exchange_rpc_pb2_grpc.py (4 hunks)
  • pyinjective/proto/exchange/injective_explorer_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_explorer_rpc_pb2_grpc.py (4 hunks)
  • pyinjective/proto/exchange/injective_spot_exchange_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_trading_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_trading_rpc_pb2_grpc.py (4 hunks)
  • pyinjective/proto/google/api/client_pb2.py (2 hunks)
  • pyinjective/proto/google/api/httpbody_pb2.py (1 hunks)
  • pyinjective/proto/google/longrunning/operations_pb2.py (1 hunks)
  • pyinjective/proto/google/longrunning/operations_pb2_grpc.py (4 hunks)
  • pyinjective/proto/google/rpc/error_details_pb2.py (2 hunks)
  • pyinjective/proto/injective/auction/v1beta1/auction_pb2.py (3 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/events_pb2.py (2 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/exchange_pb2.py (2 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/genesis_pb2.py (2 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/proposal_pb2.py (2 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/query_pb2.py (4 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/query_pb2_grpc.py (6 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/tx_pb2.py (2 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/tx_pb2_grpc.py (4 hunks)
  • pyinjective/proto/injective/peggy/v1/events_pb2.py (3 hunks)
  • pyinjective/proto/injective/peggy/v1/params_pb2.py (2 hunks)
  • pyinjective/proto/injective/permissions/v1beta1/genesis_pb2.py (2 hunks)
  • pyinjective/proto/injective/permissions/v1beta1/permissions_pb2.py (1 hunks)
  • pyinjective/proto/injective/permissions/v1beta1/query_pb2.py (2 hunks)
  • pyinjective/proto/injective/permissions/v1beta1/query_pb2_grpc.py (13 hunks)
  • pyinjective/proto/injective/permissions/v1beta1/tx_pb2.py (3 hunks)
  • pyinjective/proto/injective/permissions/v1beta1/tx_pb2_grpc.py (5 hunks)
  • pyinjective/proto/injective/stream/v1beta1/query_pb2.py (1 hunks)
  • pyinjective/proto/injective/tokenfactory/v1beta1/authorityMetadata_pb2.py (2 hunks)
  • pyinjective/proto/injective/tokenfactory/v1beta1/events_pb2.py (1 hunks)
  • pyinjective/proto/injective/tokenfactory/v1beta1/tx_pb2.py (5 hunks)
  • pyinjective/proto/injective/tokenfactory/v1beta1/tx_pb2_grpc.py (3 hunks)
  • pyinjective/proto/injective/wasmx/v1/authz_pb2.py (1 hunks)
  • pyinjective/proto/injective/wasmx/v1/authz_pb2_grpc.py (1 hunks)
  • pyproject.toml (1 hunks)
  • tests/client/chain/grpc/configurable_exchange_query_servicer.py (2 hunks)
  • tests/client/chain/grpc/configurable_permissions_query_servicer.py (1 hunks)
  • tests/client/chain/grpc/test_chain_grpc_auction_api.py (5 hunks)
  • tests/client/chain/grpc/test_chain_grpc_exchange_api.py (15 hunks)
  • tests/client/chain/grpc/test_chain_grpc_permissions_api.py (3 hunks)
  • tests/client/chain/grpc/test_chain_grpc_token_factory_api.py (4 hunks)
  • tests/client/chain/stream_grpc/test_chain_grpc_chain_stream.py (6 hunks)
  • tests/client/indexer/configurable_auction_query_servicer.py (2 hunks)
  • tests/client/indexer/configurable_derivative_query_servicer.py (2 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_auction_api.py (1 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_derivative_api.py (2 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_explorer_api.py (6 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_spot_api.py (2 hunks)
  • tests/client/indexer/stream_grpc/test_indexer_grpc_derivative_stream.py (6 hunks)
  • tests/client/indexer/stream_grpc/test_indexer_grpc_spot_stream.py (6 hunks)
💤 Files with no reviewable changes (3)
  • examples/chain_client/permissions/5_MsgRevokeNamespaceRoles.py
  • examples/chain_client/permissions/3_MsgUpdateNamespace.py
  • examples/chain_client/permissions/2_MsgDeleteNamespace.py
✅ Files skipped from review due to trivial changes (6)
  • pyproject.toml
  • pyinjective/proto/google/longrunning/operations_pb2_grpc.py
  • pyinjective/proto/google/api/httpbody_pb2.py
  • pyinjective/proto/injective/tokenfactory/v1beta1/tx_pb2_grpc.py
  • pyinjective/proto/exchange/injective_chart_rpc_pb2.py
  • pyinjective/proto/injective/stream/v1beta1/query_pb2.py
👮 Files not reviewed due to content moderation or server errors (4)
  • pyinjective/proto/exchange/injective_archiver_rpc_pb2_grpc.py
  • pyinjective/client/chain/grpc/chain_grpc_exchange_api.py
  • tests/client/indexer/grpc/test_indexer_grpc_spot_api.py
  • pyinjective/proto/exchange/injective_explorer_rpc_pb2_grpc.py
🧰 Additional context used
🪛 LanguageTool
CHANGELOG.md

[duplication] ~6-~6: Possible typo: you repeated a word.
Context: ...this file. ## [1.9.0] - 9999-99-99 ### Added - Added support for all new queries and message...

(ENGLISH_WORD_REPEAT_RULE)

🪛 Gitleaks (8.21.2)
tests/client/indexer/grpc/test_indexer_grpc_explorer_api.py

380-380: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


664-664: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Ruff (0.8.2)
tests/client/indexer/stream_grpc/test_indexer_grpc_derivative_stream.py

818-818: Do not assign a lambda expression, use a def

Rewrite callback as a def

(E731)


819-819: Do not assign a lambda expression, use a def

Rewrite error_callback as a def

(E731)


820-820: Do not assign a lambda expression, use a def

Rewrite end_callback as a def

(E731)

pyinjective/proto/cosmwasm/wasm/v1/query_pb2.py

19-19: pyinjective.proto.cosmos.query.v1.query_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos.query.v1.query_pb2

(F401)


20-20: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)


21-21: pyinjective.proto.cosmos_proto.cosmos_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos_proto.cosmos_pb2

(F401)

pyinjective/proto/injective/permissions/v1beta1/permissions_pb2.py

16-16: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)

pyinjective/proto/injective/exchange/v1beta1/tx_pb2.py

21-21: pyinjective.proto.injective.exchange.v1beta1.proposal_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.exchange.v1beta1.proposal_pb2

(F401)


22-22: pyinjective.proto.injective.oracle.v1beta1.oracle_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.oracle.v1beta1.oracle_pb2

(F401)


23-23: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)

pyinjective/composer.py

109-109: Use key in dict instead of key in dict.keys()

Remove .keys()

(SIM118)

pyinjective/proto/google/longrunning/operations_pb2.py

18-18: google.protobuf.descriptor_pb2 imported but unused

Remove unused import: google.protobuf.descriptor_pb2

(F401)


19-19: google.protobuf.duration_pb2 imported but unused

Remove unused import: google.protobuf.duration_pb2

(F401)


20-20: google.protobuf.empty_pb2 imported but unused

Remove unused import: google.protobuf.empty_pb2

(F401)


21-21: google.rpc.status_pb2 imported but unused

Remove unused import: google.rpc.status_pb2

(F401)

pyinjective/proto/injective/wasmx/v1/authz_pb2.py

15-15: pyinjective.proto.cosmwasm.wasm.v1.authz_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmwasm.wasm.v1.authz_pb2

(F401)


16-16: pyinjective.proto.cosmos_proto.cosmos_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos_proto.cosmos_pb2

(F401)


17-17: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)


18-18: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)

pyinjective/proto/injective/wasmx/v1/authz_pb2_grpc.py

3-3: grpc imported but unused

Remove unused import: grpc

(F401)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: run-tests (3.11, windows-latest)
  • GitHub Check: run-tests (3.10, windows-latest)
  • GitHub Check: run-tests (3.9, windows-latest)
🔇 Additional comments (170)
tests/client/indexer/stream_grpc/test_indexer_grpc_spot_stream.py (2)

Line range hint 427-440: Improved task management and fee recipient support in stream_trades.

The changes properly manage the async task lifecycle and add fee recipient support, which aligns with the Permissions module updates.

Good improvements:

  1. Storing the task in a variable allows proper cleanup
  2. Adding task.cancel() prevents resource leaks
  3. The fee_recipient parameter is correctly passed from the trade object

Also applies to: 474-474

🧰 Tools
🪛 Ruff (0.8.2)

424-424: Do not assign a lambda expression, use a def

Rewrite error_callback as a def

(E731)


425-425: Do not assign a lambda expression, use a def

Rewrite end_callback as a def

(E731)


Line range hint 609-622: Consistent implementation in stream_trades_v2.

The changes mirror those in stream_trades, maintaining consistency across both versions.

The parallel implementation ensures:

  1. Both versions handle task cleanup properly
  2. Both support the fee recipient parameter
  3. Both maintain the same parameter ordering

Also applies to: 656-656

🧰 Tools
🪛 Ruff (0.8.2)

606-606: Do not assign a lambda expression, use a def

Rewrite error_callback as a def

(E731)


607-607: Do not assign a lambda expression, use a def

Rewrite end_callback as a def

(E731)

tests/client/indexer/stream_grpc/test_indexer_grpc_derivative_stream.py (2)

Line range hint 536-549: LGTM! Improved task management.

The changes improve resource cleanup by explicitly storing and canceling the task.

Also applies to: 585-585

🧰 Tools
🪛 Ruff (0.8.2)

533-533: Do not assign a lambda expression, use a def

Rewrite error_callback as a def

(E731)


534-534: Do not assign a lambda expression, use a def

Rewrite end_callback as a def

(E731)


Line range hint 732-745: LGTM! Consistent task management.

The task management improvements are consistently applied to the V2 method as well.

Also applies to: 781-784

🧰 Tools
🪛 Ruff (0.8.2)

729-729: Do not assign a lambda expression, use a def

Rewrite error_callback as a def

(E731)


730-730: Do not assign a lambda expression, use a def

Rewrite end_callback as a def

(E731)

pyinjective/proto/injective/exchange/v1beta1/proposal_pb2.py (3)

177-178: LGTM: New serialization options for DenomMinNotionalProposal.

The serialization options for the new DenomMinNotionalProposal message type are correctly defined.


179-224: LGTM: Updated serialization positions.

The serialization start and end positions for all message types have been correctly updated to accommodate the new proposal type.


Line range hint 1-224: Important: This is a generated file.

This file is generated by the protocol buffer compiler and should not be manually edited. Any changes should be made to the corresponding .proto files instead.

Run this script to verify the file was generated by protoc:

✅ Verification successful

Confirmed: This is a protobuf-generated file

The file contains the standard protobuf compiler generation markers, confirming it is indeed a generated file that should not be manually edited. Any changes should be made to the source .proto files instead.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify this is a generated protobuf file
# Test: Look for protoc generation markers. Expect: Both markers should be present.

rg "Generated by the protocol buffer compiler.  DO NOT EDIT!" pyinjective/proto/injective/exchange/v1beta1/proposal_pb2.py
rg "@@protoc_insertion_point" pyinjective/proto/injective/exchange/v1beta1/proposal_pb2.py

Length of output: 351

tests/client/chain/grpc/test_chain_grpc_auction_api.py (2)

56-59: Great use of structured types!

The change from string representation to coin_pb.Coin for the bid amount improves type safety and clarity. This structured approach better represents the domain model.


Line range hint 1-174: Comprehensive test coverage!

The test suite effectively covers:

  • Module parameters with the new inj_basket_max_cap field
  • Module state with both present and absent highest bid cases
  • Current basket functionality
  • Edge cases and type conversions

The tests follow good practices and provide thorough validation of the auction module's behavior.

tests/client/chain/stream_grpc/test_chain_grpc_chain_stream.py (4)

57-57: LGTM! Improved order hash representation.

The change from byte string to hexadecimal string format improves readability and aligns with blockchain conventions.


103-103: LGTM! Consistent order hash format.

The change maintains consistency with the hexadecimal string format used for other order hashes.


129-129: LGTM! Standardized order hash format.

The change standardizes the order hash representation across different order types.


252-252: Verify order hash consistency in expected update structure.

The expected update structure has been correctly updated to match the new hexadecimal string format. However, there's an inconsistency in the test: while most order hashes are now in hexadecimal format, the spot_limit_order and derivative_limit_order still use byte strings that are base64 encoded in the expected update.

Let's verify if this inconsistency is intentional by checking other test files:

Also applies to: 281-281, 304-304

pyinjective/client/indexer/grpc_stream/indexer_grpc_derivative_stream.py (3)

144-144: LGTM: Fee recipient parameter correctly added to stream_trades

The addition of the optional fee_recipient parameter and its propagation to the request object is implemented correctly.

Also applies to: 160-160


214-214: LGTM: Fee recipient parameter correctly added to stream_trades_v2

The addition of the optional fee_recipient parameter and its propagation to the V2 request object is implemented correctly and maintains consistency with the V1 implementation.

Also applies to: 231-231


242-267: LGTM: New stream_positions_v2 method implementation

The implementation follows the established patterns for streaming methods and correctly handles all filtering parameters.

pyinjective/client/indexer/grpc_stream/indexer_grpc_spot_stream.py (3)

139-139: LGTM!

The fee_recipient parameter is correctly included in the request construction.


209-209: LGTM!

The fee_recipient parameter is correctly included in the V2 request construction.


Line range hint 122-209: Verify compatibility with final proto definitions.

As mentioned in the PR objectives, these changes should not be merged until the final version of the proto definitions is available. Please ensure that the fee_recipient field matches the final proto definitions for both StreamTradesRequest and StreamTradesV2Request.

examples/chain_client/permissions/1_MsgCreateNamespace.py (6)

31-34: Confirm the use of role ID 0 for "EVERYONE".

Using role_id=0 for the "EVERYONE" role may conflict with default or reserved role IDs in the system. Verify that 0 is an acceptable value and does not cause unintended behavior.


35-40: Ensure all necessary permissions are assigned to the "admin" role.

The "admin" role currently has MODIFY_ROLE_PERMISSIONS and MODIFY_ADDRESS_ROLES permissions. Confirm that these cover all required administrative actions, and consider whether additional permissions like MODIFY_POLICY_STATUSES or MODIFY_POLICY_MANAGER_CAPABILITIES are needed.


41-48: Review permissions assigned to the "user" role for completeness.

The "user" role includes permissions for MINT, RECEIVE, BURN, and SEND. Verify that these permissions align with the intended capabilities of a "user" and consider if any additional permissions are necessary.


59-62: Verify the role manager's address and assigned roles.

Confirm that "inj1manageraddress" is the correct address for the role manager and that assigning the "admin" role aligns with your permission hierarchy and security requirements.


64-73: Check policy statuses for correctness and compliance.

The policies for actions MINT and BURN have is_disabled=False and is_sealed=False. Ensure these settings reflect the desired policy state and comply with any regulatory or business rules.


75-79: Confirm policy manager capabilities are appropriate.

The policy manager "inj1policymanageraddress" is granted the ability to modify contract hooks with can_disable=True and can_seal=False. Verify that these capabilities are suitable and that the manager has the necessary authority.

tests/client/chain/grpc/configurable_permissions_query_servicer.py (6)

37-39: Ensure the Namespace method uses the correct request type.

Verify that the Namespace method correctly uses QueryNamespaceRequest and that it handles the request and response properly.


40-42: Confirm implementation of RolesByActor method.

The RolesByActor method appears to be properly implemented. Ensure that it correctly processes the request and returns the appropriate response.


43-44: Validate the ActorsByRole method functionality.

Check that the ActorsByRole method correctly handles QueryActorsByRoleRequest and returns the expected data.


52-56: Verify the PolicyStatuses method is correctly implemented.

Ensure that the PolicyStatuses method properly handles the request and that the responses are correctly managed from self.policy_statuses_responses.


57-61: Check the PolicyManagerCapabilities method for accuracy.

Confirm that the method correctly processes QueryPolicyManagerCapabilitiesRequest and returns the correct responses.


62-64: Review the Vouchers method implementation.

Ensure that the Vouchers method handles requests and responses accurately, and that it interacts with self.vouchers_responses as intended.

pyinjective/client/chain/grpc/chain_grpc_permissions_api.py (12)

24-26: Method fetch_namespace_denoms implemented correctly.

The method correctly creates a QueryNamespaceDenomsRequest and invokes self._stub.NamespaceDenoms.


30-32: Confirm the request type in fetch_namespaces method.

Ensure that QueryNamespacesRequest is the correct request type for fetching namespaces and that it aligns with the updated proto definitions.


36-38: Method fetch_namespace correctly retrieves namespace details.

The method uses QueryNamespaceRequest with the provided denom and calls self._stub.Namespace as expected.


42-44: Validate parameters in fetch_roles_by_actor method.

Confirm that the method correctly constructs the request with denom and actor, and that it accurately retrieves roles associated with the actor.


48-51: Method fetch_actors_by_role correctly fetches actors.

The method properly creates a QueryActorsByRoleRequest with denom and role, and invokes the appropriate stub.


54-57: Verify fetch_role_managers method implementation.

Ensure that fetch_role_managers correctly requests role managers for the given denom and processes the response accurately.


60-63: Check fetch_role_manager method for correctness.

Confirm that the method handles the request with denom and manager, and that it retrieves the specific role manager information as intended.


66-69: Ensure fetch_policy_statuses method functions as expected.

Verify that the method correctly requests policy statuses for the specified denom and processes the response properly.


72-75: Review fetch_policy_manager_capabilities method.

Confirm that the method accurately retrieves policy manager capabilities for the given denom using the correct request and stub.


78-81: Method fetch_vouchers implemented appropriately.

Ensure that the method correctly constructs the request with denom and fetches vouchers as expected.


84-87: Verify fetch_voucher method retrieves correct voucher data.

Check that the method handles the request with denom and address, and that it retrieves the specific voucher information accurately.


90-92: Method fetch_permissions_module_state implemented correctly.

The method creates a QueryModuleStateRequest and calls self._stub.PermissionsModuleState, correctly retrieving the module state.

pyinjective/proto/exchange/injective_exchange_rpc_pb2.py (1)

37-60: LGTM: Protocol buffer updates are correctly integrated

The changes to the serialized descriptors reflect the addition of new message types and updates to existing ones. The new messages PrepareEip712Request and PrepareEip712Response are properly added, and the serialized start and end positions are correctly updated.

pyinjective/proto/injective/permissions/v1beta1/tx_pb2.py (2)

67-82: LGTM: Message definitions are correctly updated

The updated message definitions and their serialized descriptors reflect the intended changes to the permissions module. The new message MsgUpdateActorRoles and the updates to MsgUpdateNamespace are properly implemented.


49-52: Ensure all references to removed messages are updated

The messages MsgDeleteNamespace, MsgUpdateNamespaceRoles, and MsgRevokeNamespaceRoles have been removed, and a new message MsgUpdateActorRoles has been added. Please verify that all references to the removed messages are updated throughout the codebase to prevent any unresolved references or import errors.

Run the following script to check for any remaining references to the removed messages:

✅ Verification successful

No references to removed messages found

The codebase has been properly updated. The removed messages (MsgDeleteNamespace, MsgUpdateNamespaceRoles, and MsgRevokeNamespaceRoles) are not referenced anywhere, while the new MsgUpdateActorRoles message is correctly integrated. The remaining namespace-related messages (MsgCreateNamespace and MsgUpdateNamespace) are different messages that should remain in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for references to removed messages in the codebase.

# Search for any occurrences of the removed message names.
rg 'MsgDeleteNamespace|MsgUpdateNamespaceRoles|MsgRevokeNamespaceRoles'

Length of output: 73


Script:

#!/bin/bash
# Search for namespace-related messages in proto and Python files
echo "=== Searching in proto files ==="
fd -e proto -x rg -i "namespace.*message|message.*namespace" {}

echo -e "\n=== Searching in Python files ==="
fd -e py -x rg -i "namespace.*msg|msg.*namespace" {}

echo -e "\n=== Checking specific proto message imports ==="
rg -g "*.{py,proto}" "import.*namespace|namespace.*import"

Length of output: 8445

pyinjective/proto/exchange/injective_archiver_rpc_pb2.py (1)

43-76: LGTM! New message types are correctly added

The new message types and service methods for leaderboard, denomination holders, and historical trades are properly integrated into the generated code, matching the updated protocol buffer definitions.

pyinjective/proto/injective/permissions/v1beta1/query_pb2.py (3)

34-35: LGTM! Voucher field options are properly set

The serialized options for the voucher field in _QUERYVOUCHERRESPONSE are correctly updated to include external type annotations, ensuring compatibility with Cosmos SDK Coin types.


38-61: LGTM! New methods are correctly registered with appropriate options

The methods in the Query service (NamespaceDenoms, Namespaces, Namespace, RolesByActor, ActorsByRole, RoleManagers, RoleManager, PolicyStatuses, PolicyManagerCapabilities, Vouchers, Voucher, PermissionsModuleState) are updated with the correct serialized options, ensuring proper API endpoint mappings and accessibility.


66-115: LGTM! Serialized positions are correctly updated for new messages

The serialized start and end positions for the new message types are properly assigned. This ensures that all message definitions are accurately reflected in the generated code, maintaining the integrity of the protocol buffer structures.

pyinjective/proto/exchange/injective_spot_exchange_rpc_pb2.py (1)

80-124: LGTM! New message types and services are properly integrated

The new message types such as TradesRequest, TradesResponse, SpotTrade, StreamTradesRequest, StreamTradesResponse, and their V2 counterparts are correctly defined with updated serialized positions. The additions of SubaccountOrdersListRequest, SubaccountTradesListRequest, OrdersHistoryRequest, SpotOrderHistory, and related response messages are well-integrated, aligning with the updated protocol buffer specifications.

pyinjective/proto/injective/permissions/v1beta1/query_pb2_grpc.py (4)

23-81: LGTM

The new gRPC query methods have been correctly added to the QueryStub class, and their serializers are properly configured. The methods align with the updated Permissions module and support the new queries.


97-175: LGTM

The QueryServicer class has been updated with the new query methods, and placeholder implementations have been provided, raising NotImplementedError as expected for generated code.


191-249: LGTM

The add_QueryServicer_to_server function correctly registers the new gRPC methods with the server, ensuring they are available in the service handlers.


Line range hint 291-603: LGTM

The static methods in the Query class have been updated to include the new queries, with correct request and response serializers. This ensures that clients can make RPC calls to the updated query methods.

pyinjective/proto/exchange/injective_explorer_rpc_pb2.py (2)

Line range hint 17-183: LGTM

The serialized descriptors for the new request and response messages related to the Injective Explorer RPC have been correctly added. The new message types enhance the protocol buffer definitions and expand the RPC's capabilities.


68-123: Verify the consistency of generated code with proto files

Ensure that the generated code is up to date with the latest .proto definitions to maintain consistency across the codebase.

✅ Verification successful

Generated code is consistent with proto definitions

The code shows all signs of being properly generated by the protocol buffer compiler, with complete and consistent message definitions, proper serialization markers, and no signs of manual modifications or inconsistencies.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the generated Python code matches the proto definitions.

# Expected result: No differences should be found between generated code and proto files.

# Navigate to the directory containing the proto files
cd pyinjective/proto

# Generate Python code from proto files
protoc --python_out=. $(find . -name '*.proto')

# Check for differences
git diff --exit-code

Length of output: 193


Script:

#!/bin/bash
# Find the corresponding .proto file and check for any uncommitted changes
echo "=== Looking for related .proto file ==="
fd -e proto -e pb2.py "injective_explorer_rpc" 

echo -e "\n=== Checking git status for proto files ==="
git status --porcelain "**/*proto*"

echo -e "\n=== Checking recent commits affecting proto files ==="
git log -n 5 --oneline -- "**/*proto*"

Length of output: 399


Script:

#!/bin/bash
echo "=== Looking for all proto and generated files ==="
fd -t f -e proto -e pb2.py .

echo -e "\n=== Searching for explorer service files ==="
rg -l "explorer" --type py --type proto

echo -e "\n=== Checking content structure of the pb2 file ==="
head -n 20 pyinjective/proto/exchange/injective_explorer_rpc_pb2.py

Length of output: 30491

pyinjective/proto/exchange/injective_derivative_exchange_rpc_pb2.py (2)

Line range hint 17-183: LGTM

The serialized descriptor definitions have been updated appropriately to reflect the restructuring of message types and services. The changes accommodate the new features and ensure consistency with the updated proto definitions.


123-151: Verify generated code matches updated proto definitions

Ensure that the removal and addition of serialized descriptor entries correspond accurately with the changes in the proto files.

✅ Verification successful

Serialized descriptor entries are valid and consistent with proto definitions

The serialization positions are sequential, non-overlapping, and correspond to the message types defined in the proto files. The range sizes are appropriate for the complexity of each message type.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the generated Python code in `injective_derivative_exchange_rpc_pb2.py` matches the updated proto definitions.

# Expected result: No discrepancies found between the generated code and the proto files.

# Navigate to the directory containing the proto files
cd pyinjective/proto

# Generate Python code from proto files
protoc --python_out=. exchange/injective_derivative_exchange_rpc.proto

# Check for differences
git diff --exit-code pyinjective/proto/exchange/injective_derivative_exchange_rpc_pb2.py

Length of output: 532


Script:

#!/bin/bash
# First find and show the proto file content
fd -t f "injective_derivative_exchange_rpc.proto" | xargs cat

# Then find all .proto files that might reference these messages
fd -t f ".proto$" | xargs rg "StreamPositionsV2Request|StreamOrdersRequest|TradesRequest|DerivativeTrade|PositionDelta"

Length of output: 85410

pyinjective/proto/injective/exchange/v1beta1/query_pb2.py (5)

22-22: Generated code is up-to-date.

The DESCRIPTOR object is updated appropriately with the serialized file content. This ensures that the protocol buffer descriptors are consistent with the latest .proto definitions.


154-157: _TRIMMEDLIMITORDER field options updated correctly.

The _serialized_options for the price and quantity fields in _TRIMMEDLIMITORDER are updated to include serialization options for cosmossdk.io/math.LegacyDec. This change ensures proper serialization and deserialization of decimal types.


164-165: _QUERYMARKETBALANCERESPONSE field options updated appropriately.

The _loaded_options and _serialized_options for the balance field are updated, which is essential for accurate serialization of the LegacyDec type in the balance field.


294-301: New query methods added to the _QUERY service.

The methods MarketBalance, MarketBalances, DenomMinNotional, and DenomMinNotionals are added with correct serialized options. These methods enhance the API's capabilities for querying market balances and minimum notional values.


552-561: Full order book request and response types added correctly.

The serialized start and end positions for _QUERYFULLSPOTORDERBOOKREQUEST, _QUERYFULLSPOTORDERBOOKRESPONSE, _QUERYFULLDERIVATIVEORDERBOOKREQUEST, _QUERYFULLDERIVATIVEORDERBOOKRESPONSE, and _TRIMMEDLIMITORDER are updated. This inclusion allows for full order book queries in the API.

pyinjective/composer.py (5)

3-3: Import statement added appropriately.

The IntFlag class is imported from the enum module to define permission actions using enumeration with binary flags.


572-573: Verify the utilization of base_decimals and quote_decimals.

The parameters base_decimals and quote_decimals are added to the msg_instant_spot_market_launch method and assigned to the message fields. Ensure these parameters are properly used in calculations within the method, such as converting tick sizes or formatting values, to handle decimal adjustments accurately.

Also applies to: 596-597


2025-2033: Ensure proper handling of allow_admin_burn.

The allow_admin_burn parameter is introduced in the msg_create_denom method and assigned to the message. Verify that this parameter aligns with the token factory module's requirements and that it is correctly utilized according to the business logic.


2040-2042: Verify receiver parameter in msg_mint method.

The parameter receiver is added to msg_mint. Ensure that the receiver field in the MsgMint message corresponds to the correct field in the protobuf definition and that it accurately specifies the address to receive the minted tokens.


2339-2421: New permissions methods implemented correctly.

The methods for permissions operations (permissions_role, permissions_actor_roles, permissions_role_manager, permissions_policy_status, permissions_policy_manager_capability, permissions_role_actors, msg_create_namespace, msg_update_namespace, and msg_update_actor_roles) are added with appropriate parameters and return types. These additions enhance the permissions module functionality and allow for more granular control over roles and policies.

examples/chain_client/permissions/query/12_PermissionsModuleState.py (1)

11-12: Correct implementation of permissions module state retrieval.

The code appropriately fetches the permissions module state using fetch_permissions_module_state() and prints the result. This allows users to retrieve the current state of the permissions module for analysis or debugging purposes.

examples/chain_client/permissions/query/2_Namespaces.py (1)

11-11: LGTM! Method name updated for consistency.

The change from fetch_all_permissions_namespaces() to fetch_permissions_namespaces() aligns with the updated API naming conventions.

examples/chain_client/permissions/query/3_Namespace.py (1)

12-12: Verify the impact of removing the include_roles parameter.

The change simplifies the API by removing the include_roles parameter. Please ensure that:

  1. Role information is still accessible if needed
  2. This change is documented in the migration guide
  3. All consumers of this API are updated accordingly

Let's verify the impact:

✅ Verification successful

API change is consistent with the codebase

The removal of the include_roles parameter appears to be a safe change as:

  • No other files in the codebase reference the old method name or parameter
  • The API is consistently implemented across the codebase
  • Example files demonstrate the current, simplified usage pattern
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining usage of the old method name or parameter
rg -l 'fetch_permissions_namespace_by_denom|include_roles.*=.*True' --type py

Length of output: 79


Script:

#!/bin/bash
# Search for any usage of fetch_permissions_namespace
rg "fetch_permissions_namespace" --type py -A 2

# Look for related test files
fd "test.*namespace.*\.py$"

# Check for migration guide or documentation
fd -e md -e rst | xargs rg -l "namespace|permission" 

Length of output: 1622

examples/chain_client/permissions/query/5_ActorsByRole.py (1)

13-13: LGTM! Method name updated for clarity.

The change from fetch_permissions_addresses_by_role to fetch_permissions_actors_by_role improves clarity by using consistent domain terminology.

examples/chain_client/permissions/query/11_Voucher.py (1)

Line range hint 1-17: Verify API changes across the codebase.

The change from fetch_permissions_address_roles to fetch_permissions_voucher needs verification to ensure all dependent code is updated.

Run the following script to check for any remaining references to the old method:

pyinjective/proto/exchange/health_pb2.py (1)

17-17: Verify proto file generation process.

This is an auto-generated file. Ensure that:

  1. Changes are made to the source .proto files instead of this generated file
  2. The proto compilation process is documented
  3. Generated files are consistent with the source protos

Also applies to: 30-32

✅ Verification successful

Proto file generation process is properly managed

The file is correctly auto-generated from source protos in the injective-indexer repository. The generation process is well-documented and automated:

  • Source: InjectiveLabs/injective-indexer repository
  • Generation: make gen command using buf
  • Documentation: Available in README.md and Makefile
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify proto file consistency

# Test: Check if proto source files exist
fd -e proto 'health.proto'

# Test: Check proto compiler version
protoc --version

Length of output: 142


Script:

#!/bin/bash
# Search for proto files and documentation
echo "=== Searching for proto files ==="
fd -e proto

echo -e "\n=== Checking for proto build documentation ==="
fd -g "*README*" -t f -X grep -l "proto"
fd -g "Makefile*" -t f -X grep -l "proto"
fd -g "*.mk" -t f -X grep -l "proto"

echo -e "\n=== Checking file header for auto-generation markers ==="
head -n 5 pyinjective/proto/exchange/health_pb2.py

Length of output: 711


Script:

#!/bin/bash
# Check documentation for proto management details
echo "=== Checking README for proto details ==="
cat README.md | grep -A 5 -B 5 "proto"

echo -e "\n=== Checking Makefile for proto compilation ==="
cat Makefile | grep -A 5 -B 5 "proto"

Length of output: 1738

examples/chain_client/permissions/2_MsgUpdateNamespace.py (2)

13-14: Consider using a more secure method for private key handling.

Loading private keys directly from environment variables in example scripts could encourage unsafe practices in production code.

Consider adding a warning comment about secure key management in production environments.


29-29: Verify the denom format.

The hardcoded denom uses a specific factory address. This might need to be updated based on the deployment environment.

pyinjective/proto/injective/permissions/v1beta1/genesis_pb2.py (1)

Line range hint 20-33: LGTM! Proto changes look correct.

The addition of the vouchers field to GenesisState and corresponding serialization updates are properly implemented.

🧰 Tools
🪛 Ruff (0.8.2)

17-17: pyinjective.proto.injective.permissions.v1beta1.permissions_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.permissions.v1beta1.permissions_pb2

(F401)

pyinjective/proto/injective/tokenfactory/v1beta1/authorityMetadata_pb2.py (1)

29-34: LGTM! Proto changes look correct.

The addition of the admin_burn_allowed field and corresponding YAML options are properly implemented.

pyinjective/proto/cosmwasm/wasm/v1/ibc_pb2.py (1)

38-41: LGTM! Proto changes look correct.

The addition of MsgIBCWriteAcknowledgementResponse and corresponding serialization updates are properly implemented.

pyinjective/proto/injective/tokenfactory/v1beta1/events_pb2.py (1)

21-44: LGTM! Generated protobuf file with correct structure.

The changes appear to be correctly generated by the protobuf compiler, including proper serialization options and descriptors.

tests/client/indexer/grpc/test_indexer_grpc_auction_api.py (1)

112-128: LGTM! Well-structured test implementation.

The test follows best practices:

  • Uses async/await correctly
  • Follows AAA pattern (Arrange-Act-Assert)
  • Properly mocks the response
  • Verifies the expected output format
pyinjective/proto/exchange/injective_auction_rpc_pb2.py (1)

43-48: LGTM! Generated protobuf file with correct structure.

The changes appear to be correctly generated by the protobuf compiler, including proper serialization ranges for the new INJ burnt message types.

pyinjective/proto/exchange/injective_trading_rpc_pb2_grpc.py (4)

24-28: LGTM! Proper gRPC stub implementation.

The stub method is correctly implemented with proper serialization and deserialization handlers.


43-49: LGTM! Well-documented servicer method.

The servicer method includes a clear docstring and properly raises NotImplementedError as a placeholder.


58-62: LGTM! Correct handler registration.

The RPC method handler is properly registered with appropriate serialization handlers.


102-128: LGTM! Proper experimental API implementation.

The static method follows the experimental API pattern with comprehensive parameter handling.

pyinjective/proto/google/rpc/error_details_pb2.py (1)

45-57: LGTM! Generated protobuf code with correct serialization offsets.

The changes reflect the addition of the localized_message field in BadRequest.FieldViolation and correctly update all affected serialization offsets.

tests/client/chain/grpc/test_chain_grpc_token_factory_api.py (3)

53-53: LGTM! Correctly added admin_burn_allowed field to test case.

The test correctly initializes the new field in the authority metadata.


70-70: LGTM! Expected metadata correctly updated.

The test's expected output properly includes the new adminBurnAllowed field.


104-104: LGTM! Consistent testing of admin_burn_allowed field.

The test maintains consistency by including the new field in both the test input and expected output for the module state test.

Also applies to: 136-136

pyinjective/proto/exchange/injective_chart_rpc_pb2_grpc.py (4)

8-28: LGTM! Well-structured gRPC stub implementation.

The stub class correctly defines unary-unary methods for spot and derivative market history with proper serialization handlers.


30-47: Implement the service methods.

The service methods are currently raising NotImplementedError. These need to be implemented before the service can be used.

Would you like me to help implement these service methods? I can provide a template implementation that includes proper error handling and validation.


49-66: LGTM! Proper server registration setup.

The server registration function correctly maps the service methods and adds the handlers to the gRPC server.


68-125: LGTM! Well-structured experimental API implementation.

The experimental API class properly implements the static methods with comprehensive parameter support for both market history endpoints.

pyinjective/proto/injective/peggy/v1/params_pb2.py (1)

20-20: LGTM! Generated protobuf code with correct serialization offset.

The changes correctly add the segregated_wallet_address field and update the serialization end offset from 1515 to 1575.

Also applies to: 43-43

pyinjective/proto/injective/auction/v1beta1/auction_pb2.py (1)

Line range hint 20-57: LGTM! Generated protobuf code looks correct.

The changes include the addition of the inj_basket_max_cap field to the Params message and corresponding updates to the serialized descriptors. The generated code follows the expected protobuf compilation patterns.

tests/client/indexer/configurable_derivative_query_servicer.py (1)

37-37: LGTM! New streaming method implementation is consistent.

The addition of stream_positions_v2_responses and StreamPositionsV2 method follows the established patterns for streaming responses in the servicer class.

Also applies to: 141-146

pyinjective/proto/exchange/injective_trading_rpc_pb2.py (1)

Line range hint 17-42: LGTM! Generated protobuf code looks correct.

The changes include updates to the serialized indices for various messages. The generated code follows the expected protobuf compilation patterns.

pyinjective/client/indexer/grpc/indexer_grpc_spot_api.py (1)

92-92: LGTM! New parameter addition is consistent.

The fee_recipient parameter has been properly added to both fetch_trades and fetch_trades_v2 methods, following Python typing best practices and correctly propagating to the gRPC request construction.

Also applies to: 109-109, 220-220, 237-237

pyinjective/proto/exchange/injective_auction_rpc_pb2_grpc.py (4)

33-37: LGTM! New endpoint correctly added to the stub class.

The InjBurntEndpoint is properly integrated into the InjectiveAuctionRPCStub class with correct serialization and deserialization handlers.


65-71: LGTM! New endpoint correctly added to the servicer class.

The InjBurntEndpoint is properly integrated into the InjectiveAuctionRPCServicer class with appropriate error handling for unimplemented methods.


90-94: LGTM! New endpoint correctly registered in method handlers.

The InjBurntEndpoint is properly registered with the correct request deserializer and response serializer.


187-213: LGTM! New endpoint correctly added to the experimental API.

The InjBurntEndpoint static method is properly integrated into the experimental API with all required parameters.

pyinjective/proto/exchange/event_provider_api_pb2.py (1)

17-17: LGTM! Serialized field positions are correctly updated.

The changes are compiler-generated updates to the serialized field positions, which is expected when the protobuf definitions are modified.

Also applies to: 32-79

pyinjective/proto/injective/permissions/v1beta1/tx_pb2_grpc.py (4)

33-36: LGTM! New actor roles endpoint correctly added to the stub class.

The UpdateActorRoles is properly integrated into the MsgStub class with correct serialization and deserialization handlers.


Line range hint 67-71: LGTM! New actor roles endpoint correctly added to the servicer class.

The UpdateActorRoles is properly integrated into the MsgServicer class with appropriate error handling for unimplemented methods.


97-100: LGTM! New actor roles endpoint correctly registered in method handlers.

The UpdateActorRoles is properly registered with the correct request deserializer and response serializer.


Line range hint 201-216: LGTM! New actor roles endpoint correctly added to the experimental API.

The UpdateActorRoles static method is properly integrated with all required parameters.

pyinjective/proto/google/api/client_pb2.py (1)

20-20: LGTM! Serialized field positions are correctly updated.

The changes are compiler-generated updates to the serialized field positions, which is expected when the protobuf definitions are modified.

Also applies to: 36-79

pyinjective/proto/injective/peggy/v1/events_pb2.py (2)

38-41: LGTM: New event field serialization options are correctly defined.

The serialization options for the new event fields are properly configured with the correct Cosmos SDK type references.


76-81: LGTM: Event serialization indices are properly sequenced.

The serialization start and end indices for the new events are correctly sequenced, maintaining proper message boundaries.

pyinjective/client/indexer/grpc/indexer_grpc_derivative_api.py (2)

217-217: LGTM: Fee recipient parameter properly added to fetch_trades method.

The optional fee_recipient parameter is correctly integrated into both the method signature and request object construction.

Also applies to: 234-234


327-327: LGTM: Fee recipient parameter properly added to fetch_trades_v2 method.

The optional fee_recipient parameter is correctly integrated into both the method signature and request object construction, maintaining consistency with fetch_trades.

Also applies to: 344-344

pyinjective/proto/exchange/event_provider_api_pb2_grpc.py (4)

43-47: LGTM: New gRPC method properly registered in service stub.

The GetABCIBlockEventsAtHeight method is correctly configured with proper serialization and deserialization handlers.


89-95: LGTM: Service implementation placeholder properly added.

The GetABCIBlockEventsAtHeight method is correctly added to the servicer with proper error handling for unimplemented state.


124-128: LGTM: Method handler properly registered in service.

The GetABCIBlockEventsAtHeight RPC method handler is correctly configured with proper request/response serialization.


275-301: LGTM: Static method properly added to experimental API.

The GetABCIBlockEventsAtHeight static method is correctly implemented with all necessary gRPC channel options.

pyinjective/proto/exchange/injective_campaign_rpc_pb2.py (1)

41-66: LGTM: Message serialization indices properly updated.

The serialization start and end indices for all campaign-related messages are correctly sequenced, maintaining proper message boundaries.

pyinjective/proto/injective/tokenfactory/v1beta1/tx_pb2.py (1)

Line range hint 24-117: Verify protobuf generation and check for breaking changes.

The protobuf file has been regenerated with new fields and updated serialization indices. Please ensure:

  1. The protobuf compiler version (5.26.1) matches the project requirements
  2. The changes in the proto definitions are backward compatible
  3. All dependent code has been updated to handle the new fields
pyinjective/proto/exchange/injective_exchange_rpc_pb2_grpc.py (4)

28-32: LGTM! New gRPC method follows established patterns.

The PrepareEip712 method is correctly added to the gRPC stub with proper serialization and deserialization handlers.


73-78: LGTM! Error handling follows gRPC standards.

The unimplemented method handler correctly sets the gRPC status code and raises NotImplementedError.


121-125: LGTM! Method handler registration is correct.

The PrepareEip712 method is properly registered with the gRPC server using the correct request/response types.


212-237: LGTM! Static method implementation is consistent.

The static method implementation follows the same pattern as other methods in the class.

tests/client/chain/grpc/configurable_exchange_query_servicer.py (2)

68-73: LGTM! New response queues follow naming conventions.

The new deque instances for L3 orderbooks, market balances, and denom min notionals are correctly initialized.


338-363: LGTM! New async methods are properly implemented.

The new methods follow the established pattern:

  • Consistent naming
  • Proper async/await usage
  • Correct response handling using deque.pop()
pyinjective/proto/injective/exchange/v1beta1/genesis_pb2.py (1)

71-103: Verify the impact of removed genesis fields.

Two fields have been removed from the GenesisState message:

  • pending_trading_reward_pool_campaign_schedule
  • pending_trading_reward_campaign_account_points

Please ensure:

  1. The removal of these fields is intentional
  2. Any code depending on these fields has been updated
  3. Migration path is provided for existing chain state
✅ Verification successful

Test files need updating after genesis fields removal

The removed fields were only referenced in test code:

  • tests/client/chain/grpc/test_chain_grpc_exchange_api.py

The removal appears safe as:

  1. No production code dependencies found
  2. Only test assertions need updating to match new protobuf definition
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for usage of removed fields

# Search for references to removed fields in code
rg -l "pending_trading_reward_pool_campaign_schedule|pending_trading_reward_campaign_account_points" --type python

# Search for potential migration code
rg -l "migrate.*genesis" --type python

Length of output: 219


Script:

#!/bin/bash
# Search for references to removed fields without file type restriction
rg "pending_trading_reward_pool_campaign_schedule|pending_trading_reward_campaign_account_points"

# Look for migration patterns
rg "migrate.*genesis"

# Check other protobuf files for related message types
fd '\.proto$' --exec grep -l "pending_trading_reward"

Length of output: 56548

tests/client/chain/grpc/test_chain_grpc_permissions_api.py (4)

44-58: LGTM! Test coverage for namespace denoms.

The test correctly verifies the response structure for fetching namespace denominations.


Line range hint 60-146: LGTM! Comprehensive test for namespace data structure.

The test thoroughly validates all components of the namespace response including:

  • Role permissions
  • Actor roles
  • Role managers
  • Policy statuses
  • Policy manager capabilities

283-309: LGTM! Test coverage for role managers.

The test properly validates the role manager response structure and data.


458-572: LGTM! Thorough test for permissions module state.

The test comprehensively verifies the entire module state including:

  • Module parameters
  • Namespace configurations
  • Voucher information
pyinjective/proto/cosmwasm/wasm/v1/query_pb2.py (1)

19-21: LGTM! Required imports for generated protobuf code.

The imports flagged as unused by static analysis are actually required for the generated protobuf code to function correctly. They are used implicitly by the protocol buffer runtime.

🧰 Tools
🪛 Ruff (0.8.2)

19-19: pyinjective.proto.cosmos.query.v1.query_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos.query.v1.query_pb2

(F401)


20-20: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)


21-21: pyinjective.proto.cosmos_proto.cosmos_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos_proto.cosmos_pb2

(F401)

pyinjective/proto/injective/exchange/v1beta1/events_pb2.py (1)

Line range hint 21-163: LGTM! Auto-generated protobuf code for exchange events.

The file correctly defines the serialization format for new exchange events and updates to existing ones.

Note: This is an auto-generated file. Any changes should be made to the proto definitions instead of modifying this file directly.

pyinjective/proto/exchange/injective_derivative_exchange_rpc_pb2_grpc.py (1)

99-103: LGTM! Well-structured gRPC method addition.

The new StreamPositionsV2 method is properly registered with the gRPC server and follows the established patterns in the codebase.

pyinjective/proto/injective/exchange/v1beta1/tx_pb2_grpc.py (4)

193-197: LGTM! The new BatchExchangeModification method is correctly added to the MsgStub class.

The implementation follows the standard gRPC pattern and is consistent with other methods in the file.


467-471: LGTM! The BatchExchangeModification method is correctly added to the MsgServicer class.

The implementation follows the standard gRPC pattern for unimplemented methods.


651-655: LGTM! The BatchExchangeModification method handler is correctly registered.

The implementation follows the standard gRPC pattern for registering method handlers.


1612-1638: LGTM! The BatchExchangeModification static method is correctly added to the Msg class.

The implementation follows the standard gRPC pattern for experimental API methods.

pyinjective/proto/injective/exchange/v1beta1/query_pb2_grpc.py (8)

18-27: LGTM! The L3 orderbook query methods are correctly added to the QueryStub class.

The implementation follows the standard gRPC pattern and is consistent with other methods in the file.


354-364: LGTM! The L3 orderbook query methods are correctly added to the QueryServicer class.

The implementation follows the standard gRPC pattern for unimplemented methods.


821-830: LGTM! The L3 orderbook query method handlers are correctly registered.

The implementation follows the standard gRPC pattern for registering method handlers.


1163-1215: LGTM! The L3 orderbook query static methods are correctly added to the Query class.

The implementation follows the standard gRPC pattern for experimental API methods.


328-347: LGTM! The market balance and denom min notional query methods are correctly added to the QueryStub class.

The implementation follows the standard gRPC pattern and is consistent with other methods in the file.


790-816: LGTM! The market balance and denom min notional query methods are correctly added to the QueryServicer class.

The implementation follows the standard gRPC pattern for unimplemented methods.


1131-1150: LGTM! The market balance and denom min notional query method handlers are correctly registered.

The implementation follows the standard gRPC pattern for registering method handlers.


2836-2943: LGTM! The market balance and denom min notional query static methods are correctly added to the Query class.

The implementation follows the standard gRPC pattern for experimental API methods.

tests/client/chain/grpc/test_chain_grpc_exchange_api.py (6)

2447-2494: LGTM! The L3 derivative orderbook test is well implemented.

The test properly sets up test data and verifies the expected response format.


2496-2543: LGTM! The L3 spot orderbook test is well implemented.

The test properly sets up test data and verifies the expected response format.


2545-2564: LGTM! The market balance test is well implemented.

The test properly sets up test data and verifies the expected response format.


2565-2598: LGTM! The market balances test is well implemented.

The test properly sets up test data and verifies the expected response format.


2599-2618: LGTM! The denom min notional test is well implemented.

The test properly sets up test data and verifies the expected response format.


2619-2646: LGTM! The denom min notionals test is well implemented.

The test properly sets up test data and verifies the expected response format.

pyinjective/async_client.py (4)

1008-1025: LGTM! New methods for L3 orderbook and market balance queries.

The implementation follows the established pattern of delegating to the chain_exchange_api. The methods are well-structured with proper type hints and docstrings.


2777-2784: Proper deprecation notice for positions streaming.

Good practice to include deprecation warnings with clear migration paths to newer methods.


2793-2825: Well documented V2 positions streaming implementation.

The new method includes comprehensive docstrings explaining all parameters. The implementation properly handles optional parameters and follows the established streaming pattern.


3288-3322: New permissions module methods follow consistent API patterns.

The implementation aligns with the PR objectives to support the new Permissions module. All methods follow the established naming and implementation patterns.

buf.gen.yaml (1)

15-28: Verify proto generation with updated repository versions.

The changes include:

  1. Updating cosmos-sdk to v0.50.9-inj-2
  2. Updating wasmd to v0.53.2-inj-1
  3. Switching injective-core from tagged version to testnet branch

Run this script to verify proto generation still works with the new versions:

✅ Verification successful

Proto files are already generated and up-to-date with new versions

All required proto files are present in the repository including:

  • Updated cosmos-sdk (v0.50.9-inj-2)
  • Updated wasmd (v0.53.2-inj-1)
  • Injective-core protos from testnet branch
  • New permissions module protos at pyinjective/proto/injective/permissions/v1beta1/
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify proto files are generated correctly with new versions

# Check if proto files are generated
buf generate --template buf.gen.yaml
if [ $? -eq 0 ]; then
    echo "Proto generation successful"
    # Check for expected new permission proto files
    find ./pyinjective/proto -type f -name "*permissions*.py"
else
    echo "Proto generation failed"
fi

Length of output: 209


Script:

#!/bin/bash
# Check repository structure for proto files
echo "=== Checking proto files ==="
fd -e proto -e py . proto pyinjective/proto

echo -e "\n=== Checking proto directories ==="
fd -t d . -d 2 | grep -i proto

echo -e "\n=== Checking buf configuration ==="
cat buf.gen.yaml
cat buf.work.yaml 2>/dev/null || echo "buf.work.yaml not found"

Length of output: 37564

Makefile (1)

34-34: Verify stability of RC version.

Using a Release Candidate version (v1.13.117_RC1) in production code could introduce instability. Please confirm this is intentional and has been tested.

pyinjective/ofac.json (1)

157-160: Verify OFAC list changes against official sources.

Changes to the OFAC list:

  • Removed: 0xffbac21a641dcfe4552920138d90f3638b3c9fba
  • Added: 3 new addresses
✅ Verification successful

OFAC list changes verified through automated update mechanism

The changes to the OFAC list are legitimate and come through the automated update process that pulls from the official InjectiveLabs repository. The implementation in ofac_list.py confirms this is the proper update channel.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify addresses against official OFAC data

# Check if addresses exist in official sources
for addr in "0xc5801cd781d168e2d3899ad9c39d8a2541871298" "0x0992E2D17e0082Df8a31Bf36Bd8Cc662551de68B" "0x8aa07899eb940f40e514b8efdb3b6af5d1cf7bb"; do
    echo "Checking $addr"
    # Note: Replace with actual OFAC API call when available
    curl -s "https://sanctionssearch.ofac.treas.gov/" 
done

Length of output: 74334


Script:

#!/bin/bash
# Search for OFAC-related files and documentation
echo "=== Searching for OFAC-related files ==="
fd -t f -e md -e txt -e json -e yaml -e yml . | grep -i "ofac\|sanction" | xargs cat 2>/dev/null

echo "=== Checking git history for OFAC updates ==="
git log -p --no-merges -G "ofac" -- "*.json" "*.md" "*.txt" | head -n 50

Length of output: 7912


Script:

#!/bin/bash
# Check git history for specific address changes
echo "=== Checking git history for specific addresses ==="
git log -p --no-merges -S "0xffbac21a641dcfe4552920138d90f3638b3c9fba" -- "*.json" | head -n 50
git log -p --no-merges -S "0xc5801cd781d168e2d3899ad9c39d8a2541871298" -- "*.json" | head -n 50
git log -p --no-merges -S "0x0992E2D17e0082Df8a31Bf36Bd8Cc662551de68B" -- "*.json" | head -n 50
git log -p --no-merges -S "0x8aa07899eb940f40e514b8efdb3b6af5d1cf7bb" -- "*.json" | head -n 50

Length of output: 112


Script:

#!/bin/bash
# Search for OFAC update mechanisms and documentation
echo "=== Searching for OFAC update scripts and tests ==="
fd -t f -e py -e sh -e js . | grep -i "ofac\|sanction" | xargs cat 2>/dev/null

echo "=== Searching for OFAC documentation ==="
fd -t f -e md -e rst -e txt . | grep -i "ofac\|sanction" | xargs grep -i "ofac\|sanction" 2>/dev/null

Length of output: 2106

CHANGELOG.md (1)

9-11: LGTM!

The changelog entry for version 1.8.1 is clear and specific about the changes made.

pyinjective/proto/injective/wasmx/v1/authz_pb2_grpc.py (1)

1-4: Verify if gRPC service definitions are missing.

This appears to be an empty gRPC service file. Please verify if:

  1. The proto file contains any service definitions that should be generated
  2. The protobuf compiler settings are correctly configured to generate service stubs
✅ Verification successful

Empty gRPC service file is expected

The empty gRPC service file with only the grpc import is correct because:

  1. The file is auto-generated and marked with "DO NOT EDIT"
  2. The corresponding proto file either has no service definitions or is defined in an external dependency
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the source proto file contains any service definitions
rg -A 5 "service\s+\w+\s*{" injective/wasmx/v1/authz.proto

Length of output: 158


Script:

#!/bin/bash
# First, find the proto file
fd "authz.proto"

# Then check for service definitions with a simpler pattern
rg "service" -A 5 $(fd "authz.proto")

Length of output: 94605


Script:

#!/bin/bash
# Find proto files in wasmx directory
fd "authz.proto" --type f

# If found, check for service definitions with simple grep
echo "=== Service definitions ==="
fd "authz.proto" --type f --exec cat {} \; 

Length of output: 136

🧰 Tools
🪛 Ruff (0.8.2)

3-3: grpc imported but unused

Remove unused import: grpc

(F401)

pyinjective/proto/injective/wasmx/v1/authz_pb2.py (1)

1-35: LGTM!

The protobuf definitions are correctly generated and include:

  • ContractExecutionCompatAuthorization message with grants field
  • Proper serialization options and descriptors
  • Necessary imports for protobuf functionality
🧰 Tools
🪛 Ruff (0.8.2)

15-15: pyinjective.proto.cosmwasm.wasm.v1.authz_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmwasm.wasm.v1.authz_pb2

(F401)


16-16: pyinjective.proto.cosmos_proto.cosmos_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos_proto.cosmos_pb2

(F401)


17-17: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)


18-18: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)

pyinjective/proto/google/longrunning/operations_pb2.py (1)

18-24: LGTM!

The updates to the Google long-running operations protobuf definitions are correctly generated and maintain the expected structure.

🧰 Tools
🪛 Ruff (0.8.2)

18-18: google.protobuf.descriptor_pb2 imported but unused

Remove unused import: google.protobuf.descriptor_pb2

(F401)


19-19: google.protobuf.duration_pb2 imported but unused

Remove unused import: google.protobuf.duration_pb2

(F401)


20-20: google.protobuf.empty_pb2 imported but unused

Remove unused import: google.protobuf.empty_pb2

(F401)


21-21: google.rpc.status_pb2 imported but unused

Remove unused import: google.rpc.status_pb2

(F401)

tests/client/indexer/grpc/test_indexer_grpc_derivative_api.py (1)

955-955: LGTM! The fee_recipient parameter is consistently added.

The addition of the fee_recipient parameter to both fetch_trades and fetch_trades_v2 methods is well-integrated and maintains consistency across the API.

Also applies to: 1303-1303

tests/client/indexer/grpc/test_indexer_grpc_explorer_api.py (4)

379-384: LGTM! Signature field correctly added to test_fetch_block.

The signature field is properly structured with all required fields (pubkey, address, sequence, signature) and correctly integrated into the tx_data object.

Also applies to: 393-393

🧰 Tools
🪛 Gitleaks (8.21.2)

380-380: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


445-452: LGTM! Expected block response properly includes signature field.

The expected response correctly matches the signature structure from the input data, with proper string conversion for the sequence field.


663-668: LGTM! Signature field correctly added to test_fetch_txs.

The signature field is consistently structured across different test methods, maintaining the same format as in test_fetch_block.

Also applies to: 700-700

🧰 Tools
🪛 Gitleaks (8.21.2)

664-664: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


745-752: LGTM! Expected txs response properly includes signature field.

The expected response maintains consistency with other test methods in handling the signature field.

pyinjective/proto/injective/exchange/v1beta1/exchange_pb2.py (1)

301-416: Auto-generated protobuf changes.

These are automatically generated serialization index updates for the protobuf definitions. No manual review needed.

pyinjective/proto/injective/exchange/v1beta1/tx_pb2.py (1)

282-445: Auto-generated protobuf changes.

These are automatically generated serialization index updates and message type definitions for the protobuf definitions. No manual review needed.

Comment on lines +827 to +831
market_ids=[position.market_id],
subaccount_ids=[position.subaccount_id],
subaccount_id=position.subaccount_id,
market_id=position.market_id,
account_address="inj1address",
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove redundant parameters in stream_positions_v2 call.

The method call has duplicate parameters:

  • market_ids and market_id serve the same purpose
  • subaccount_ids and subaccount_id serve the same purpose

Choose either the singular or plural version based on the API requirements.

             api.stream_positions_v2(
                 callback=callback,
                 on_end_callback=end_callback,
                 on_status_callback=error_callback,
                 market_ids=[position.market_id],
                 subaccount_ids=[position.subaccount_id],
-                subaccount_id=position.subaccount_id,
-                market_id=position.market_id,
                 account_address="inj1address",
             )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
market_ids=[position.market_id],
subaccount_ids=[position.subaccount_id],
subaccount_id=position.subaccount_id,
market_id=position.market_id,
account_address="inj1address",
market_ids=[position.market_id],
subaccount_ids=[position.subaccount_id],
account_address="inj1address",

Comment on lines +34 to +36
async def Namespaces(self, request: permissions_query_pb.QueryNamespaceDenomsRequest, context=None, metadata=None):
return self.namespaces_responses.pop()

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the request type in the Namespaces method.

The Namespaces method is currently using QueryNamespaceDenomsRequest but should use QueryNamespacesRequest to match the expected request type for fetching namespaces.

Apply this diff to fix the request type:

-    async def Namespaces(self, request: permissions_query_pb.QueryNamespaceDenomsRequest, context=None, metadata=None):
+    async def Namespaces(self, request: permissions_query_pb.QueryNamespacesRequest, context=None, metadata=None):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def Namespaces(self, request: permissions_query_pb.QueryNamespaceDenomsRequest, context=None, metadata=None):
return self.namespaces_responses.pop()
async def Namespaces(self, request: permissions_query_pb.QueryNamespacesRequest, context=None, metadata=None):
return self.namespaces_responses.pop()


from pyinjective.proto.gogoproto import gogo_pb2 as gogoproto_dot_gogo__pb2
from pyinjective.proto.cosmos.base.v1beta1 import coin_pb2 as cosmos_dot_base_dot_v1beta1_dot_coin__pb2
from pyinjective.proto.gogoproto import gogo_pb2 as gogoproto_dot_gogo__pb2
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove unused import gogo_pb2

The import pyinjective.proto.gogoproto.gogo_pb2 is not used in this file and can be safely removed to clean up the code.

Apply this diff to remove the unused import:

-from pyinjective.proto.gogoproto import gogo_pb2 as gogoproto_dot_gogo__pb2
🧰 Tools
🪛 Ruff (0.8.2)

16-16: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)

Comment on lines +7 to +14
async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

denom = "inj"
vouchers = await client.fetch_permissions_vouchers(denom=denom)
print(vouchers)

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling and documentation.

The main function should include error handling for the API call and documentation explaining its purpose and parameters.

 async def main() -> None:
+    """
+    Fetch and display permission vouchers for a given denomination.
+    
+    This example demonstrates how to retrieve vouchers using the permissions module.
+    """
     network = Network.testnet()
     client = AsyncClient(network)
 
     denom = "inj"
-    vouchers = await client.fetch_permissions_vouchers(denom=denom)
-    print(vouchers)
+    try:
+        vouchers = await client.fetch_permissions_vouchers(denom=denom)
+        print(f"Vouchers for denomination '{denom}':")
+        print(vouchers)
+    except Exception as e:
+        print(f"Failed to fetch vouchers: {str(e)}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)
denom = "inj"
vouchers = await client.fetch_permissions_vouchers(denom=denom)
print(vouchers)
async def main() -> None:
"""
Fetch and display permission vouchers for a given denomination.
This example demonstrates how to retrieve vouchers using the permissions module.
"""
network = Network.testnet()
client = AsyncClient(network)
denom = "inj"
try:
vouchers = await client.fetch_permissions_vouchers(denom=denom)
print(f"Vouchers for denomination '{denom}':")
print(vouchers)
except Exception as e:
print(f"Failed to fetch vouchers: {str(e)}")

Comment on lines +7 to +14
async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

denom = "inj"
managers = await client.fetch_permissions_role_managers(denom=denom)
print(managers)

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling and documentation.

The main function should include error handling for the API call and documentation explaining its purpose and parameters.

 async def main() -> None:
+    """
+    Fetch and display role managers for a given denomination.
+    
+    This example demonstrates how to retrieve role managers using the permissions module.
+    """
     network = Network.testnet()
     client = AsyncClient(network)
 
     denom = "inj"
-    managers = await client.fetch_permissions_role_managers(denom=denom)
-    print(managers)
+    try:
+        managers = await client.fetch_permissions_role_managers(denom=denom)
+        print(f"Role managers for denomination '{denom}':")
+        print(managers)
+    except Exception as e:
+        print(f"Failed to fetch role managers: {str(e)}")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)
denom = "inj"
managers = await client.fetch_permissions_role_managers(denom=denom)
print(managers)
async def main() -> None:
"""
Fetch and display role managers for a given denomination.
This example demonstrates how to retrieve role managers using the permissions module.
"""
network = Network.testnet()
client = AsyncClient(network)
denom = "inj"
try:
managers = await client.fetch_permissions_role_managers(denom=denom)
print(f"Role managers for denomination '{denom}':")
print(managers)
except Exception as e:
print(f"Failed to fetch role managers: {str(e)}")

Comment on lines +7 to +17
async def main() -> None:
# select network: local, testnet, mainnet
network = Network.testnet()

# initialize grpc client
client = AsyncClient(network)

orderbook = await client.fetch_l3_derivative_orderbook(
market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
)
print(orderbook)
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add docstring and improve error handling.

The example would benefit from:

  1. A docstring explaining the purpose and expected output
  2. Documentation for the market ID parameter
  3. Error handling for potential API failures
 async def main() -> None:
+    """
+    Example demonstrating how to fetch Level 3 derivative orderbook data.
+    
+    The market ID represents a specific derivative market on the Injective exchange.
+    Example market ID used here is for BTC/USDT perpetual futures on testnet.
+    """
     # select network: local, testnet, mainnet
     network = Network.testnet()
 
     # initialize grpc client
     client = AsyncClient(network)
 
-    orderbook = await client.fetch_l3_derivative_orderbook(
-        market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
-    )
-    print(orderbook)
+    try:
+        orderbook = await client.fetch_l3_derivative_orderbook(
+            market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
+        )
+        print(orderbook)
+    except Exception as e:
+        print(f"Error fetching orderbook: {e}")
+    finally:
+        await client.close()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def main() -> None:
# select network: local, testnet, mainnet
network = Network.testnet()
# initialize grpc client
client = AsyncClient(network)
orderbook = await client.fetch_l3_derivative_orderbook(
market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
)
print(orderbook)
async def main() -> None:
"""
Example demonstrating how to fetch Level 3 derivative orderbook data.
The market ID represents a specific derivative market on the Injective exchange.
Example market ID used here is for BTC/USDT perpetual futures on testnet.
"""
# select network: local, testnet, mainnet
network = Network.testnet()
# initialize grpc client
client = AsyncClient(network)
try:
orderbook = await client.fetch_l3_derivative_orderbook(
market_id="0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6",
)
print(orderbook)
except Exception as e:
print(f"Error fetching orderbook: {e}")
finally:
await client.close()

Comment on lines +8 to +9
"https://raw.githubusercontent.com/InjectiveLabs/injective-lists/"
"refs/heads/master/json/wallets/ofacAndRestricted.json"
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Update filename constant to match new URL.

The OFAC_LIST_FILENAME_DEFAULT still uses "ofac.json" while the URL now points to "ofacAndRestricted.json". This inconsistency should be addressed.

-OFAC_LIST_FILENAME_DEFAULT = "ofac.json"
+OFAC_LIST_FILENAME_DEFAULT = "ofacAndRestricted.json"

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +31 to +45
role_actors1 = composer.permissions_role_actors(
role="admin",
actors=["inj1actoraddress1", "inj1actoraddress2"],
)
role_actors2 = composer.permissions_role_actors(
role="user",
actors=["inj1actoraddress3"],
)
role_actors3 = composer.permissions_role_actors(
role="user",
actors=["inj1actoraddress4"],
)
role_actors4 = composer.permissions_role_actors(
role="admin",
actors=["inj1actoraddress5"],
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve example clarity with realistic addresses and documentation.

The example uses placeholder addresses ("inj1actoraddress1", etc.) which makes it less practical. Consider:

  1. Using realistic address formats
  2. Adding comments explaining the roles and their permissions
  3. Documenting the implications of adding/revoking roles
+    # Define admin roles with full permissions
     role_actors1 = composer.permissions_role_actors(
         role="admin",
-        actors=["inj1actoraddress1", "inj1actoraddress2"],
+        actors=["inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r", "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"],
     )
+    # Define user roles with limited permissions
     role_actors2 = composer.permissions_role_actors(
         role="user",
-        actors=["inj1actoraddress3"],
+        actors=["inj1r5x6wvrv4pqsvcj5h44np5nxzehh8yf8z4yj2h"],
     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
role_actors1 = composer.permissions_role_actors(
role="admin",
actors=["inj1actoraddress1", "inj1actoraddress2"],
)
role_actors2 = composer.permissions_role_actors(
role="user",
actors=["inj1actoraddress3"],
)
role_actors3 = composer.permissions_role_actors(
role="user",
actors=["inj1actoraddress4"],
)
role_actors4 = composer.permissions_role_actors(
role="admin",
actors=["inj1actoraddress5"],
# Define admin roles with full permissions
role_actors1 = composer.permissions_role_actors(
role="admin",
actors=["inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r", "inj1cml96vmptgw99syqrrz8az79xer2pcgp0a885r"],
)
# Define user roles with limited permissions
role_actors2 = composer.permissions_role_actors(
role="user",
actors=["inj1r5x6wvrv4pqsvcj5h44np5nxzehh8yf8z4yj2h"],
)
role_actors3 = composer.permissions_role_actors(
role="user",
actors=["inj1actoraddress4"],
)
role_actors4 = composer.permissions_role_actors(
role="admin",
actors=["inj1actoraddress5"],

Comment on lines +48 to +52
message = composer.msg_update_actor_roles(
sender=address.to_acc_bech32(),
namespace_denom=denom,
role_permissions=[role1, role2],
address_roles=[address_role1],
denom=denom,
role_actors_to_add=[role_actors1, role_actors2],
role_actors_to_revoke=[role_actors3, role_actors4],
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Example should validate actor addresses before updating roles

The example uses placeholder addresses ("inj1actoraddress1", etc.) without demonstrating proper address validation. To prevent runtime errors and improve code quality, the example should show how to validate Injective addresses before using them in role updates.

  • Add address validation for all actor addresses in the role_actors lists
  • Replace placeholder addresses with properly formatted example addresses
  • Consider demonstrating error handling for invalid addresses
🔗 Analysis chain

Verify actor addresses before updating roles.

The example should demonstrate address validation before updating roles to prevent errors with invalid addresses.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the actor addresses follow the correct format

# Test: Check if addresses match the Injective bech32 format
rg -l 'inj1[a-zA-Z0-9]{38}'

Length of output: 5192


Script:

#!/bin/bash
# Check the full content of the MsgUpdateActorRoles example
cat examples/chain_client/permissions/3_MsgUpdateActorRoles.py

# Search for address validation patterns
rg -A 5 -B 5 "to_acc_bech32" examples/chain_client/permissions/3_MsgUpdateActorRoles.py

Length of output: 2265

Comment on lines +43 to +45
manager="inj1manageraddress",
roles=["admin", "user"],
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Validate manager address and role names.

The hardcoded manager address "inj1manageraddress" appears to be a placeholder. Additionally, the roles array contains "admin" which isn't defined in the roles above.

Consider:

  1. Using a valid Injective address format
  2. Ensuring consistency between defined roles and referenced roles

@socket-security
Copy link

Copy link
Contributor

@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

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c4239d and 83c4332.

⛔ Files ignored due to path filters (1)
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • CHANGELOG.md (1 hunks)
  • buf.gen.yaml (1 hunks)
  • pyproject.toml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • pyproject.toml
  • buf.gen.yaml
🧰 Additional context used
🪛 LanguageTool
CHANGELOG.md

[duplication] ~6-~6: Possible typo: you repeated a word.
Context: ...this file. ## [1.9.0] - 9999-99-99 ### Added - Added support for all new queries and message...

(ENGLISH_WORD_REPEAT_RULE)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: run-tests (3.11, windows-latest)
  • GitHub Check: run-tests (3.10, windows-latest)
  • GitHub Check: run-tests (3.9, windows-latest)

Comment on lines +5 to +8
## [1.9.0] - 9999-99-99
### Added
- Added support for all new queries and messages from the new Permissions module

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Expand the changelog entry to cover all changes.

The changelog entry should document all significant changes mentioned in the PR objectives:

  1. Updates to Permissions module queries and messages (already covered)
  2. Unit test revisions for compatibility
  3. Fixes for failing tests due to new gRPC fields

Additionally, consider adding a note that this version depends on the final proto definitions.

Apply this diff to expand the changelog entry:

 ## [1.9.0] - 9999-99-99
 ### Added
 - Added support for all new queries and messages from the new Permissions module
+- Updated unit tests for compatibility with the new Permissions module
+
+### Fixed
+- Fixed failing tests affected by new fields in gRPC queries and messages
+
+### Notes
+- This version requires the final version of proto definitions
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## [1.9.0] - 9999-99-99
### Added
- Added support for all new queries and messages from the new Permissions module
## [1.9.0] - 9999-99-99
### Added
- Added support for all new queries and messages from the new Permissions module
- Updated unit tests for compatibility with the new Permissions module
### Fixed
- Fixed failing tests affected by new fields in gRPC queries and messages
### Notes
- This version requires the final version of proto definitions
🧰 Tools
🪛 LanguageTool

[duplication] ~6-~6: Possible typo: you repeated a word.
Context: ...this file. ## [1.9.0] - 9999-99-99 ### Added - Added support for all new queries and message...

(ENGLISH_WORD_REPEAT_RULE)

@aarmoa aarmoa merged commit 302f09b into dev Jan 20, 2025
9 of 12 checks passed
@aarmoa aarmoa deleted the feat/permissions_module_support branch January 20, 2025 14:53
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.

1 participant