Skip to content

Conversation

@mmeloni
Copy link
Collaborator

@mmeloni mmeloni commented Nov 6, 2025

Summary by CodeRabbit

  • New Features

    • Added comprehensive test framework for Injective with mock chain, address generation, and custom handler support.
    • Added test utilities for market management, order execution, authorization flows, and oracle interactions.
    • Added mock constants and helper functions for blockchain testing scenarios.
  • Documentation

    • Added changelog documenting project version history and key changes.
  • Chores

    • Updated project configuration and dependencies for testing infrastructure.

@coderabbitai
Copy link

coderabbitai bot commented Nov 6, 2025

Walkthrough

A new Rust testing crate for Injective is established, including project configuration, mock infrastructure for chain and address generation, and comprehensive test utilities for authorization, banking, exchange, insurance, and oracle operations.

Changes

Cohort / File(s) Summary
Project Configuration
.gitignore, CHANGELOG.md, Cargo.toml
Added gitignore patterns for build outputs and IDE config; introduced CHANGELOG documenting v1.0.0–1.1.1; defined Rust crate manifest with dependencies (cosmwasm-std, cw-multi-test, injective crates, secp256k1, etc.)
Module Wiring
src/lib.rs, src/multi_test/mod.rs, src/test_tube/mod.rs
Exposed four public modules from lib root (mocks, multi_test, test_tube, utils); exposed address_generator and chain_mock submodules; exposed six test_tube submodules (authz, bank, exchange, insurance, oracle, utils)
Mocks Infrastructure
src/mocks.rs
Added public constants for market IDs, denoms, and decimals; introduced mock factory functions for spot markets, derivative markets, and mid-price TOB payloads
Multi-test Address Generation
src/multi_test/address_generator.rs
Implemented InjectiveAddressGenerator and StorageAwareInjectiveAddressGenerator strategies with Secp256k1-based Injective address generation, keccak256 hashing, and bech32 encoding
Multi-test Chain Mock
src/multi_test/chain_mock.rs
Created comprehensive mock chain infrastructure including CustomInjectiveHandler module, response/assertion containers, caching state, and factory functions for deterministic on-chain testing
Test Tube Authorization Utilities
src/test_tube/authz.rs
Added helpers for generic, send, and revoke authorizations; bulk execution of generic authorizations with expiration support
Test Tube Bank Utilities
src/test_tube/bank.rs
Introduced send and query_balance helpers for bank operations in test environments
Test Tube Exchange Utilities
src/test_tube/exchange.rs
Provided extensive market launch, order execution, and price creation functions for spot and perpetual markets; included governance admin and denom notional helpers
Test Tube Insurance Utilities
src/test_tube/insurance.rs
Added launch_insurance_fund helper for insurance fund provisioning in tests
Test Tube Oracle Utilities
src/test_tube/oracle.rs
Introduced price feed oracle setup, relay, and query utilities with governance proposal support
Test Tube Utils
src/test_tube/utils.rs
Added wasm_file path resolution (target/wasm32 and artifacts dirs) and store_code helper for contract deployment
General Utilities
src/utils.rs
Provided numeric conversion helpers (FPDecimal ↔ human-readable), market scaling for spot/perp orders, coin creation, and error message builders

Sequence Diagram(s)

sequenceDiagram
    participant Test
    participant MockApp as MockedInjectiveApp
    participant Handler as CustomInjectiveHandler
    participant Storage as State/ResponseCache

    Test->>MockApp: Execute custom message
    MockApp->>Handler: route execute
    Handler->>Storage: record message
    Handler->>Storage: lookup response
    alt Response configured
        Handler->>Handler: run optional assertion
        Handler->>Test: return stored response
    else No response
        Handler->>Test: return empty AppResponse
    end

    Test->>MockApp: Query custom data
    MockApp->>Handler: route query
    Handler->>Storage: record query
    Handler->>Storage: lookup response
    alt Response configured
        Handler->>Handler: run optional assertion
        Handler->>Test: return stored Binary
    else No response
        Handler->>Test: return empty Binary
    end
Loading
sequenceDiagram
    participant Test
    participant AddressGen as InjectiveAddressGenerator
    participant Crypto as Secp256k1
    participant Encoding as bech32/humanize

    Test->>AddressGen: generate_inj_address()
    AddressGen->>Crypto: gen secret key
    Crypto->>Crypto: derive public key
    AddressGen->>AddressGen: keccak256(pubkey[0:20])
    AddressGen->>Encoding: to_hex(hash) + prefix 0x
    AddressGen->>Encoding: addr_to_bech32(hex)
    Encoding->>Test: return Addr (inj1...)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • src/multi_test/address_generator.rs: Cryptographic address generation with Secp256k1 and keccak256—verify correctness of key derivation, hashing, and bech32 encoding; confirm both AddressGenerator implementations handle trait contract properly
  • src/multi_test/chain_mock.rs: Substantial mock infrastructure with custom module handlers, response/assertion containers, and stateful caching—verify Module trait implementation logic, response/assertion execution, and state consistency across execute/query paths
  • src/test_tube/exchange.rs: Most extensive file with 20+ public functions involving market launches, order creation, price scaling, and governance; verify numeric scaling logic, market ID retrieval, and integration with test framework APIs
  • src/utils.rs: Multiple numeric conversion and scaling functions—verify FPDecimal precision handling, decimal exponent transformations, and spot/perp market scaling calculations
  • Cross-module consistency: Confirm mock constants, denomination values, and decimal configurations are consistent across mocks.rs, utils.rs, and test utilities

Poem

🐰 A testing warren springs to life, complete,
With mocks and chains and utils so neat,
Address generators hop through crypto's dance,
While test tubes brew the on-chain trance,
Exchange and oracle harmonize the beat!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.19% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: init repo' accurately reflects the main objective of initializing the repository with foundational testing utilities, mocks, and module structure for the injective-testing crate.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/init-repo

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (7)
.gitignore (1)

1-2: Good foundation for repository initialization.

The basic .gitignore correctly excludes Rust build outputs and JetBrains IDE configuration. For a library crate, this covers the essential patterns.

Optional: Consider expanding .gitignore for broader tooling support.

If the team uses multiple editors or platforms, you may want to add patterns for:

  • .DS_Store (macOS)
  • .vscode/ (Visual Studio Code)
  • *.swp, *.swo (Vim)
  • *.iml (IntelliJ project files)

These additions would make the repository more inclusive but aren't critical for the initial setup.

src/test_tube/utils.rs (1)

3-19: Consider checking existence of the fallback path.

The function checks whether target and arch_target paths exist (lines 12, 14), but returns the fallback path (line 17) without verification. This means wasm_file may return a non-existent path, causing store_code to panic later when calling std::fs::read (line 22).

For test utilities, this may be acceptable behavior, but consider either:

  1. Adding an existence check for the fallback path and returning an error if none exist
  2. Documenting that this function may return a non-existent path
src/multi_test/chain_mock.rs (3)

17-20: Consider removing unused enum.

The StargateT enum is defined but never used in this file. If it's intended for future use or external consumption, consider documenting its purpose or adding a #[allow(dead_code)] attribute.


73-78: Consider handling serialization errors more gracefully.

Both with_ok_response methods use .unwrap() on to_json_binary(), which could panic if serialization fails. Consider using .expect() with a descriptive message to aid debugging when payload serialization fails.

Apply this pattern to both methods:

-    response: Some(Ok(Some(to_json_binary(payload).unwrap()))),
+    response: Some(Ok(Some(to_json_binary(payload).expect("Failed to serialize payload")))),

Also applies to: 98-102


341-345: Simplify the binary copy implementation.

The manual copying with clone_from_slice is unnecessary since Binary implements Clone. The current implementation also allocates a zero-filled vector that is immediately overwritten.

Apply this diff to simplify:

 fn copy_binary(binary: &Binary) -> Binary {
-    let mut c: Vec<u8> = vec![0; binary.to_vec().len()];
-    c.clone_from_slice(binary);
-    Binary::new(c)
+    binary.clone()
 }
src/test_tube/exchange.rs (2)

36-96: Consider extracting the governance module address as a constant.

Line 48 hardcodes the governance module address with a comment noting it could change. Consider extracting this as a module-level constant to make it easier to update and reuse across test helpers.

Example:

const GOVERNANCE_MODULE_ADDRESS: &str = "inj10d07y265gmmuvt4z0w9aw880jnsr700jstypyt";

866-887: Remove unnecessary divisions by one.

Lines 876 and 884 divide by Uint128::one(), which has no effect. These operations are unnecessary and should be removed.

Apply this diff:

-    let total_balance = Uint128::from_str(&trade_deposits_during.deposits[&denom].total_balance)
-    .unwrap_or(Uint128::zero()) // Use zero if the result is an Err
-    / Uint128::one();
+    let total_balance = Uint128::from_str(&trade_deposits_during.deposits[&denom].total_balance)
+        .unwrap_or(Uint128::zero());
 
     let effective_position = exchange
         .query_subaccount_effective_position_in_market(&QuerySubaccountEffectivePositionInMarketRequest { market_id, subaccount_id })
         .unwrap();
 
     let effective_margin = effective_position.state.as_ref().map_or(Uint128::zero(), |state| {
         Uint128::from_str(&state.effective_margin).unwrap_or(Uint128::zero())
-    }) / Uint128::one();
+    });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef416d5 and 75c8899.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • .gitignore (1 hunks)
  • CHANGELOG.md (1 hunks)
  • Cargo.toml (1 hunks)
  • src/lib.rs (1 hunks)
  • src/mocks.rs (1 hunks)
  • src/multi_test/address_generator.rs (1 hunks)
  • src/multi_test/chain_mock.rs (1 hunks)
  • src/multi_test/mod.rs (1 hunks)
  • src/test_tube/authz.rs (1 hunks)
  • src/test_tube/bank.rs (1 hunks)
  • src/test_tube/exchange.rs (1 hunks)
  • src/test_tube/insurance.rs (1 hunks)
  • src/test_tube/mod.rs (1 hunks)
  • src/test_tube/oracle.rs (1 hunks)
  • src/test_tube/utils.rs (1 hunks)
  • src/utils.rs (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
src/mocks.rs (1)
src/utils.rs (1)
  • human_to_dec (30-32)
src/test_tube/insurance.rs (1)
src/utils.rs (1)
  • human_to_dec (30-32)
src/multi_test/chain_mock.rs (1)
src/multi_test/address_generator.rs (1)
  • default (46-50)
src/test_tube/exchange.rs (1)
src/utils.rs (4)
  • dec_to_proto (26-28)
  • scale_price_quantity_perp_market (64-75)
  • scale_price_quantity_spot_market (54-62)
  • str_coin (48-52)
🔇 Additional comments (10)
src/multi_test/mod.rs (1)

1-2: LGTM!

Clean module structure exposing the multi-test infrastructure.

src/test_tube/mod.rs (1)

1-6: LGTM!

Well-organized module structure for test-tube utilities covering authorization, banking, exchange, insurance, oracle, and general utilities.

src/lib.rs (1)

1-4: LGTM!

Clear and concise crate root that exposes the four main module categories: mocks, multi_test, test_tube, and utils.

src/test_tube/insurance.rs (1)

11-40: LGTM!

The insurance fund launch helper provides a clean interface for test setup. The use of .unwrap() is appropriate for test utilities where panics on failure are acceptable. The fixed initial deposit amount and -1 expiry value are reasonable defaults for testing scenarios.

src/test_tube/bank.rs (2)

11-24: LGTM!

The send helper provides a clean interface for bank transfers in tests. The use of .unwrap() is appropriate for test utilities.


26-33: LGTM!

The query_balance helper correctly handles the optional balance response, defaulting to zero when no balance exists. This is a sensible default for test scenarios.

src/test_tube/utils.rs (1)

21-24: LGTM!

The store_code helper provides a convenient wrapper for loading and storing WASM code. The use of .unwrap() is acceptable for test utilities where panics on failure provide clear error messages.

Cargo.toml (1)

19-19: Upgrade to a maintained rand version for better maintainability.

The rand crate version 0.4.6 is from 2017 and significantly outdated; the current stable version is 0.9.2 (released 2025). While rand 0.4.6 itself has no direct RustSec advisory, rand_core versions 0.4.0–0.4.1 and 0.6.0–0.6.1 contained known vulnerabilities. Verification of Cargo.lock confirms your build pulls in safe rand_core versions (0.4.2, 0.6.4), so no active vulnerability is present. However, using such an old, unmaintained version creates a maintenance liability. Upgrade to a maintained rand version (0.9.x) to reduce long-term risk and stay current with security patches.

src/multi_test/chain_mock.rs (1)

184-288: LGTM!

The Module implementation correctly handles execute, query, and sudo operations with proper guards for assertions and responses. The unwrap calls are safely guarded by preceding checks that verify the data exists.

src/test_tube/exchange.rs (1)

1-901: Well-structured test utilities.

The exchange test helpers are comprehensive and well-organized, providing useful abstractions for common testing scenarios like market launches, order execution, and price creation. The consistent naming conventions and parameter patterns make the API intuitive to use.

Comment on lines +8 to +24
## [1.1.1] - 2024-10-02

### Added

- Added a staking denom to the mocks

## [1.1.0] - 2024-08-23

### Changed

- Updated `lib.rs` so that the re-organisation is adhered to

## [1.0.0] - 2024-08-23

### Changed

- Restructure of architecture to improve organisation of helper functions and also to enable re-use with multiple projects
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Historical changelog entries in an "init repo" PR.

The changelog contains versions dating back to August 2024, which seems inconsistent with this being an initialization PR. This suggests the code is being migrated or extracted from another repository rather than created from scratch. Consider clarifying in the PR description whether this is a migration/extraction, or update the changelog to reflect that this is version 1.2.0 as the initial public release.

🤖 Prompt for AI Agents
In CHANGELOG.md around lines 8–24, the file contains historical version entries
(Aug–Oct 2024) that contradict an "init repo" PR; either clarify in the PR
description that this is a migration/extraction from another repository (mention
source repo and date), or edit the changelog so the initial public release is a
single entry (e.g., v1.2.0 or v1.0.0) reflecting the init PR and move prior
history into a separate MIGRATION.md or archive section labeled "Migrated
history" with the original dates; update the changelog header and PR description
accordingly to ensure consistency.

Comment on lines +33 to +57
min_quantity_tick_size: FPDecimal::must_from_str("10000000000000.0"), // 0.00001 @ 18dp
relayer_fee_share_rate: FPDecimal::must_from_str("0.4"),
min_notional: FPDecimal::ZERO,
}
}

// Mock INJ Market
pub fn mock_derivative_market(market_id: &str) -> DerivativeMarket {
DerivativeMarket {
ticker: String::from("INJ:USDT"),
oracle_base: String::from("inj"),
oracle_quote: String::from("usdt"),
oracle_type: OracleType::PriceFeed,
oracle_scale_factor: 0u32,
quote_denom: String::from("usdt"),
market_id: MarketId::unchecked(market_id),
initial_margin_ratio: FPDecimal::must_from_str("0.195"),
maintenance_margin_ratio: FPDecimal::must_from_str("0.05"),
maker_fee_rate: FPDecimal::ZERO,
taker_fee_rate: FPDecimal::ZERO,
isPerpetual: true,
status: MarketStatus::Active,
min_price_tick_size: FPDecimal::must_from_str("1000.0"), // 0.001
min_quantity_tick_size: FPDecimal::must_from_str("0.001"), // 0.001
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix the tick size scaling constants.

FPDecimal::must_from_str already takes a human-readable decimal. Feeding it "10000000000000.0" (Line 33) or "1000.0" (Line 55) makes the mock markets report astronomically large tick sizes instead of the intended 0.00001 and 0.001. Any tests depending on these helpers will behave incorrectly (orders will fail validation because of the exaggerated ticks). Please feed the actual human values and let FPDecimal manage the fixed-point scaling.

-        min_quantity_tick_size: FPDecimal::must_from_str("10000000000000.0"), // 0.00001 @ 18dp
+        min_quantity_tick_size: FPDecimal::must_from_str("0.00001"), // 0.00001 @ 18dp
...
-        min_price_tick_size: FPDecimal::must_from_str("1000.0"),   // 0.001
+        min_price_tick_size: FPDecimal::must_from_str("0.001"),   // 0.001
📝 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
min_quantity_tick_size: FPDecimal::must_from_str("10000000000000.0"), // 0.00001 @ 18dp
relayer_fee_share_rate: FPDecimal::must_from_str("0.4"),
min_notional: FPDecimal::ZERO,
}
}
// Mock INJ Market
pub fn mock_derivative_market(market_id: &str) -> DerivativeMarket {
DerivativeMarket {
ticker: String::from("INJ:USDT"),
oracle_base: String::from("inj"),
oracle_quote: String::from("usdt"),
oracle_type: OracleType::PriceFeed,
oracle_scale_factor: 0u32,
quote_denom: String::from("usdt"),
market_id: MarketId::unchecked(market_id),
initial_margin_ratio: FPDecimal::must_from_str("0.195"),
maintenance_margin_ratio: FPDecimal::must_from_str("0.05"),
maker_fee_rate: FPDecimal::ZERO,
taker_fee_rate: FPDecimal::ZERO,
isPerpetual: true,
status: MarketStatus::Active,
min_price_tick_size: FPDecimal::must_from_str("1000.0"), // 0.001
min_quantity_tick_size: FPDecimal::must_from_str("0.001"), // 0.001
}
min_quantity_tick_size: FPDecimal::must_from_str("0.00001"), // 0.00001 @ 18dp
relayer_fee_share_rate: FPDecimal::must_from_str("0.4"),
min_notional: FPDecimal::ZERO,
}
}
// Mock INJ Market
pub fn mock_derivative_market(market_id: &str) -> DerivativeMarket {
DerivativeMarket {
ticker: String::from("INJ:USDT"),
oracle_base: String::from("inj"),
oracle_quote: String::from("usdt"),
oracle_type: OracleType::PriceFeed,
oracle_scale_factor: 0u32,
quote_denom: String::from("usdt"),
market_id: MarketId::unchecked(market_id),
initial_margin_ratio: FPDecimal::must_from_str("0.195"),
maintenance_margin_ratio: FPDecimal::must_from_str("0.05"),
maker_fee_rate: FPDecimal::ZERO,
taker_fee_rate: FPDecimal::ZERO,
isPerpetual: true,
status: MarketStatus::Active,
min_price_tick_size: FPDecimal::must_from_str("0.001"), // 0.001
min_quantity_tick_size: FPDecimal::must_from_str("0.001"), // 0.001
}
🤖 Prompt for AI Agents
In src/mocks.rs around lines 33 to 57, the tick-size constants are passed to
FPDecimal::must_from_str as already-scaled integers ("10000000000000.0" and
"1000.0") causing huge tick sizes; change those two calls to use the actual
human-readable decimals ("0.00001" for the first min_quantity_tick_size and
"0.001" for min_price_tick_size / min_quantity_tick_size as appropriate) so
FPDecimal handles the fixed-point scaling correctly.

Comment on lines +528 to +547
pub fn launch_spot_market_atom(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount, ticker: String) -> String {
exchange
.instant_spot_market_launch_v2(
v2::MsgInstantSpotMarketLaunch {
sender: signer.address(),
ticker: "ATOM/USDT".to_owned(),
base_denom: MOCK_ATOM_DENOM.to_owned(),
quote_denom: MOCK_QUOTE_DENOM.to_owned(),
min_price_tick_size: dec_to_proto(FPDecimal::must_from_str("0.000010000000000000")),
min_quantity_tick_size: dec_to_proto(FPDecimal::must_from_str("100000")),
min_notional: dec_to_proto(FPDecimal::must_from_str("1")),
base_decimals: MOCK_ATOM_DECIMALS as u32,
quote_decimals: MOCK_QUOTE_DECIMALS as u32,
},
signer,
)
.unwrap();

get_spot_market_id(exchange, ticker)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix ticker parameter usage inconsistency.

The function accepts a ticker parameter but hardcodes "ATOM/USDT" when launching the market (Line 533), then attempts to retrieve the market using the provided ticker parameter (Line 546). This inconsistency will cause the function to fail when ticker != "ATOM/USDT".

Apply this diff to use the ticker parameter consistently:

         v2::MsgInstantSpotMarketLaunch {
             sender: signer.address(),
-            ticker: "ATOM/USDT".to_owned(),
+            ticker: ticker.clone(),
             base_denom: MOCK_ATOM_DENOM.to_owned(),
📝 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
pub fn launch_spot_market_atom(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount, ticker: String) -> String {
exchange
.instant_spot_market_launch_v2(
v2::MsgInstantSpotMarketLaunch {
sender: signer.address(),
ticker: "ATOM/USDT".to_owned(),
base_denom: MOCK_ATOM_DENOM.to_owned(),
quote_denom: MOCK_QUOTE_DENOM.to_owned(),
min_price_tick_size: dec_to_proto(FPDecimal::must_from_str("0.000010000000000000")),
min_quantity_tick_size: dec_to_proto(FPDecimal::must_from_str("100000")),
min_notional: dec_to_proto(FPDecimal::must_from_str("1")),
base_decimals: MOCK_ATOM_DECIMALS as u32,
quote_decimals: MOCK_QUOTE_DECIMALS as u32,
},
signer,
)
.unwrap();
get_spot_market_id(exchange, ticker)
}
pub fn launch_spot_market_atom(exchange: &Exchange<InjectiveTestApp>, signer: &SigningAccount, ticker: String) -> String {
exchange
.instant_spot_market_launch_v2(
v2::MsgInstantSpotMarketLaunch {
sender: signer.address(),
ticker: ticker.clone(),
base_denom: MOCK_ATOM_DENOM.to_owned(),
quote_denom: MOCK_QUOTE_DENOM.to_owned(),
min_price_tick_size: dec_to_proto(FPDecimal::must_from_str("0.000010000000000000")),
min_quantity_tick_size: dec_to_proto(FPDecimal::must_from_str("100000")),
min_notional: dec_to_proto(FPDecimal::must_from_str("1")),
base_decimals: MOCK_ATOM_DECIMALS as u32,
quote_decimals: MOCK_QUOTE_DECIMALS as u32,
},
signer,
)
.unwrap();
get_spot_market_id(exchange, ticker)
}
🤖 Prompt for AI Agents
In src/test_tube/exchange.rs around lines 528 to 547, the
launch_spot_market_atom function takes a ticker parameter but hardcodes
"ATOM/USDT" when building v2::MsgInstantSpotMarketLaunch (line ~533), causing a
mismatch with the later get_spot_market_id(exchange, ticker) call; replace the
hardcoded string with the provided ticker (e.g., use ticker.clone() or
ticker.to_owned() for the MsgInstantSpotMarketLaunch.ticker field) so the same
ticker value is used for both launching the market and retrieving its ID.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants