@xochi/client 0.0.0-stage → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/LICENSE +21 -0
- package/README.md +120 -2
- package/dist/cjs/claim.d.ts +33 -0
- package/dist/cjs/claim.js +44 -0
- package/dist/cjs/fee.d.ts +247 -0
- package/dist/cjs/fee.js +295 -0
- package/dist/cjs/index.d.ts +18 -0
- package/dist/cjs/index.js +33 -0
- package/dist/cjs/machine/claimInfo.d.ts +29 -0
- package/dist/cjs/machine/claimInfo.js +26 -0
- package/dist/cjs/machine/decisions.d.ts +452 -0
- package/dist/cjs/machine/decisions.js +665 -0
- package/dist/cjs/machine/deposit.d.ts +113 -0
- package/dist/cjs/machine/deposit.js +265 -0
- package/dist/cjs/machine/index.d.ts +23 -0
- package/dist/cjs/machine/index.js +53 -0
- package/dist/cjs/machine/machine.d.ts +411 -0
- package/dist/cjs/machine/machine.js +1627 -0
- package/dist/cjs/machine/phase.d.ts +24 -0
- package/dist/cjs/machine/phase.js +45 -0
- package/dist/cjs/machine/quoteChecks.d.ts +41 -0
- package/dist/cjs/machine/quoteChecks.js +82 -0
- package/dist/cjs/machine/receipt.d.ts +151 -0
- package/dist/cjs/machine/receipt.js +69 -0
- package/dist/cjs/machine/recipientEcho.d.ts +16 -0
- package/dist/cjs/machine/recipientEcho.js +27 -0
- package/dist/cjs/machine/solverPin.d.ts +110 -0
- package/dist/cjs/machine/solverPin.js +214 -0
- package/dist/cjs/machine/state.d.ts +167 -0
- package/dist/cjs/machine/state.js +31 -0
- package/dist/cjs/machine/transition.d.ts +15 -0
- package/dist/cjs/machine/transition.js +20 -0
- package/dist/cjs/machine/validateRequest.d.ts +15 -0
- package/dist/cjs/machine/validateRequest.js +127 -0
- package/dist/cjs/machine/view.d.ts +3 -0
- package/dist/cjs/machine/view.js +74 -0
- package/dist/cjs/machine/wire.d.ts +527 -0
- package/dist/cjs/machine/wire.js +280 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/shared/api.d.ts +9 -0
- package/dist/cjs/shared/api.js +5 -0
- package/dist/cjs/shared/chains.d.ts +243 -0
- package/dist/cjs/shared/chains.js +250 -0
- package/dist/cjs/shared/eip712.d.ts +44 -0
- package/dist/cjs/shared/eip712.js +64 -0
- package/dist/cjs/shared/index.d.ts +16 -0
- package/dist/cjs/shared/index.js +32 -0
- package/dist/cjs/shared/intentStream.d.ts +74 -0
- package/dist/cjs/shared/intentStream.js +59 -0
- package/dist/cjs/shared/intents.d.ts +88 -0
- package/dist/cjs/shared/intents.js +227 -0
- package/dist/cjs/shared/schemas.d.ts +928 -0
- package/dist/cjs/shared/schemas.js +524 -0
- package/dist/cjs/shared/shieldedPreview.d.ts +841 -0
- package/dist/cjs/shared/shieldedPreview.js +128 -0
- package/dist/cjs/shared/stealth.d.ts +53 -0
- package/dist/cjs/shared/stealth.js +68 -0
- package/dist/cjs/shared/trading.d.ts +153 -0
- package/dist/cjs/shared/trading.js +185 -0
- package/dist/cjs/shared/types.d.ts +37 -0
- package/dist/cjs/shared/types.js +7 -0
- package/dist/cjs/shared/validators.d.ts +30 -0
- package/dist/cjs/shared/validators.js +79 -0
- package/dist/cjs/transport/client.d.ts +234 -0
- package/dist/cjs/transport/client.js +1456 -0
- package/dist/esm/claim.d.ts +33 -0
- package/dist/esm/claim.js +41 -0
- package/dist/esm/fee.d.ts +247 -0
- package/dist/esm/fee.js +285 -0
- package/dist/esm/index.d.ts +18 -0
- package/dist/esm/index.js +17 -0
- package/dist/esm/machine/claimInfo.d.ts +29 -0
- package/dist/esm/machine/claimInfo.js +23 -0
- package/dist/esm/machine/decisions.d.ts +452 -0
- package/dist/esm/machine/decisions.js +640 -0
- package/dist/esm/machine/deposit.d.ts +113 -0
- package/dist/esm/machine/deposit.js +260 -0
- package/dist/esm/machine/index.d.ts +23 -0
- package/dist/esm/machine/index.js +23 -0
- package/dist/esm/machine/machine.d.ts +411 -0
- package/dist/esm/machine/machine.js +1621 -0
- package/dist/esm/machine/phase.d.ts +24 -0
- package/dist/esm/machine/phase.js +42 -0
- package/dist/esm/machine/quoteChecks.d.ts +41 -0
- package/dist/esm/machine/quoteChecks.js +78 -0
- package/dist/esm/machine/receipt.d.ts +151 -0
- package/dist/esm/machine/receipt.js +64 -0
- package/dist/esm/machine/recipientEcho.d.ts +16 -0
- package/dist/esm/machine/recipientEcho.js +24 -0
- package/dist/esm/machine/solverPin.d.ts +110 -0
- package/dist/esm/machine/solverPin.js +210 -0
- package/dist/esm/machine/state.d.ts +167 -0
- package/dist/esm/machine/state.js +28 -0
- package/dist/esm/machine/transition.d.ts +15 -0
- package/dist/esm/machine/transition.js +17 -0
- package/dist/esm/machine/validateRequest.d.ts +15 -0
- package/dist/esm/machine/validateRequest.js +123 -0
- package/dist/esm/machine/view.d.ts +3 -0
- package/dist/esm/machine/view.js +71 -0
- package/dist/esm/machine/wire.d.ts +527 -0
- package/dist/esm/machine/wire.js +266 -0
- package/dist/esm/shared/api.d.ts +9 -0
- package/dist/esm/shared/api.js +4 -0
- package/dist/esm/shared/chains.d.ts +243 -0
- package/dist/esm/shared/chains.js +236 -0
- package/dist/esm/shared/eip712.d.ts +44 -0
- package/dist/esm/shared/eip712.js +61 -0
- package/dist/esm/shared/index.d.ts +16 -0
- package/dist/esm/shared/index.js +16 -0
- package/dist/esm/shared/intentStream.d.ts +74 -0
- package/dist/esm/shared/intentStream.js +55 -0
- package/dist/esm/shared/intents.d.ts +88 -0
- package/dist/esm/shared/intents.js +213 -0
- package/dist/esm/shared/schemas.d.ts +928 -0
- package/dist/esm/shared/schemas.js +521 -0
- package/dist/esm/shared/shieldedPreview.d.ts +841 -0
- package/dist/esm/shared/shieldedPreview.js +124 -0
- package/dist/esm/shared/stealth.d.ts +53 -0
- package/dist/esm/shared/stealth.js +64 -0
- package/dist/esm/shared/trading.d.ts +153 -0
- package/dist/esm/shared/trading.js +182 -0
- package/dist/esm/shared/types.d.ts +37 -0
- package/dist/esm/shared/types.js +6 -0
- package/dist/esm/shared/validators.d.ts +30 -0
- package/dist/esm/shared/validators.js +74 -0
- package/dist/esm/transport/client.d.ts +234 -0
- package/dist/esm/transport/client.js +1447 -0
- package/package.json +61 -4
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire shapes and decoders.
|
|
3
|
+
*
|
|
4
|
+
* The worker speaks the canonical snake_case contract (`QuoteResponseSchema` in
|
|
5
|
+
* `@xochi/shared`, `public/openapi.yaml`); everything past this module is
|
|
6
|
+
* camelCase. Decoding happens HERE, once, so the trade widget and `@xochi/sdk`
|
|
7
|
+
* read a quote, an execute result and an intent status through the same code
|
|
8
|
+
* rather than through two mappers that drift.
|
|
9
|
+
*/
|
|
10
|
+
import type { ChainId, SelectableChainId, SettlementType, DestinationType, FeeBreakdown, FeeDenomination, Eip712TypedData, SettlementOption, QuoteResponseWire, ExecuteResponseWire, IntentStatus } from "../shared/index.js";
|
|
11
|
+
/** Full destination specification */
|
|
12
|
+
export interface IntentDestination {
|
|
13
|
+
type: DestinationType;
|
|
14
|
+
chainId?: ChainId;
|
|
15
|
+
shielded: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Recipient address on the destination chain, for a non-EVM settlement (Tron).
|
|
18
|
+
* The user types it; EVM routes settle to the connected wallet and omit it.
|
|
19
|
+
*/
|
|
20
|
+
recipientAddress?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface QuoteRequest {
|
|
23
|
+
wallet?: string;
|
|
24
|
+
/** Ask for pricing only. Preview quotes cannot be signed or executed. */
|
|
25
|
+
preview?: boolean;
|
|
26
|
+
/** Idempotency key for one explicit Tron deposit-route allocation. */
|
|
27
|
+
allocationKey?: string;
|
|
28
|
+
fromChainId: SelectableChainId;
|
|
29
|
+
toChainId: SelectableChainId;
|
|
30
|
+
fromToken: string;
|
|
31
|
+
toToken: string;
|
|
32
|
+
fromAmount: string;
|
|
33
|
+
deadline: number;
|
|
34
|
+
slippageBps: number;
|
|
35
|
+
trustScore?: number;
|
|
36
|
+
settlementPreference: SettlementType;
|
|
37
|
+
/** Recipient on the destination chain (non-EVM routes); omit for EVM. */
|
|
38
|
+
recipientAddress?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Refund destination on the ORIGIN chain, for a deposit-route origin (Tron).
|
|
41
|
+
* Omit for EVM origins, where a refund goes back to the connected wallet.
|
|
42
|
+
* See xochi#358: without it a refund pays the on-chain deposit sender, which
|
|
43
|
+
* strands funds when the deposit came from an exchange.
|
|
44
|
+
*/
|
|
45
|
+
refundAddress?: string;
|
|
46
|
+
destination?: IntentDestination;
|
|
47
|
+
/** Stealth meta-address for stealth settlements */
|
|
48
|
+
stealthMetaAddress?: {
|
|
49
|
+
spendingPubKey: string;
|
|
50
|
+
viewingPubKey: string;
|
|
51
|
+
chainId: ChainId;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** Stealth settlement claim info (factory + salt for counterfactual SimpleAccount) */
|
|
55
|
+
export interface ClaimInfo {
|
|
56
|
+
factoryAddress: string;
|
|
57
|
+
salt: number;
|
|
58
|
+
}
|
|
59
|
+
export interface QuoteResponse {
|
|
60
|
+
success: boolean;
|
|
61
|
+
intentId: string;
|
|
62
|
+
quoteId: string;
|
|
63
|
+
canSolve: boolean;
|
|
64
|
+
/** True when this is a non-persisted, non-executable public price preview. */
|
|
65
|
+
preview?: boolean;
|
|
66
|
+
toAmount: string;
|
|
67
|
+
minToAmount: string;
|
|
68
|
+
xochiFee: string;
|
|
69
|
+
xochiFeeRate: string;
|
|
70
|
+
/**
|
|
71
|
+
* All-in cost of this quote in basis points, measured server-side by the same
|
|
72
|
+
* fixed-cost guard that refuses an uneconomical order. Distinct from
|
|
73
|
+
* `xochiFeeRate`, which is the flat schedule rate: this one moves with route
|
|
74
|
+
* and size. Absent when the guard could not run -- render nothing, not zero.
|
|
75
|
+
*/
|
|
76
|
+
costBps?: number;
|
|
77
|
+
/** Itemized layer split; absent until the worker/Riddler emit it. */
|
|
78
|
+
feeBreakdown?: FeeBreakdown;
|
|
79
|
+
/**
|
|
80
|
+
* Which token `feeBreakdown`'s layer AMOUNTS are measured in: `"origin"` =
|
|
81
|
+
* from-token base units, `"destination"` = to-token base units.
|
|
82
|
+
*
|
|
83
|
+
* On the wire so the renderer reads the denomination instead of inferring it
|
|
84
|
+
* from which branch produced the breakdown. Formatting a fee with the wrong
|
|
85
|
+
* token's decimals misstates it by the exchange rate (by 10^12 on an
|
|
86
|
+
* 18-decimal origin), and every live route today is 6 decimals on both sides,
|
|
87
|
+
* so the mistake is invisible until it is not.
|
|
88
|
+
*
|
|
89
|
+
* Absent means UNKNOWN, never a default. The worker emits it whenever it
|
|
90
|
+
* forwards a served breakdown and omits it when there is no breakdown.
|
|
91
|
+
*/
|
|
92
|
+
feeDenomination?: FeeDenomination;
|
|
93
|
+
estimatedGasCost: string;
|
|
94
|
+
/**
|
|
95
|
+
* Subscribe capability for this intent's live status + race stream, served
|
|
96
|
+
* once with the quote. TREAT AS A BEARER TOKEN: possession is the entire
|
|
97
|
+
* authorization and the relay replays its recent buffer to each new
|
|
98
|
+
* subscriber. Never log it and never put it in a shared URL.
|
|
99
|
+
*
|
|
100
|
+
* Absent means no stream (an intent quoted before the field existed), which
|
|
101
|
+
* the client must read as "poll only" rather than substituting the intentId.
|
|
102
|
+
* That substitution is the bug this field exists to prevent: the id is public
|
|
103
|
+
* by construction.
|
|
104
|
+
*/
|
|
105
|
+
streamTopic?: string;
|
|
106
|
+
expiry: string;
|
|
107
|
+
gasless: boolean;
|
|
108
|
+
gaslessFee?: string;
|
|
109
|
+
paymentMethod?: PaymentMethod;
|
|
110
|
+
eip712Data?: Eip712TypedData;
|
|
111
|
+
/**
|
|
112
|
+
* Origin-pull authorization served by the solver. The user signs this in
|
|
113
|
+
* addition to eip712Data; the signature is sent as pullSignature on execute.
|
|
114
|
+
* Present when the route requires origin collection (erc3009 / permit2).
|
|
115
|
+
*/
|
|
116
|
+
pullAuthorization?: Eip712TypedData;
|
|
117
|
+
/**
|
|
118
|
+
* Non-EVM origin (Tron): the per-intent address the user manually sends
|
|
119
|
+
* TRC-20 to. Mutually exclusive with pullAuthorization. Only ever surfaced to
|
|
120
|
+
* the UI after depositAttestation verifies against the pinned signer.
|
|
121
|
+
*/
|
|
122
|
+
depositAddress?: string;
|
|
123
|
+
/** Solver attestation over the deposit binding; verified fail-closed. */
|
|
124
|
+
depositAttestation?: string;
|
|
125
|
+
/** Deposit-acceptance deadline (unix seconds) for a deposit route. */
|
|
126
|
+
depositDeadline?: number;
|
|
127
|
+
/**
|
|
128
|
+
* The RESOLVED settlement type the quote is served under, read from
|
|
129
|
+
* `route.settlement_type`. Distinct from the value REQUESTED: the solver may
|
|
130
|
+
* serve a different one, and the v2 deposit attestation signs the resolved
|
|
131
|
+
* value. Undefined when the solver did not state it, which a deposit route
|
|
132
|
+
* must treat as a refusal rather than assuming "public" -- guessing here would
|
|
133
|
+
* silently diverge from the signed message on every quote.
|
|
134
|
+
*/
|
|
135
|
+
settlementType?: SettlementType;
|
|
136
|
+
/**
|
|
137
|
+
* The served `escrow` envelope, verbatim, when the quote carried the key.
|
|
138
|
+
* Not modelled: it is held only so the `@xochi/signer` checks the machine
|
|
139
|
+
* runs at ingest can see it. This client does not run the escrow binding, so
|
|
140
|
+
* a quote whose `escrow` is anything but absent or `null` is refused before
|
|
141
|
+
* it can reach the wallet.
|
|
142
|
+
*/
|
|
143
|
+
escrow?: unknown;
|
|
144
|
+
/**
|
|
145
|
+
* Echo of the requested destination recipient (non-EVM/Tron routes). The
|
|
146
|
+
* client asserts a solvable quote echoes exactly the address it asked for
|
|
147
|
+
* (fail-closed on mismatch); absent for EVM routes. See #113.
|
|
148
|
+
*/
|
|
149
|
+
recipientAddress?: string;
|
|
150
|
+
settlementOptions: SettlementOption[];
|
|
151
|
+
claimInfo?: ClaimInfo;
|
|
152
|
+
error?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Stable machine key for a declined quote (served beside `error`). Branch on
|
|
155
|
+
* this, never on the prose: the wire contract documents the vocabulary and
|
|
156
|
+
* says an unrecognized value is a non-retryable decline.
|
|
157
|
+
*/
|
|
158
|
+
errorCategory?: string;
|
|
159
|
+
/**
|
|
160
|
+
* Smallest order (USD) that clears this route right now; served on an
|
|
161
|
+
* `amount_too_small` decline. THE number to retry with (it already covers
|
|
162
|
+
* the solver floor and the fixed-cost threshold). Moves with corridor cost,
|
|
163
|
+
* so never cache it.
|
|
164
|
+
*/
|
|
165
|
+
minimumAmountUsd?: number;
|
|
166
|
+
/**
|
|
167
|
+
* The solver's own live floor (USD), for transparency copy only. An order at
|
|
168
|
+
* exactly this figure delivers almost nothing; never offer it as the retry.
|
|
169
|
+
*/
|
|
170
|
+
minFillableUsd?: number;
|
|
171
|
+
destination?: IntentDestination;
|
|
172
|
+
}
|
|
173
|
+
export interface ExecuteRequest {
|
|
174
|
+
intentId: string;
|
|
175
|
+
quoteId: string;
|
|
176
|
+
signature: string;
|
|
177
|
+
nonce: number;
|
|
178
|
+
pullSignature?: string;
|
|
179
|
+
aztecProof?: string;
|
|
180
|
+
}
|
|
181
|
+
export interface ExecuteResponse {
|
|
182
|
+
success: boolean;
|
|
183
|
+
intentId: string;
|
|
184
|
+
status: IntentStatus;
|
|
185
|
+
txHash?: string;
|
|
186
|
+
/** Destination fill hash (cross-chain); usually arrives later via status/WS. */
|
|
187
|
+
receivingTxHash?: string;
|
|
188
|
+
/** Public fill receipt (Riddler #632) + its chain, when a fill resolves inline. */
|
|
189
|
+
settlementTxHash?: string;
|
|
190
|
+
settlementChainId?: ChainId;
|
|
191
|
+
bridgeTxHash?: string;
|
|
192
|
+
/** In-doubt: funds may be in flight but unconfirmed. */
|
|
193
|
+
reconciling?: boolean;
|
|
194
|
+
error?: string;
|
|
195
|
+
/**
|
|
196
|
+
* `NOT_EXECUTED_SUBSTATUS` on a `failed` the Worker wrote knowing nothing
|
|
197
|
+
* moved; the only `failed` the machine offers Retry on after an execute.
|
|
198
|
+
*/
|
|
199
|
+
substatus?: string;
|
|
200
|
+
/** Note commitment for shielded settlements */
|
|
201
|
+
noteCommitment?: string;
|
|
202
|
+
/** Stealth settlement info */
|
|
203
|
+
stealthAddress?: string;
|
|
204
|
+
ephemeralPubKey?: string;
|
|
205
|
+
viewTag?: number;
|
|
206
|
+
/**
|
|
207
|
+
* Per-intent read capability (xochi#563), served once and only by a server
|
|
208
|
+
* that issues it (xochi#565, merged as `0317e84`, once deployed). Keep it
|
|
209
|
+
* with the intent and pass it as `readToken` to `getIntent` /
|
|
210
|
+
* `getIntentStatus`: a stealth intent read without it omits its on-chain
|
|
211
|
+
* legs. A token read of a shielded intent gets only the status-only view, as
|
|
212
|
+
* an anonymous read does (SPEC.md §5.1, `IntentReadOptions`).
|
|
213
|
+
* A bearer secret: never log it or put it in a URL.
|
|
214
|
+
*/
|
|
215
|
+
readToken?: string;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* An execute response as the machine receives it in `ExecuteReplied`: the
|
|
219
|
+
* bearer `readToken` removed (`const { readToken, ...response } = ...`) and
|
|
220
|
+
* kept outside the machine, so no message, model, effect or replay log holds
|
|
221
|
+
* it. The machine derives the fund-safety verdict (#226) from this response
|
|
222
|
+
* itself; a host relays it and never decides it.
|
|
223
|
+
*/
|
|
224
|
+
export type ExecuteReply = Omit<ExecuteResponse, "readToken"> & {
|
|
225
|
+
readToken?: never;
|
|
226
|
+
};
|
|
227
|
+
export type IntentMessageType = "intent_status";
|
|
228
|
+
/**
|
|
229
|
+
* The status update `useIntent` applies. In-app only, never a wire shape: the
|
|
230
|
+
* status poll builds it from `/api/intent/:id/status`, and `mapStatusFrame`
|
|
231
|
+
* builds it from the stream's `IntentStatusFrame` (`@xochi/shared`).
|
|
232
|
+
*/
|
|
233
|
+
export interface IntentWebSocketMessage {
|
|
234
|
+
type: IntentMessageType;
|
|
235
|
+
intentId: string;
|
|
236
|
+
status: IntentStatus;
|
|
237
|
+
txHash?: string;
|
|
238
|
+
/** Destination fill hash (broadcast on cross-chain completion). */
|
|
239
|
+
receivingTxHash?: string;
|
|
240
|
+
/** Public fill receipt (Riddler #632) + its chain, broadcast on completion. */
|
|
241
|
+
settlementTxHash?: string;
|
|
242
|
+
settlementChainId?: ChainId;
|
|
243
|
+
/** In-doubt signal (broadcast when an execute lands in reconcile). */
|
|
244
|
+
reconciling?: boolean;
|
|
245
|
+
/**
|
|
246
|
+
* Riddler's granular fill substatus, verbatim; see IntentState.substatus. On
|
|
247
|
+
* a `failed`, `NOT_EXECUTED_SUBSTATUS` is the Worker's "nothing moved".
|
|
248
|
+
*/
|
|
249
|
+
substatus?: string;
|
|
250
|
+
error?: string;
|
|
251
|
+
/** Machine-readable refund reason code (deposit routes) on a `refunded` status. */
|
|
252
|
+
refundReason?: string;
|
|
253
|
+
timestamp: string;
|
|
254
|
+
}
|
|
255
|
+
/** How the token pull + gas execution is handled */
|
|
256
|
+
export type PaymentMethod = "erc3009" | "permit2" | "pimlico" | "x402" | "mpp" | "approval" | "deposit";
|
|
257
|
+
export declare function isQuoteResponseWire(value: unknown): value is QuoteResponseWire & {
|
|
258
|
+
readonly escrow?: unknown;
|
|
259
|
+
};
|
|
260
|
+
export declare function isExecuteResponseWire(value: unknown): value is ExecuteResponseWire;
|
|
261
|
+
/**
|
|
262
|
+
* Read the resolved settlement type out of the solver's opaque `route` bag.
|
|
263
|
+
*
|
|
264
|
+
* `route` is `z.record(z.string(), z.unknown())` in the contract: a passthrough
|
|
265
|
+
* the worker does not model, so it arrives untyped. Narrow it to the closed
|
|
266
|
+
* settlement vocabulary here rather than casting, and return undefined for
|
|
267
|
+
* anything unrecognised. Callers that need it (the v2 deposit attestation) must
|
|
268
|
+
* treat undefined as a refusal: a wrong guess produces a message that fails to
|
|
269
|
+
* recover, which reads as a solver outage rather than as our bug.
|
|
270
|
+
*/
|
|
271
|
+
export declare function readResolvedSettlementType(route: Record<string, unknown> | undefined): SettlementType | undefined;
|
|
272
|
+
export declare function mapQuoteResponse(w: QuoteResponseWire & {
|
|
273
|
+
readonly escrow?: unknown;
|
|
274
|
+
}): QuoteResponse;
|
|
275
|
+
export declare function mapExecuteResponse(w: ExecuteResponseWire): ExecuteResponse;
|
|
276
|
+
export declare const RACE_MESSAGE_TYPES: readonly ["race_started", "solver_bid", "race_won"];
|
|
277
|
+
export type RaceMessageType = (typeof RACE_MESSAGE_TYPES)[number];
|
|
278
|
+
/**
|
|
279
|
+
* Live race telemetry relayed from Riddler while an intent fills.
|
|
280
|
+
*
|
|
281
|
+
* DISPLAY ONLY. Intent status comes from lifecycle (`status`) frames and the status
|
|
282
|
+
* poll; nothing here may advance a swap or change what the user is told they
|
|
283
|
+
* received. `solver` is a pseudonymous handle, never an operator identity or an
|
|
284
|
+
* address, and `elapsedMs` is the server's clock (the local one is decoration).
|
|
285
|
+
*/
|
|
286
|
+
export interface RaceWebSocketMessage {
|
|
287
|
+
type: RaceMessageType;
|
|
288
|
+
intentId: string;
|
|
289
|
+
solver?: string;
|
|
290
|
+
/** Destination amount this bid delivers (base units, string). */
|
|
291
|
+
amountOut?: string;
|
|
292
|
+
/** Price improvement against the accepted quote, in bps. */
|
|
293
|
+
improvementBps?: number;
|
|
294
|
+
/** Solvers active on this route when the race opened (race_started only). */
|
|
295
|
+
solversActive?: number;
|
|
296
|
+
/** Server-side ms since the race opened. */
|
|
297
|
+
elapsedMs?: number;
|
|
298
|
+
timestamp: string;
|
|
299
|
+
}
|
|
300
|
+
export declare function isRaceWebSocketMessage(value: unknown): value is RaceWebSocketMessage;
|
|
301
|
+
/**
|
|
302
|
+
* Granular origin-pull states the solver may emit that the `IntentStatus`
|
|
303
|
+
* union doesn't model, bucketed into the nearest known state. Unknown/granular
|
|
304
|
+
* strings otherwise reach `phaseFromStatus` (which drops them to the confirm
|
|
305
|
+
* screen) and fall outside the poll's in-flight set (freezing the row mid-flight
|
|
306
|
+
* -- the dead-spinner bug).
|
|
307
|
+
*/
|
|
308
|
+
export declare const GRANULAR_WIRE_STATUS: Readonly<Record<string, IntentStatus>>;
|
|
309
|
+
/**
|
|
310
|
+
* A raw `/status` value, decoded.
|
|
311
|
+
*
|
|
312
|
+
* `mapped` is a status this build models: a union member, or one of Riddler's
|
|
313
|
+
* granular strings bucketed above. `unmapped` is any other string, and it is
|
|
314
|
+
* deliberately NOT a guess at an outcome: it buckets to `executing` so the poll
|
|
315
|
+
* runs on to a real terminal (an unrecognized string must never freeze the row),
|
|
316
|
+
* and the machine shows it as "Still confirming" (reconciling) rather than as a
|
|
317
|
+
* normal in-flight step. It can never decode to `completed`. This is the
|
|
318
|
+
* fail-closed half of the CLAUDE.md "Status-vocabulary sync" rule.
|
|
319
|
+
*
|
|
320
|
+
* `absent` is a body with no status string at all: not a Riddler status, so
|
|
321
|
+
* not a vocabulary signal. It keeps the in-flight bucket and nothing else.
|
|
322
|
+
*/
|
|
323
|
+
export type DecodedWireStatus = {
|
|
324
|
+
kind: "mapped";
|
|
325
|
+
status: IntentStatus;
|
|
326
|
+
} | {
|
|
327
|
+
kind: "unmapped";
|
|
328
|
+
status: "executing";
|
|
329
|
+
raw: string;
|
|
330
|
+
} | {
|
|
331
|
+
kind: "absent";
|
|
332
|
+
status: "executing";
|
|
333
|
+
};
|
|
334
|
+
export declare function decodeWireStatus(raw: unknown): DecodedWireStatus;
|
|
335
|
+
/**
|
|
336
|
+
* The normalized status of an in-flight intent, read from `GET
|
|
337
|
+
* /api/intent/:id/status`.
|
|
338
|
+
*/
|
|
339
|
+
export interface IntentStatusData {
|
|
340
|
+
/**
|
|
341
|
+
* The intent this status is about, echoed by the worker (`intent_id` on every
|
|
342
|
+
* branch of `buildStatusDeliverable`). Carried so a consumer that merges the
|
|
343
|
+
* response into a stored record can check it is merging into the right one;
|
|
344
|
+
* null when an older worker omits it.
|
|
345
|
+
*/
|
|
346
|
+
intentId: string | null;
|
|
347
|
+
status: IntentStatus;
|
|
348
|
+
/**
|
|
349
|
+
* True when the wire status was outside this build's vocabulary and `status`
|
|
350
|
+
* is only the in-flight bucket (`decodeWireStatus`). Absent means mapped.
|
|
351
|
+
*/
|
|
352
|
+
unmapped?: boolean;
|
|
353
|
+
txHash: string | null;
|
|
354
|
+
receivingTxHash: string | null;
|
|
355
|
+
/** Public fill receipt (Riddler #632) + its chain; the receipt CTA keys off these. */
|
|
356
|
+
settlementTxHash: string | null;
|
|
357
|
+
settlementChainId: number | null;
|
|
358
|
+
error: string | null;
|
|
359
|
+
/** Machine-readable refund reason code (deposit routes); null otherwise. */
|
|
360
|
+
refundReason: string | null;
|
|
361
|
+
/**
|
|
362
|
+
* Riddler's granular origin-pull/fill substatus, passed through verbatim
|
|
363
|
+
* (pulling | pulled | filling | filled | refunding | ...), or on a `failed`
|
|
364
|
+
* the Worker wrote knowing nothing moved, `NOT_EXECUTED_SUBSTATUS`. NOT a
|
|
365
|
+
* status: the top-level `status` is what advances the lifecycle.
|
|
366
|
+
*
|
|
367
|
+
* It is read for two things. A `failed` after an execute offers Retry only
|
|
368
|
+
* with `not_executed` (README "Fund safety"). And it tells a user whose
|
|
369
|
+
* destination leg has already landed (`filled`) apart from one still
|
|
370
|
+
* waiting: Riddler can hold an intent at top-level `settling` with
|
|
371
|
+
* `substatus: filled` indefinitely, which is exactly the state a stuck
|
|
372
|
+
* stealth swap sits in (xochi#376): the money is delivered and the app was
|
|
373
|
+
* showing an undifferentiated "settling".
|
|
374
|
+
*/
|
|
375
|
+
substatus: string | null;
|
|
376
|
+
terminal: boolean;
|
|
377
|
+
/**
|
|
378
|
+
* Present (true) when the server withheld the on-chain legs of a stealth or
|
|
379
|
+
* shielded intent from this read (xochi#563; served by xochi#565, merged as
|
|
380
|
+
* `0317e84`, once deployed): the read carried no owner proof. The tx hashes
|
|
381
|
+
* and `settlementChainId` are then null because they were withheld, not
|
|
382
|
+
* because they do not exist, and the server omits `substatus` unless it is
|
|
383
|
+
* `not_executed`. A wallet SIWE session for the intent's wallet reads them,
|
|
384
|
+
* and so does the read token of a stealth intent only: a token read of a
|
|
385
|
+
* shielded intent gets this view too (SPEC.md §5.1).
|
|
386
|
+
*/
|
|
387
|
+
legsWithheld?: true;
|
|
388
|
+
/**
|
|
389
|
+
* Present only with `legsWithheld`: true once the destination fill receipt
|
|
390
|
+
* exists, standing in for the withheld `settlementTxHash`; never true on a
|
|
391
|
+
* terminal failure (`withheldSettlementConfirmed`). The machine shows it
|
|
392
|
+
* exactly as `substatus: "filled"` (delivered); it does not move `status` or
|
|
393
|
+
* `terminal`.
|
|
394
|
+
*/
|
|
395
|
+
settlementConfirmed?: boolean;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Discriminated result of a status poll:
|
|
399
|
+
* - `IntentStatusData` on a 200,
|
|
400
|
+
* - `{ notFound: true }` on a definitive 404 (a definitive absence, NOT a
|
|
401
|
+
* verdict: only a pre-dispatch row may be terminalized on it, see
|
|
402
|
+
* `isSweepablePreDispatch`, and a "not sent yet" intent ends on it as
|
|
403
|
+
* nothing moved once past its finish, see `IntentState.notSent`),
|
|
404
|
+
* - `null` on a transient failure (retry on the next tick).
|
|
405
|
+
*/
|
|
406
|
+
export type IntentStatusResult = IntentStatusData | {
|
|
407
|
+
notFound: true;
|
|
408
|
+
} | null;
|
|
409
|
+
/**
|
|
410
|
+
* Statuses that are settled: no further status polling is needed. Xochi's own
|
|
411
|
+
* lifecycle vocabulary (`IntentStatus`), and the fallback the status decoder
|
|
412
|
+
* uses when the worker omits `terminal`.
|
|
413
|
+
*/
|
|
414
|
+
export declare const TERMINAL_INTENT_STATUSES: Readonly<Partial<Record<IntentStatus, true>>>;
|
|
415
|
+
export declare function isTerminalIntentStatus(status: IntentStatus): boolean;
|
|
416
|
+
/**
|
|
417
|
+
* Whether an anonymous read's `settlement_confirmed` (xochi#563) counts as a
|
|
418
|
+
* delivered fill. Only on a read that withheld the legs (the marker stands in
|
|
419
|
+
* for the withheld receipt), and only when `status` decodes (`decodeWireStatus`)
|
|
420
|
+
* to a status this build models that is not a terminal failure and not part of
|
|
421
|
+
* a refund: never on `refunded` / `failed` / `expired`, on a granular status
|
|
422
|
+
* bucketed to one (`fill_failed`, `refund_failed`), on any `refund*` status
|
|
423
|
+
* (`refunding`, `refund_pending`), or on an unmapped or absent status.
|
|
424
|
+
*/
|
|
425
|
+
export declare function withheldSettlementConfirmed(read: {
|
|
426
|
+
status: unknown;
|
|
427
|
+
legsWithheld: unknown;
|
|
428
|
+
settlementConfirmed: unknown;
|
|
429
|
+
}): boolean;
|
|
430
|
+
export interface IntentRecord {
|
|
431
|
+
id: string;
|
|
432
|
+
walletAddress: string;
|
|
433
|
+
status: IntentStatus;
|
|
434
|
+
fromChainId: ChainId;
|
|
435
|
+
toChainId: ChainId;
|
|
436
|
+
fromToken: string;
|
|
437
|
+
toToken: string;
|
|
438
|
+
/**
|
|
439
|
+
* Absent when the server did not serve it, never defaulted: a withheld or
|
|
440
|
+
* missing amount is not zero (SPEC.md §5.1). The same for `toAmount`,
|
|
441
|
+
* `createdAt` and `updatedAt`.
|
|
442
|
+
*/
|
|
443
|
+
fromAmount?: string;
|
|
444
|
+
toAmount?: string;
|
|
445
|
+
quoteId: string;
|
|
446
|
+
tier: string;
|
|
447
|
+
feeRate: number;
|
|
448
|
+
settlementType: SettlementType;
|
|
449
|
+
aztecNoteHash?: string;
|
|
450
|
+
txHash?: string;
|
|
451
|
+
/** Public fill receipt (Riddler #632) + its chain, persisted at completion. */
|
|
452
|
+
settlementTxHash?: string;
|
|
453
|
+
settlementChainId?: ChainId;
|
|
454
|
+
createdAt?: string;
|
|
455
|
+
updatedAt?: string;
|
|
456
|
+
error?: string;
|
|
457
|
+
/** `NOT_EXECUTED_SUBSTATUS` on a `failed` the Worker wrote knowing nothing moved. */
|
|
458
|
+
substatus?: string;
|
|
459
|
+
destinationType?: DestinationType;
|
|
460
|
+
/** Never true on a full record: see `WithheldIntentRecord`. */
|
|
461
|
+
legsWithheld?: false;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* `GET /api/intent/:id` read without owner proof (xochi#563; served by
|
|
465
|
+
* xochi#565 once deployed): the server's status-only view, for a stealth
|
|
466
|
+
* intent read without the read token or an owner session, and for a shielded
|
|
467
|
+
* intent read without an owner session, token or not (SPEC.md §5.1,
|
|
468
|
+
* `IntentReadOptions`). Tokens, amounts, wallet, quote, tier, fee, timestamps
|
|
469
|
+
* and every tx hash are withheld, so they are absent here rather than
|
|
470
|
+
* defaulted, and `substatus` is present only when it is `not_executed`; read
|
|
471
|
+
* with the token (stealth), or a wallet SIWE session for the intent's wallet,
|
|
472
|
+
* for the full `IntentRecord`.
|
|
473
|
+
*/
|
|
474
|
+
export interface WithheldIntentRecord {
|
|
475
|
+
legsWithheld: true;
|
|
476
|
+
id: string;
|
|
477
|
+
/**
|
|
478
|
+
* The served status decoded (`decodeWireStatus`): a granular one
|
|
479
|
+
* (`fill_failed`) as its bucket, an unmodelled one as `executing` with
|
|
480
|
+
* `unmapped: true`.
|
|
481
|
+
*/
|
|
482
|
+
status: IntentStatus;
|
|
483
|
+
/** True when the served status was outside this build's vocabulary. Absent means mapped. */
|
|
484
|
+
unmapped?: true;
|
|
485
|
+
fromChainId?: ChainId;
|
|
486
|
+
toChainId?: ChainId;
|
|
487
|
+
settlementType?: SettlementType;
|
|
488
|
+
error?: string;
|
|
489
|
+
/** As on `IntentRecord`. */
|
|
490
|
+
substatus?: string;
|
|
491
|
+
/**
|
|
492
|
+
* True once the destination fill receipt exists (it is withheld itself);
|
|
493
|
+
* never on a terminal failure (`withheldSettlementConfirmed`).
|
|
494
|
+
*/
|
|
495
|
+
settlementConfirmed: boolean;
|
|
496
|
+
}
|
|
497
|
+
export interface IntentRecordWire {
|
|
498
|
+
id: string;
|
|
499
|
+
wallet_address?: string;
|
|
500
|
+
status: string;
|
|
501
|
+
from_chain_id?: ChainId;
|
|
502
|
+
to_chain_id?: ChainId;
|
|
503
|
+
from_token?: string;
|
|
504
|
+
to_token?: string;
|
|
505
|
+
from_amount?: string;
|
|
506
|
+
to_amount?: string;
|
|
507
|
+
quote_id?: string;
|
|
508
|
+
tier?: string;
|
|
509
|
+
fee_rate?: number;
|
|
510
|
+
settlement_type?: SettlementType;
|
|
511
|
+
aztec_note_hash?: string;
|
|
512
|
+
tx_hash?: string;
|
|
513
|
+
settlement_tx_hash?: string | null;
|
|
514
|
+
settlement_chain_id?: ChainId | null;
|
|
515
|
+
created_at?: string;
|
|
516
|
+
updated_at?: string;
|
|
517
|
+
error?: string;
|
|
518
|
+
substatus?: string | null;
|
|
519
|
+
legs_withheld?: boolean;
|
|
520
|
+
settlement_confirmed?: boolean;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* One `GET /api/intent/:id` body: the status-only `WithheldIntentRecord` when
|
|
524
|
+
* the server says it withheld the legs, else the full record.
|
|
525
|
+
*/
|
|
526
|
+
export declare function mapIntentRead(w: IntentRecordWire): IntentRecord | WithheldIntentRecord;
|
|
527
|
+
export declare function mapIntentRecord(w: IntentRecordWire): IntentRecord;
|