Skip to content

Commit e96f813

Browse files
authored
Merge pull request #18 from InjectiveLabs/codex/port-trading-frontend-skill-lessons
docs: add client-side RFQ gateway guidance
2 parents f2662da + af4a540 commit e96f813

3 files changed

Lines changed: 246 additions & 22 deletions

File tree

skills/injective-rfq-integrations/README.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ add Injective RFQ taker flows:
1010
- user grants scoped AuthZ once through Web3Gateway fee payer
1111
- app sends RFQs with a short quote collection window
1212
- app settles through the RFQ gateway prepared autosign transaction path
13+
- advanced apps can move gateway-style quote collection and selection into the
14+
browser when latency requires it
1315
- position close is the same RFQ path with `margin: "0"`
1416
- TP/SL uses signed RFQ conditional close intents, not orderbook reduce-only
1517
orders
@@ -24,15 +26,17 @@ Read these in order:
2426
1. [SKILL.md](./SKILL.md) - the full implementation playbook.
2527
2. [references/architecture.md](./references/architecture.md) - flow diagrams and state
2628
boundaries.
27-
3. [references/frontend-rfq-flow.md](./references/frontend-rfq-flow.md) - quote windows,
29+
3. [references/client-side-gateway.md](./references/client-side-gateway.md) -
30+
moving gateway/indexer duties into a browser latency path.
31+
4. [references/frontend-rfq-flow.md](./references/frontend-rfq-flow.md) - quote windows,
2832
ACKs, gateway settlement, and manual TakerStream collection.
29-
4. [references/quote-probe-uptime.md](./references/quote-probe-uptime.md) - quote uptime
33+
5. [references/quote-probe-uptime.md](./references/quote-probe-uptime.md) - quote uptime
3034
probes, market discovery, fanout limits, and frontend eligibility signals.
31-
5. [references/authz-and-autosign.md](./references/authz-and-autosign.md) - grants,
35+
6. [references/authz-and-autosign.md](./references/authz-and-autosign.md) - grants,
3236
ephemeral keys, Web3Gateway fee-payer setup.
33-
6. [references/conditional-tpsl.md](./references/conditional-tpsl.md) - RFQ
37+
7. [references/conditional-tpsl.md](./references/conditional-tpsl.md) - RFQ
3438
TP/SL signed intents.
35-
7. [references/troubleshooting.md](./references/troubleshooting.md) - common failures.
39+
8. [references/troubleshooting.md](./references/troubleshooting.md) - common failures.
3640

3741
## Recommended Integration Path
3842

@@ -47,8 +51,9 @@ Most frontend partners should use the RFQ gateway autosign flow:
4751
6. Broadcast via `TxGrpcApi.broadcast`.
4852
7. For TP/SL, sign `SignedTakerIntent` EIP-712 and submit conditional orders.
4953

50-
Use the lower-level TakerStream sample only when you need to manually inspect
51-
ACKs and quotes in the browser.
54+
Use client-side gateway mode only when latency or custom quote selection is
55+
worth owning ACK mapping, quote filtering, sequence readiness, broadcast timing,
56+
optimistic state, and reconciliation in the browser.
5257

5358
## Production Lessons
5459

skills/injective-rfq-integrations/SKILL.md

Lines changed: 67 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@ description: >-
44
Integrate Injective RFQ taker flows into browser apps and operational quote
55
monitors. Use this skill when building, reviewing, or debugging RFQ gateway
66
autosign settlement, Web3Gateway AuthZ setup, manual TakerStream quote
7-
collection, RFQ open/close flows, gateway prefetch, optimistic position
8-
updates, conditional TP/SL intents, quote uptime probes, market-readiness
9-
checks, or mainnet RFQ frontend integrations. Covers mainnet parameters,
10-
canonical decimals, quote windows, signer slots, market discovery,
11-
quote-hit diagnostics, and production RFQ gotchas.
7+
collection, client-side gateway-style quote selection, RFQ open/close flows,
8+
gateway prefetch, optimistic position updates, conditional TP/SL intents,
9+
quote uptime probes, market-readiness checks, or mainnet RFQ frontend
10+
integrations. Covers mainnet parameters, canonical decimals, quote windows,
11+
signer slots, market discovery, quote-hit diagnostics, and production RFQ
12+
gotchas.
1213
license: MIT
1314
metadata:
1415
author: ck
@@ -18,9 +19,9 @@ metadata:
1819
# Injective RFQ Integrations
1920

2021
Use this skill when adding Injective RFQ to a frontend or when building an RFQ
21-
quote monitoring tool. Keep the main flow simple: prefer the RFQ gateway for
22-
trade settlement, and use manual TakerStream only when you need raw quote
23-
diagnostics.
22+
quote monitoring tool. Keep the main flow simple: use the RFQ gateway when you
23+
want managed settlement, and use client-side gateway mode only when the app is
24+
ready to own quote collection, selection, broadcast timing, and reconciliation.
2425

2526
## Mainnet Parameters
2627

@@ -42,7 +43,9 @@ EVM chain ID used in EIP-712 domains, Web3Gateway signatures, and
4243

4344
## Choose The Path
4445

45-
Use the gateway autosign path for production browser trading:
46+
Use the managed gateway autosign path for production browser trading when
47+
latency is acceptable and you want the backend gateway to own quote collection
48+
and settlement assembly:
4649

4750
1. Connect an EVM wallet and derive the user's Injective address.
4851
2. Create a local ephemeral autosign key for that wallet.
@@ -54,12 +57,44 @@ Use the gateway autosign path for production browser trading:
5457
7. Insert both autosign and fee-payer signatures in decoded signer order.
5558
8. Broadcast and poll the tx for final reconciliation.
5659

57-
Use manual TakerStream only for diagnostics, special routing, quote uptime
58-
checks, or latency-sensitive liquidation/arbitrage flows that need maker
59-
allowlists/denylists. It exposes ACK/quote timing and raw maker identity; if
60-
you accept manually, prefetch account sequence and timeout height before quote
61-
collection so the signed accept tx can be broadcast immediately after selecting
62-
a quote.
60+
Use client-side gateway mode when the browser needs lower click-time latency or
61+
special quote selection. In that mode, the app is moving gateway/indexer duties
62+
to the client: TakerStream request ownership, ACK mapping, quote collection,
63+
quote selection, accept transaction preparation, per-wallet serialization,
64+
optimistic state, and chain/indexer reconciliation. Read
65+
[references/client-side-gateway.md](./references/client-side-gateway.md)
66+
before implementing it.
67+
68+
Use manual TakerStream diagnostics when you only need raw quote behavior,
69+
maker identity, or quote uptime checks. Diagnostics should not silently turn
70+
into settlement; settlement requires all client-side gateway responsibilities.
71+
72+
## Client-Side Gateway Mode
73+
74+
Client-side gateway mode is a latency optimization, not just a transport
75+
choice. The gateway behaves like a coordinator/indexer: it opens RFQs, tracks
76+
ACKs, collects maker quotes, chooses executable quotes, assembles settlement,
77+
and reconciles state. A browser implementation must replace those duties
78+
explicitly instead of only opening a WebSocket.
79+
80+
- Keep one active taker stream owner per wallet/session and reconnect
81+
deliberately on wallet changes.
82+
- Track `clientId -> rfqId` ACK replacement. Quotes can arrive before ACK, and
83+
ACK ids may differ from local client ids.
84+
- Use short, bounded collection windows. Start the window from ACK or the first
85+
matching quote, not from arbitrary UI time.
86+
- Sort executable quotes deterministically: lower price is better for long
87+
takers, higher price is better for short takers.
88+
- Validate quote freshness, signed payload fields, maker eligibility, market,
89+
direction, quantity, TTL, chain ids, contract, and worst-price guardrails.
90+
- Prefetch account sequence and timeout height before selection when quote TTLs
91+
are tight. Avoid post-selection RPCs in sub-second paths.
92+
- Serialize accepts per wallet. Parallel accepts can race account sequence even
93+
when they target different markets.
94+
- Treat optimistic position state as provisional until chain/indexer data
95+
confirms it. Roll back cleanly on post-match broadcast or chain failure.
96+
- Keep a managed gateway fallback or recovery path unless the product has
97+
operational monitoring for quote hit rate, maker failures, and stuck state.
6398

6499
## Production Rules
65100

@@ -131,6 +166,21 @@ of user-facing states and serialize trade submission:
131166
of the grid. Filtering can resize the target card and make the trading form
132167
feel unstable.
133168

169+
## Prequote Price Semantics
170+
171+
Separate display prices from RFQ guardrails:
172+
173+
- Button prices should show the best live maker quote when available.
174+
- Fallback display prices can use index price plus or minus the user's
175+
slippage setting, but label them as estimates.
176+
- Prequote RFQ `worstPrice` does not have to equal user slippage. A client-side
177+
gateway can use tighter RFQ prequote tiers for quote discovery, then escalate
178+
after misses.
179+
- User slippage still belongs in final submit guardrails and can affect sizing
180+
indirectly when quantity is derived from quote notional.
181+
- Worst price is a guardrail, not an expected execution price. Seeing better
182+
maker quotes than the guardrail is normal.
183+
134184
## RFQ Input Rules
135185

136186
For open requests, derive quantity from stake, leverage, and mark price:
@@ -258,6 +308,8 @@ editing or canceling a lane, re-query before signing fresh intents.
258308

259309
## References
260310

311+
- [references/client-side-gateway.md](./references/client-side-gateway.md): moving
312+
gateway/indexer duties into a browser latency path.
261313
- [references/frontend-rfq-flow.md](./references/frontend-rfq-flow.md): gateway vs manual
262314
TakerStream, quote filters, and signer rules.
263315
- [references/authz-and-autosign.md](./references/authz-and-autosign.md): Web3Gateway
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Client-Side Gateway Mode
2+
3+
Use this reference when a browser app moves RFQ gateway/indexer duties into the
4+
client to reduce click-time latency. Keep the guidance generic: do not depend
5+
on private app routes, private maker lists, or project-specific flags.
6+
7+
## Mental Model
8+
9+
The gateway is not only a transaction helper. It behaves like a short-lived RFQ
10+
coordinator:
11+
12+
- opens RFQ requests
13+
- maps local client ids to acknowledged RFQ ids
14+
- collects signed maker quotes
15+
- filters invalid or stale quotes
16+
- selects executable quotes
17+
- prepares or signs settlement context
18+
- broadcasts quickly enough for quote TTLs
19+
- reconciles selected quotes against chain and indexer state
20+
21+
Client-side gateway mode is safe only when the frontend owns those same duties.
22+
Opening a TakerStream and displaying quotes is not enough.
23+
24+
## When To Use It
25+
26+
Use client-side gateway mode for:
27+
28+
- latency-sensitive browser trading where managed gateway prepare is too slow
29+
- maker-routed flows that need explicit allowlists, denylists, or selection
30+
policy
31+
- products that need immediate optimistic fills from selected quotes
32+
- operational experiments where quote ACK timing and maker response timing are
33+
part of the product signal
34+
35+
Prefer the managed RFQ gateway when:
36+
37+
- the product does not need custom quote selection
38+
- the app cannot own account sequence and timeout-height readiness
39+
- monitoring cannot detect quote-hit drops, maker failures, or reconciliation
40+
drift
41+
- the team wants backend-owned transaction assembly and fee-payer behavior
42+
43+
## Request Lifecycle
44+
45+
1. Build canonical RFQ input from market metadata, quantity, margin, direction,
46+
and worst-price guardrail.
47+
2. Attach a unique `clientId` for local tracking.
48+
3. Connect one taker stream per wallet/session.
49+
4. Send the prequote or firm request.
50+
5. Track the ACK. Replace local `clientId` with acknowledged `rfqId` when the
51+
stream returns one.
52+
6. Accept quotes for both the original `clientId` and acknowledged `rfqId`
53+
during the transition because quotes can arrive before ACK.
54+
7. Start the quote collection window on ACK or first matching quote.
55+
8. Filter quotes before sorting.
56+
9. Select enough quotes to fill the requested quantity.
57+
10. Broadcast without post-selection RPCs when quote TTLs are tight.
58+
11. Emit optimistic state only after quote selection or match, then reconcile
59+
against chain/indexer state.
60+
61+
## Quote Validation Checklist
62+
63+
Reject a quote unless all required fields match the active request:
64+
65+
- signature is present
66+
- maker address is present
67+
- taker address matches the active wallet/session
68+
- market id matches
69+
- direction matches
70+
- RFQ id or client id matches the active request
71+
- Cosmos chain id is `injective-1`
72+
- EVM chain id, when present, is `1776`
73+
- contract address is the canonical RFQ contract
74+
- quantity is positive and can fill the requested amount after aggregation
75+
- price is inside the worst-price guardrail
76+
- expiry leaves enough TTL for broadcast and inclusion
77+
- maker is allowed by the current routing policy
78+
79+
Sort valid quotes deterministically:
80+
81+
- long taker: lower price first
82+
- short taker: higher price first
83+
- equal price: preserve stable ordering or use explicit secondary criteria such
84+
as quantity or TTL
85+
86+
## Price And Slippage Semantics
87+
88+
Keep these concepts separate:
89+
90+
- **display quote**: best current maker quote shown in the UI
91+
- **fallback display estimate**: index price plus or minus user slippage when no
92+
maker quote is present
93+
- **prequote worst price**: quote-discovery guardrail sent to makers
94+
- **final submit worst price**: user-facing execution guardrail
95+
96+
Do not assume prequote worst price equals user slippage. A latency-focused app
97+
can start prequote discovery with tighter RFQ-specific tiers, then widen after
98+
misses. User slippage still belongs in final submit validation and can affect
99+
derived sizing when the user enters a quote notional instead of a base
100+
quantity.
101+
102+
## Sequence, Timeout, And TTL
103+
104+
For manual accept paths, quote TTL can be shorter than the time needed to fetch
105+
account state after selection. Prepare the broadcast path before collecting:
106+
107+
- account number
108+
- sequence
109+
- timeout height or timeout timestamp
110+
- gas limit
111+
- fee payer or broadcaster context
112+
- signer order and pubkey normalization
113+
114+
If quote TTLs are sub-second or low-second, avoid fetching sequence or block
115+
height after quote selection. Select, sign, and broadcast immediately.
116+
117+
## State And Concurrency
118+
119+
Serialize firm accepts per wallet. Per-market locks are not enough because two
120+
parallel accepts can consume or invalidate the same account sequence.
121+
122+
Track active state explicitly:
123+
124+
- stream connection generation
125+
- latest request ids by market and direction
126+
- in-flight firm accept id
127+
- selected quote ids
128+
- optimistic fills
129+
- rollback timeout
130+
- reconciliation status
131+
132+
Optimistic UI should update from selected or matched quote data, not requested
133+
input alone. Clear provisional state on real indexer insert/update/delete,
134+
explicit rollback, account reset, or expiry.
135+
136+
## Portability Pattern
137+
138+
Before moving any gateway/indexer behavior into a client, write down what the
139+
gateway currently owns and split it into three buckets:
140+
141+
- protocol correctness: signing bytes, signer order, chain ids, decimal
142+
canonicalization, AuthZ grants
143+
- latency path: prequote, quote collection, quote selection, sequence
144+
readiness, broadcast timing
145+
- observability: ACK timing, quote-hit rate, maker failures, stale state, user
146+
copy
147+
148+
Move only the latency-critical pieces client-side first. Keep a managed gateway
149+
or backend fallback until the client path has parity tests and production
150+
metrics.
151+
152+
## Tests To Add
153+
154+
Cover these before calling the client-side gateway production-ready:
155+
156+
- quote before ACK is accepted for the active request
157+
- ACK replacement updates latest RFQ id without dropping matching quotes
158+
- long quotes sort lowest price first
159+
- short quotes sort highest price first
160+
- invalid chain id, market id, direction, contract, maker, stale expiry, and
161+
outside-worst-price quotes are rejected
162+
- collection window closes on timeout and selects enough quantity
163+
- account sequence race is blocked by per-wallet serialization
164+
- selected quote data drives optimistic filled state
165+
- failed post-selection broadcast rolls back optimistic state once
166+
- managed gateway fallback or retry path is reachable when no valid quotes are
167+
collected

0 commit comments

Comments
 (0)