InjectiveLabs/injective-rfq-toolkit:
- Python:
examples/test_settlement.py - TypeScript taker example:
examples/ts-retail/main.ts
Prerequisites
- An Injective wallet (a 32-byte secp256k1 private key)
-
A small amount of INJ for gas on
injective-888(testnet) – testnet faucet - USDC in the wallet’s exchange subaccount to cover your margin
-
Network connectivity to
wss://testnet.rfq.ws.injective.network/injective_rfq_rpc.InjectiveRfqRPC/TakerStream - Python 3.11+ or Node.js 18+
1. Install
Python – clone the toolkit repo and install the library:2. Configure environment
Create a.env file at the repo root:
configs/testnet.yaml) already points at:
| Setting | Value |
|---|---|
| Indexer WebSocket (TakerStream) | wss://testnet.rfq.ws.injective.network/injective_rfq_rpc.InjectiveRfqRPC/TakerStream |
| Indexer HTTP | https://testnet.rfq.injective.network |
| Chain gRPC | testnet-grpc.injective.dev:443 |
| Chain LCD | https://testnet.sentry.lcd.injective.network |
| RFQ contract | inj1qw7jk82hjvf79tnjykux6zacuh9gl0z0wl3ruk |
| Cosmos chain ID | injective-888 |
| EIP-712 chain ID | 1439 |
| INJ/USDC PERP | 0xdc70164d7120529c3cd84278c98df4151210c0447a65a2aab03459cf328de41e |
injective-rfq-toolkit connect without additional stream authentication.
3. Grant authz permissions (once)
Before you can accept any quotes, you must grant the TrueCurrent contract three message types via Injective’sauthz module. See Authorization setup for the full explanation.
Python:
RETAIL_AUTHZ_GRANTS expands to three message types:
/injective.exchange.v2.MsgPrivilegedExecuteContract/injective.exchange.v2.MsgBatchUpdateOrders/cosmos.bank.v1beta1.MsgSend
4. Submit a request
Open a TakerStream WebSocket and send an RFQ request. Python:rfq_id for quote collection and settlement. The request uses a client UUID for correlation; the indexer assigns the RFQ id that makers quote against.
TypeScript:
rfq_id for quote filtering and settlement. Do not use Date.now() as the settlement rfq_id.
See TakerStream for the full request schema, the gRPC-web framing details, and the rfq_id correlation patterns.
5. Collect quotes
Quotes stream in over the same WebSocket. Open a collection window, gather every quote matching your taker stream andrfq_id, and pick the best one (or several – see Accepting quotes for multi-quote aggregation).
Python:
6. Accept onchain
Now submitAcceptQuote to the TrueCurrent contract. This is where the three encoding gotchas bite – read Accepting quotes for the full story.
Python (the ContractClient.accept_quote helper handles encoding for you):
What happens on failure
| Error | Cause | Fix |
|---|---|---|
unauthorized | Missing authz grant | Run step 3 |
quote expired | Quote expiry passed before your tx confirmed | Re-collect quotes, submit faster |
signature verification failed | Passed signature as hex, not base64 | Decode the indexer’s hex and re-encode base64 |
deserialize Expiry | Passed expiry as a raw int | Wrap as {"ts": <ms>} |
insufficient balance | Subaccount margin too low | Deposit more USDC to the exchange subaccount |
maker not whitelisted | Indexer forwarded a stale quote | Skip that quote, try the next best |
Next
- Authorization setup – grant details and revocation
- TakerStream – request schema and quote collection
- Accepting quotes – multi-quote aggregation and every field of the
AcceptQuotemessage - Best practices – slippage, expiry, reconnection, testing

