Skip to content

Commit

Permalink
Add sequence manager (#190)
Browse files Browse the repository at this point in the history
* Add sequence manager

* Fix faucet endpoint example
  • Loading branch information
samtin0x authored Jul 11, 2024
1 parent fbbb62d commit 1f549ce
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 5 deletions.
42 changes: 39 additions & 3 deletions v4-client-py-v2/dydx_v4_client/node/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,24 @@ async def get_rewards_params(self) -> rewards_query.QueryParamsResponse:
return stub.Params(rewards_query.QueryParamsRequest())


class SequenceManager:
def __init__(self, query_node_client: QueryNodeClient):
self.query_node_client = query_node_client

async def before_send(self, wallet: Wallet):
if self.query_node_client:
account = await self.query_node_client.get_account(wallet.address)
wallet.sequence = account.sequence

async def after_send(self, wallet: Wallet):
if not self.query_node_client:
wallet.sequence += 1


@dataclass
class MutatingNodeClient(QueryNodeClient):
builder: Builder
sequence_manager: SequenceManager = None

async def broadcast(self, transaction: Tx, mode=BroadcastMode.BROADCAST_MODE_SYNC):
"""
Expand Down Expand Up @@ -459,7 +474,15 @@ async def send_message(
Returns:
The response from the broadcast.
"""
return await self.send(wallet, self.builder.build(wallet, message), mode)
if self.sequence_manager:
await self.sequence_manager.before_send(wallet)

response = await self.send(wallet, self.builder.build(wallet, message), mode)

if self.sequence_manager:
await self.sequence_manager.after_send(wallet)

return response

async def broadcast_message(
self, wallet: Wallet, message: Message, mode=BroadcastMode.BROADCAST_MODE_SYNC
Expand All @@ -475,7 +498,15 @@ async def broadcast_message(
Returns:
The response from the broadcast.
"""
return await self.broadcast(self.builder.build(wallet, message), mode)
if self.sequence_manager:
await self.sequence_manager.before_send(wallet)

response = await self.broadcast(self.builder.build(wallet, message), mode)

if self.sequence_manager:
await self.sequence_manager.after_send(wallet)

return response

def build_transaction(self, wallet: Wallet, messages: List[Message], fee: Fee):
"""
Expand Down Expand Up @@ -521,9 +552,14 @@ def calculate_fee(self, gas_used) -> Fee:

@dataclass
class NodeClient(MutatingNodeClient):
manage_sequence: bool = True

@staticmethod
async def connect(config: NodeConfig) -> Self:
return NodeClient(config.channel, Builder(config.chain_id, config.usdc_denom))
client = NodeClient(config.channel, Builder(config.chain_id, config.usdc_denom))
if client.manage_sequence:
client.sequence_manager = SequenceManager(QueryNodeClient(client.channel))
return client

async def deposit(
self,
Expand Down
9 changes: 9 additions & 0 deletions v4-client-py-v2/dydx_v4_client/wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
from functools import partial
from typing import TYPE_CHECKING

import bech32
import ecdsa
from Crypto.Hash import RIPEMD160
from bip_utils import Bip39SeedGenerator, Bip44, Bip44Coins
from v4_proto.cosmos.crypto.secp256k1.keys_pb2 import PubKey

Expand Down Expand Up @@ -45,3 +47,10 @@ async def from_mnemonic(node: "NodeClient", mnemonic: str, address: str):
@property
def public_key(self) -> PubKey:
return PubKey(key=self.key.get_verifying_key().to_string("compressed"))

@property
def address(self) -> str:
public_key_bytes = self.public_key.key
sha256_hash = hashlib.sha256(public_key_bytes).digest()
ripemd160_hash = RIPEMD160.new(sha256_hash).digest()
return bech32.bech32_encode("dydx", bech32.convertbits(ripemd160_hash, 8, 5))
2 changes: 1 addition & 1 deletion v4-client-py-v2/examples/faucet_endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ async def test():
faucet = FaucetClient(TESTNET_FAUCET)
response = await faucet.fill(TEST_ADDRESS, 0, 2000)
print(response)
print(response.status)
print(response.status_code)


asyncio.run(test())
13 changes: 12 additions & 1 deletion v4-client-py-v2/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions v4-client-py-v2/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ websocket-client = "^1.7.0"
bip-utils = "^2.9.3"
ecdsa = "^0.19.0"
typing-extensions = "^4.12.2"
bech32 = "^1.2.0"
pycryptodome = "^3.20.0"


[tool.poetry.group.dev.dependencies]
Expand Down

0 comments on commit 1f549ce

Please sign in to comment.