Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 4 additions & 15 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,11 @@ repos:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/flakeheaven/flakeheaven
rev: 3.3.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.10
hooks:
- id: flakeheaven
name: flakeheaven
description: '`flakeheaven` is a `flake8` wrapper.'
entry: flakeheaven lint
language: python
types_or: [ python, jupyter, markdown, rst, yaml ]
require_serial: true
minimum_pre_commit_version: 2.9.0
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
name: isort (python)
- id: ruff
args: [--fix]
Comment thread
coderabbitai[bot] marked this conversation as resolved.
- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.9.1
hooks:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ clean-all:
$(call clean_repos)

clone-injective-indexer:
git clone https://github.com/InjectiveLabs/injective-indexer.git -b v1.18.3 --depth 1 --single-branch
git clone https://github.com/InjectiveLabs/injective-indexer.git -b v1.18.59 --depth 1 --single-branch
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Current Makefile pin =="
rg -n -C2 'clone-injective-indexer|injective-indexer\.git|-b v' Makefile

echo "== Remote tags check (exists + nearby versions) =="
git ls-remote --tags https://github.com/InjectiveLabs/injective-indexer.git \
  | rg -n 'refs/tags/v1\.18\.59$|refs/tags/v1\.19|refs/tags/v1\.18' \
  | tail -n 50

Repository: InjectiveLabs/sdk-python

Length of output: 502


🏁 Script executed:

# Search for references to proto versions, v1.19.0-beta, or indexer compatibility
rg -i "v1\.19|proto.*version|indexer.*version|compatibility" --type-list | head -5

Repository: InjectiveLabs/sdk-python

Length of output: 457


🏁 Script executed:

# Search for README or documentation files that might explain version requirements
find . -maxdepth 2 -type f \( -name "README*" -o -name "*.md" -o -name "requirements*" -o -name "setup.py" \) | head -20

Repository: InjectiveLabs/sdk-python

Length of output: 151


🏁 Script executed:

# Check if there are any version or compatibility files in the root
ls -la | grep -E "(version|proto|indexer|requirement)" || true

Repository: InjectiveLabs/sdk-python

Length of output: 50


🏁 Script executed:

# Search the codebase for any mentions of v1.18.59 or comments about this pin
rg "v1\.18\.59|v1\.19\.0" -A3 -B3

Repository: InjectiveLabs/sdk-python

Length of output: 674


🏁 Script executed:

# Check README for version or compatibility information
cat README.md | head -100

Repository: InjectiveLabs/sdk-python

Length of output: 2985


🏁 Script executed:

# Check CHANGELOG for version compatibility notes
cat CHANGELOG.md | head -200

Repository: InjectiveLabs/sdk-python

Length of output: 7787


🏁 Script executed:

# Search for any TODOs or FIXMEs related to versions or indexer
rg "TODO|FIXME|XXX" Makefile buf.gen.yaml -B2 -A2

Repository: InjectiveLabs/sdk-python

Length of output: 50


🏁 Script executed:

# Check if there's any documentation or comments explaining the version pin
rg "v1\.18|v1\.19|indexer" --type md -B2 -A2

Repository: InjectiveLabs/sdk-python

Length of output: 1759


Address version mismatch between proto and indexer pins.

The proto generation (buf.gen.yaml) uses v1.19.0-beta from injective-core, but the Makefile pins the indexer to v1.18.59. Based on the CHANGELOG (v1.13.0: compatibility with core v1.18.0 and indexer v1.18.3), indexer and core versions are kept closely aligned. For proto v1.19.0-beta, the indexer should likely be v1.19.x to ensure RPC/message definition compatibility. Either upgrade the indexer pin or clarify if using older indexer APIs is intentional.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` at line 29, The Makefile clones injective-indexer at v1.18.59 which
mismatches the proto generation using injective-core v1.19.0-beta
(buf.gen.yaml); update the indexer pin in the Makefile (the git clone line that
references injective-indexer) to a matching v1.19.x tag (or the exact
v1.19.0-beta-compatible release) to ensure RPC/message compatibility, or add a
clear comment in the Makefile explaining why the older indexer pin is
intentionally kept and provide compatibility notes referencing buf.gen.yaml.


clone-all: clone-injective-indexer

Expand Down
54 changes: 15 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,45 +72,21 @@ poetry run pytest -v

---

## Choose Exchange V1 or Exchange V2 queries

The Injective Python SDK provides two different clients for interacting with the exchange:

1. **Exchange V1 Client** (`async_client` module):
- Use this client if you need to interact with the original Injective Exchange API
- Import using: `from pyinjective.async_client import AsyncClient`
- Suitable for applications that need to maintain compatibility with the original exchange interface
- Example:
```python
from pyinjective.async_client import AsyncClient
from pyinjective.network import Network

async def main():
# Initialize client with mainnet
client = AsyncClient(network=Network.mainnet())
# Or use testnet
# client = AsyncClient(network=Network.testnet())
# Use V1 exchange queries here
```

2. **Exchange V2 Client** (`async_client_v2` module):
- Use this client for the latest exchange features and improvements
- Import using: `from pyinjective.async_client_v2 import AsyncClient`
- Recommended for new applications and when you need access to the latest exchange features
- Example:
```python
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.network import Network

async def main():
# Initialize client with mainnet
client = AsyncClient(network=Network.mainnet())
# Or use testnet
# client = AsyncClient(network=Network.testnet())
# Use V2 exchange queries here
```

Both clients provide similar interfaces but with different underlying implementations. Choose V2 for new projects unless you have specific requirements for V1 compatibility.
## Async client (exchange V2)

The Injective Python SDK exposes `AsyncClient` from the `async_client_v2` module:

- Import using: `from pyinjective.async_client_v2 import AsyncClient`
- Example:
```python
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.network import Network

Comment on lines +82 to +84
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Network module files:"
fd -i 'network.py'

echo "Network class definitions:"
rg -n --type=py '\bclass\s+Network\b'

echo "Current import paths used in repository:"
rg -n --type=py 'from pyinjective\.network import Network|from pyinjective\.core\.network import Network'

Repository: InjectiveLabs/sdk-python

Length of output: 35125


🏁 Script executed:

cat -n README.md | sed -n '75,95p'

Repository: InjectiveLabs/sdk-python

Length of output: 960


🏁 Script executed:

find pyinjective -name '__init__.py' -type f -exec grep -l "from.*network.*import\|Network" {} \;

Repository: InjectiveLabs/sdk-python

Length of output: 50


🏁 Script executed:

ls -la pyinjective/network.py 2>&1

Repository: InjectiveLabs/sdk-python

Length of output: 137


Fix the Network import path in the README.md V2 usage example.

Line 83 uses from pyinjective.network import Network, but this module does not exist. The correct import path is from pyinjective.core.network import Network, which is used consistently throughout the codebase and all examples. Users copying this documentation snippet will encounter an ImportError.

📝 Proposed doc fix
 from pyinjective.async_client_v2 import AsyncClient
-from pyinjective.network import Network
+from pyinjective.core.network import Network
📝 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
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.network import Network
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@README.md` around lines 82 - 84, The README V2 example imports Network from
the wrong module; update the import to use the canonical path by replacing "from
pyinjective.network import Network" with "from pyinjective.core.network import
Network" so the example matches the codebase and avoids ImportError when using
AsyncClient/Network in the V2 usage snippet.

async def main():
client = AsyncClient(network=Network.mainnet())
# Or use testnet
# client = AsyncClient(network=Network.testnet())
```

> **Market Format Differences**:
> - V1 AsyncClient: Markets are initialized with values in chain format (raw blockchain values)
Expand Down
16 changes: 8 additions & 8 deletions buf.gen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ inputs:
- module: buf.build/googleapis/googleapis
- module: buf.build/cosmos/ics23
- git_repo: https://github.com/InjectiveLabs/ibc-go
tag: v8.7.0-inj.3
tag: v8.7.0-inj.4
- git_repo: https://github.com/InjectiveLabs/wasmd
tag: v0.53.3-inj.2
tag: v0.53.3-inj.3
- git_repo: https://github.com/InjectiveLabs/cometbft
tag: v1.0.1-inj.6
tag: v1.0.1-inj.7
- git_repo: https://github.com/InjectiveLabs/cosmos-sdk
tag: v0.50.14-inj.4
tag: v0.50.14-inj.9
# - git_repo: https://github.com/InjectiveLabs/wasmd
# branch: v0.51.x-inj
# subdir: proto
- git_repo: https://github.com/InjectiveLabs/hyperlane-cosmos
tag: v1.0.1-inj
subdir: proto
# - git_repo: https://github.com/InjectiveLabs/hyperlane-cosmos
# tag: v1.0.1-inj
# subdir: proto
- git_repo: https://github.com/InjectiveLabs/injective-core
tag: v1.18.0
tag: v1.19.0-beta
subdir: proto
# - git_repo: https://github.com/InjectiveLabs/injective-core
# branch: c-655/add_chainlink_data_streams_oracle
Expand Down
54 changes: 54 additions & 0 deletions examples/chain_client/auction/2_MsgClaimVoucher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
dotenv.load_dotenv()
private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

network = Network.devnet()

client = AsyncClient(network)
composer = await client.composer()

gas_price = await client.current_chain_gas_price()
gas_price = int(gas_price * 1.1)

message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
network=network,
private_key=private_key_in_hexa,
gas_price=gas_price,
client=client,
composer=composer,
)

priv_key = PrivateKey.from_hex(private_key_in_hexa)
pub_key = priv_key.to_public_key()
address = pub_key.to_address()

denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

message = composer.msg_auction_claim_voucher(
sender=address.to_acc_bech32(),
denom=denom,
)

result = await message_broadcaster.broadcast([message])
print("---Transaction Response---")
print(json.dumps(result, indent=2))

gas_price = await client.current_chain_gas_price()
gas_price = int(gas_price * 1.1)
message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
17 changes: 17 additions & 0 deletions examples/chain_client/auction/query/1_Vouchers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

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


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
18 changes: 18 additions & 0 deletions examples/chain_client/auction/query/2_Voucher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

denom = "inj"
address = "inj1knhahceyp57j5x7xh69p7utegnnnfgxavmahjr"
voucher = await client.fetch_auction_voucher(denom=denom, address=address)
print(voucher)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
3 changes: 2 additions & 1 deletion examples/chain_client/distribution/1_SetWithdrawAddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

import dotenv

from pyinjective import AsyncClient, PrivateKey
from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network

Expand Down
3 changes: 2 additions & 1 deletion examples/chain_client/distribution/4_FundCommunityPool.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import dotenv

from pyinjective import AsyncClient, PrivateKey
from pyinjective import PrivateKey
from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network

Expand Down
54 changes: 54 additions & 0 deletions examples/chain_client/insurance/4_MsgClaimVoucher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import asyncio
import json
import os

import dotenv

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.broadcaster import MsgBroadcasterWithPk
from pyinjective.core.network import Network
from pyinjective.wallet import PrivateKey


async def main() -> None:
dotenv.load_dotenv()
private_key_in_hexa = os.getenv("INJECTIVE_PRIVATE_KEY")

network = Network.devnet()

client = AsyncClient(network)
composer = await client.composer()

gas_price = await client.current_chain_gas_price()
gas_price = int(gas_price * 1.1)

message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
network=network,
private_key=private_key_in_hexa,
gas_price=gas_price,
client=client,
composer=composer,
)

priv_key = PrivateKey.from_hex(private_key_in_hexa)
pub_key = priv_key.to_public_key()
address = pub_key.to_address()

denom = "factory/inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r/inj_test"

message = composer.msg_insurance_claim_voucher(
sender=address.to_acc_bech32(),
denom=denom,
)

result = await message_broadcaster.broadcast([message])
print("---Transaction Response---")
print(json.dumps(result, indent=2))

gas_price = await client.current_chain_gas_price()
gas_price = int(gas_price * 1.1)
message_broadcaster.update_gas_price(gas_price=gas_price)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
17 changes: 17 additions & 0 deletions examples/chain_client/insurance/query/1_Vouchers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

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


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
18 changes: 18 additions & 0 deletions examples/chain_client/insurance/query/2_Voucher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import asyncio

from pyinjective.async_client_v2 import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

denom = "inj"
address = "inj1knhahceyp57j5x7xh69p7utegnnnfgxavmahjr"
voucher = await client.fetch_insurance_voucher(denom=denom, address=address)
print(voucher)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
Loading
Loading