Skip to main content
Use this runbook when you need to prove an RFQ integration works end to end on testnet. Complete the checks in order. Do not continue past a failed check; downstream failures usually become noisier versions of the same setup issue. The commands assume the injective-rfq-toolkit reference client. That repo is the ground truth for the Python examples used by these docs.

0. Before you start

This flow is EIP-712 v2 only. Quotes must carry sign_mode="v2" and evm_chain_id=1439 on testnet. TakerStream conditional orders must carry conditional_order_sign_mode="v2" and conditional_order_evm_chain_id=1439. The quote payload uses snake_case fields: chain_id remains the Cosmos chain ID, injective-888; do not put 1439 in quote.chain_id.
MakerStream requires an auth challenge response before RFQ requests are forwarded. Configure MakerStreamClient with auth_private_key, auth_evm_chain_id, and auth_contract_address. If the stream connects and pongs but never receives requests, debug the auth challenge first.
You need:

1. Install the reference client

If you already have the repo locally, pull the latest main branch before testing.

2. Configure .env

Create injective-rfq-toolkit/.env:
Load .env before running standalone scripts:
Derive an Injective address from a hex private key:

3. Verify wallet and subaccount balances

Each active wallet needs:
  • INJ for gas in the bank balance.
  • USDC margin in the exchange subaccount used by RFQ settlement.
Bank balance query:
Look for:
  • inj
  • erc20:0x0C382e685bbeeFE5d3d9C29e29E341fEE8E84C5d for testnet USDC
For exchange subaccount balances, use the balance helpers in injective-rfq-toolkit or query the Injective exchange module directly. The maker subaccount must match the registered maker_subaccount_nonce; if list_makers returns null, fund and quote with nonce 0.

4. Verify maker whitelist

Makers must be registered before MakerStream routes RFQ requests to them and before quotes can settle. The raw contract query checks only the first page:
list_makers is paginated. The first page can omit a registered maker if the address sorts after the first 20 results. Prefer the toolkit helper below when checking your own address.
If the maker is not registered, follow Maker whitelist.

5. Verify and grant authz

Check maker grants:
Check taker grants:
Expected grants: If either response is empty or missing a required grant, run the script in Authorization setup. Submit grants sequentially and wait between transactions; parallel grant broadcasts commonly fail with account sequence errors.

6. Run smoke checks

This smoke verifies config loading, indexer reachability, chain reachability, and EIP-712 v2 quote signing. It does not fully prove the MakerStream challenge flow; the full E2E test does that.
If WebSocket connectivity works here but the maker receives no requests in the full test, the likely failure is the MakerStream auth challenge, not basic networking.

7. Run live AcceptQuote settlement

Use the reference script first:
Native gRPC variant:
A successful run proves the full path:
  1. Taker connects to TakerStream.
  2. Maker connects to MakerStream and answers MakerChallenge.
  3. Taker sends an RFQ request and receives the indexer-assigned rfq_id.
  4. Maker waits for that same taker plus rfq_id, signs a quote with EIP-712 v2, and sends it with sign_mode="v2".
  5. Taker collects matching quotes.
  6. Taker submits AcceptQuote.
  7. Maker receives quote or settlement updates.
Success should end with a transaction hash. Open it in testnet explorer and confirm both parties’ derivative positions changed on the selected market. The maker client must include auth fields:
Operational notes:
  • client_id should be a UUID. The indexer assigns the real rfq_id in the ACK.
  • MakerStream can broadcast other takers’ RFQs. Filter by taker address plus the ACK-returned rfq_id.
  • quote_ack means “accepted by the indexer”, not “filled by the taker”.
  • Live quote expiry is intentionally short but must be at least 1500 ms. Longer expiries improve match odds, but increase stale-price exposure.

8. Run TP/SL signed-intent validation

TP/SL exits are taker-signed conditional orders. The taker signs a SignedTakerIntent, submits it through TakerStream, and the TP/SL executor executes AcceptSignedIntent when the trigger condition is satisfied. Before testing:
  • The taker has an open position to close.
  • The executor wallet has INJ for gas if you are testing low-level executor submission.
  • The executor can source a normal RFQ quote when the trigger fires. No maker-specific TP/SL setup is required beyond the standard MakerStream quote loop.
Minimum signing and submission shape:
The helper sets TakerStream wire fields conditional_order_sign_mode="v2" and conditional_order_evm_chain_id when sign_mode and evm_chain_id are passed.

9. Cancel signed intents

Use CancelIntentLane to cancel all active intents for one (taker, market_id, subaccount_nonce) lane.
Use CancelAllIntents only when you need to invalidate every lane for the taker. Future intents must use the incremented epoch or lane_version.

Common blockers

For field-level details, see Protocol reference and Troubleshooting.
Last modified on June 2, 2026