@recoilpay/intent-react 0.2.0 → 0.3.0

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/dist/index.cjs CHANGED
@@ -21,14 +21,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  RecoilIntent: () => RecoilIntent,
24
- createIntentSession: () => import_intent_core2.createIntentSession,
24
+ createIntentSession: () => import_intent_core4.createIntentSession,
25
+ createOfframpSession: () => import_intent_core4.createOfframpSession,
26
+ useOfframp: () => useOfframp,
25
27
  useRecoilIntent: () => useRecoilIntent,
26
- viemWallet: () => import_intent_core2.viemWallet
28
+ viemWallet: () => import_intent_core4.viemWallet
27
29
  });
28
30
  module.exports = __toCommonJS(index_exports);
29
31
 
30
32
  // src/RecoilIntent.tsx
31
- var import_react2 = require("react");
33
+ var import_react4 = require("react");
32
34
 
33
35
  // src/icons.tsx
34
36
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -58,29 +60,334 @@ var Route = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { ...base,
58
60
  ] });
59
61
  var External = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...base, width: 12, height: 12, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 3H3v10h10v-3M9 3h4v4M13 3L7 9" }) });
60
62
 
61
- // src/useRecoilIntent.ts
63
+ // src/Offramp.tsx
62
64
  var import_intent_core = require("@recoilpay/intent-core");
63
65
  var import_react = require("react");
66
+ var import_jsx_runtime2 = require("react/jsx-runtime");
67
+ var BUSY = ["switchingChain", "approving", "opening", "signing", "locking"];
68
+ function busyLabel(phase, symbol) {
69
+ switch (phase) {
70
+ case "switchingChain":
71
+ return "Switching network\u2026";
72
+ case "approving":
73
+ return `Approving ${symbol}\u2026`;
74
+ case "opening":
75
+ return "Encrypting your details\u2026";
76
+ case "signing":
77
+ return "Confirm in your wallet\u2026";
78
+ default:
79
+ return `Locking your ${symbol}\u2026`;
80
+ }
81
+ }
82
+ function Offramp({ offramp, request, isConnected, onConnect, onDone }) {
83
+ (0, import_react.useEffect)(() => {
84
+ if (request) void offramp.requestQuote(request);
85
+ }, [request]);
86
+ const { phase, preview, trade, error } = offramp;
87
+ const corridor = offramp.request?.corridor ?? null;
88
+ if (phase === "quoting")
89
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "rp-note", "data-tone": "accent", children: [
90
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-note-icon", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) }),
91
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: trade ? "Loading your cash-out\u2026" : "Finding the best cash-out rate\u2026" })
92
+ ] });
93
+ if (phase === "needsWallet")
94
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-connect", children: [
95
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: "Connect a wallet to cash out." }),
96
+ onConnect && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-button", onClick: onConnect, children: "Connect wallet" })
97
+ ] });
98
+ if (phase === "error" && !trade)
99
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-error", children: [
100
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: error }),
101
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-button rp-button-quiet", onClick: onDone, children: "Dismiss" })
102
+ ] });
103
+ if ((phase === "quoted" || BUSY.includes(phase)) && phase !== "locking" && preview && corridor)
104
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(QuoteForm, { offramp, preview, corridor, isConnected, onConnect, onCancel: onDone });
105
+ if (trade) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TradeStatus, { offramp, trade, onDone });
106
+ return null;
107
+ }
108
+ function QuoteForm(p) {
109
+ const { offramp, preview, corridor } = p;
110
+ const [bankCode, setBankCode] = (0, import_react.useState)("");
111
+ const [account, setAccount] = (0, import_react.useState)("");
112
+ const [name, setName] = (0, import_react.useState)("");
113
+ const busy = BUSY.includes(offramp.phase);
114
+ const complete = Boolean(bankCode && account.trim() && name.trim());
115
+ const submit = (e) => {
116
+ e.preventDefault();
117
+ if (!p.isConnected) return p.onConnect?.();
118
+ if (complete && !busy) void offramp.confirm({ rail: corridor.rail, bankCode, account, name });
119
+ };
120
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { className: "rp-card", onSubmit: submit, "aria-label": "Cash out", children: [
121
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card-head", children: [
122
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
123
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-overline", children: "Review" }),
124
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-card-title", children: "Cash out to your bank" })
125
+ ] }),
126
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "rp-badge", children: [
127
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Check, {}),
128
+ " Quoted"
129
+ ] })
130
+ ] }),
131
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-route", children: [
132
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-amount", children: [
133
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-overline", children: "You pay" }),
134
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-amount-value", children: [
135
+ preview.payAmount,
136
+ " ",
137
+ preview.paySymbol
138
+ ] }),
139
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-amount-chain", children: [
140
+ "on ",
141
+ preview.chainName
142
+ ] })
143
+ ] }),
144
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-route-arrow", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ArrowRight, {}) }),
145
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-amount", "data-align": "end", children: [
146
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-overline", children: "You receive" }),
147
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-amount-value", children: [
148
+ preview.currencySymbol,
149
+ preview.receiveAmount
150
+ ] }),
151
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-amount-chain", children: "in your bank account" })
152
+ ] })
153
+ ] }),
154
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("dl", { className: "rp-meta", children: [
155
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
156
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "Rate" }),
157
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("dd", { children: [
158
+ preview.currencySymbol,
159
+ preview.rate,
160
+ " / ",
161
+ preview.paySymbol
162
+ ] })
163
+ ] }),
164
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
165
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "Fee" }),
166
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("dd", { children: [
167
+ preview.currencySymbol,
168
+ preview.fee
169
+ ] })
170
+ ] }),
171
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
172
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "Paid within" }),
173
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("dd", { "data-accent": true, children: [
174
+ Math.max(1, Math.round(preview.paymentWindowSecs / 60)),
175
+ " min"
176
+ ] })
177
+ ] })
178
+ ] }),
179
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("fieldset", { className: "rp-fields", disabled: busy, children: [
180
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "rp-field", children: [
181
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Bank" }),
182
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("select", { value: bankCode, onChange: (e) => setBankCode(e.target.value), required: true, children: [
183
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: "", children: "Choose your bank" }),
184
+ corridor.banks.map((b) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("option", { value: b.code, children: b.name }, b.code))
185
+ ] })
186
+ ] }),
187
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "rp-field", children: [
188
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: corridor.accountLabel }),
189
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
190
+ "input",
191
+ {
192
+ value: account,
193
+ onChange: (e) => setAccount(e.target.value),
194
+ inputMode: "numeric",
195
+ autoComplete: "off",
196
+ spellCheck: false,
197
+ maxLength: 34,
198
+ required: true
199
+ }
200
+ )
201
+ ] }),
202
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "rp-field", children: [
203
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Account name" }),
204
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { value: name, onChange: (e) => setName(e.target.value), autoComplete: "name", maxLength: 140, required: true })
205
+ ] })
206
+ ] }),
207
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "rp-fineprint", children: "Your bank details are encrypted on this device for the solver who pays you. RecoilPay only keeps a fingerprint of them, so it can check the payout went to this account." }),
208
+ offramp.needsApproval && !busy && p.isConnected && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "rp-fineprint", children: [
209
+ "First time with ",
210
+ preview.paySymbol,
211
+ ": your wallet will ask for a one-time approval, then a signature."
212
+ ] }),
213
+ offramp.error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "rp-card-error", children: offramp.error }),
214
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card-actions", children: [
215
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "submit", className: "rp-button", disabled: busy || (p.isConnected ? !complete : !p.onConnect), children: [
216
+ busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
217
+ busy ? busyLabel(offramp.phase, preview.paySymbol) : !p.isConnected ? "Connect wallet" : offramp.needsApproval ? `Approve ${preview.paySymbol} and cash out` : "Cash out"
218
+ ] }),
219
+ !busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-link", onClick: p.onCancel, children: "Cancel" })
220
+ ] })
221
+ ] });
222
+ }
223
+ var STEPS = ["Locked", "Paying you", "You confirm", "Done"];
224
+ function stepOf(trade) {
225
+ switch (trade.state) {
226
+ case "quoted":
227
+ return 0;
228
+ case "awaiting_fiat":
229
+ return 1;
230
+ case "awaiting_confirmation":
231
+ case "disputed":
232
+ return 2;
233
+ default:
234
+ return 3;
235
+ }
236
+ }
237
+ function TradeStatus({ offramp, trade, onDone }) {
238
+ const [disputing, setDisputing] = (0, import_react.useState)(false);
239
+ const [reason, setReason] = (0, import_react.useState)("");
240
+ const corridor = offramp.request?.corridor;
241
+ const amount = corridor ? `${corridor.symbol}${(0, import_intent_core.formatFiat)(trade.fiat_minor_units, corridor)}` : `${trade.fiat_minor_units} (minor units) ${trade.fiat_currency}`;
242
+ const acting = offramp.phase === "confirming" || offramp.phase === "disputing";
243
+ const bad = trade.state === "refunded_to_funder" || trade.state === "failed";
244
+ const good = trade.state === "settled_to_fiat_payer";
245
+ const ended = good || bad;
246
+ const active = stepOf(trade);
247
+ const title = {
248
+ quoted: `Locking your ${trade.asset}\u2026`,
249
+ awaiting_fiat: `Sending ${amount} to your bank\u2026`,
250
+ awaiting_confirmation: `Did ${amount} arrive?`,
251
+ disputed: "Under review",
252
+ settled_to_fiat_payer: "Cashed out",
253
+ refunded_to_funder: `${trade.asset} returned`,
254
+ failed: "Cash-out did not start"
255
+ };
256
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card", "data-state": bad ? "bad" : good ? "good" : "pending", children: [
257
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-card-head", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-card-title", children: title[trade.state] }) }),
258
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ol", { className: "rp-steps", style: { gridTemplateColumns: `repeat(${STEPS.length}, 1fr)` }, children: STEPS.map((label, i) => {
259
+ const state = bad ? "bad" : i < active || good ? "done" : i === active ? "current" : "todo";
260
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { "data-state": state, children: [
261
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-step-dot", children: state === "bad" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Cross, {}) : state === "done" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Check, {}) : state === "current" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) : null }),
262
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-step-label", children: label })
263
+ ] }, label);
264
+ }) }),
265
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card-body", children: [
266
+ trade.state === "awaiting_fiat" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { children: [
267
+ "Your ",
268
+ trade.asset,
269
+ " is locked in escrow. The solver is paying you now; you'll be asked to confirm when they say it's sent."
270
+ ] }),
271
+ trade.state === "awaiting_confirmation" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { children: [
272
+ "The solver says they sent ",
273
+ amount,
274
+ trade.payment_reference ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
275
+ " ",
276
+ "with reference ",
277
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-mono", children: trade.payment_reference })
278
+ ] }) : null,
279
+ ". Check your bank app. Your ",
280
+ trade.asset,
281
+ " stays locked until you answer, so only confirm once the money is in your account."
282
+ ] }) }),
283
+ trade.state === "disputed" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { children: [
284
+ "An admin is reviewing this cash-out. Your ",
285
+ trade.asset,
286
+ " stays in escrow until they decide."
287
+ ] }),
288
+ good && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { children: [
289
+ amount,
290
+ " was paid to your account."
291
+ ] }),
292
+ trade.state === "refunded_to_funder" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { children: [
293
+ "Your ",
294
+ trade.asset,
295
+ " was returned to your wallet."
296
+ ] }),
297
+ trade.state === "failed" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: "The lock never landed, so nothing left your wallet." })
298
+ ] }),
299
+ offramp.error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "rp-card-error", children: offramp.error }),
300
+ trade.state === "awaiting_confirmation" && !disputing && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card-actions", children: [
301
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "button", className: "rp-button", disabled: acting, onClick: () => void offramp.confirmReceived(), children: [
302
+ offramp.phase === "confirming" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
303
+ offramp.phase === "confirming" ? "Confirm in your wallet\u2026" : `I received ${amount}`
304
+ ] }),
305
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-link", disabled: acting, onClick: () => setDisputing(true), children: "It hasn't arrived" })
306
+ ] }),
307
+ trade.state === "awaiting_confirmation" && disputing && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
308
+ "form",
309
+ {
310
+ className: "rp-card-actions",
311
+ onSubmit: (e) => {
312
+ e.preventDefault();
313
+ void offramp.dispute(reason);
314
+ },
315
+ children: [
316
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "rp-field rp-field-wide", children: [
317
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "What went wrong?" }),
318
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("textarea", { value: reason, onChange: (e) => setReason(e.target.value), maxLength: 500, rows: 3, required: true })
319
+ ] }),
320
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("button", { type: "submit", className: "rp-button", disabled: acting || !reason.trim(), children: [
321
+ offramp.phase === "disputing" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
322
+ offramp.phase === "disputing" ? "Confirm in your wallet\u2026" : "Open a dispute"
323
+ ] }),
324
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-link", disabled: acting, onClick: () => setDisputing(false), children: "Back" })
325
+ ]
326
+ }
327
+ ),
328
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("details", { className: "rp-receipt", children: [
329
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("summary", { children: "Receipt" }),
330
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("dl", { children: [
331
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
332
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "Trade" }),
333
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { className: "rp-mono", children: trade.id })
334
+ ] }),
335
+ offramp.payeeSalt && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
336
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "Bank details proof" }),
337
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { className: "rp-mono", children: offramp.payeeSalt })
338
+ ] })
339
+ ] }),
340
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: "Keep these if you might need to dispute: with your bank details, they prove which account the solver was told to pay." })
341
+ ] }),
342
+ ended && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-card-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-button rp-button-quiet", onClick: onDone, children: "New intent" }) }),
343
+ trade.state === "quoted" && offramp.error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-card-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-button rp-button-quiet", onClick: onDone, children: "Start over" }) })
344
+ ] });
345
+ }
346
+
347
+ // src/useOfframp.ts
348
+ var import_intent_core2 = require("@recoilpay/intent-core");
349
+ var import_react2 = require("react");
350
+ function useOfframp(options = {}) {
351
+ const [session] = (0, import_react2.useState)(() => options.session ?? (0, import_intent_core2.createOfframpSession)({ apiUrl: options.apiUrl }));
352
+ const state = (0, import_react2.useSyncExternalStore)(session.subscribe, session.getState, session.getState);
353
+ const wallet = options.wallet ?? null;
354
+ (0, import_react2.useEffect)(() => session.setWallet(wallet), [session, wallet]);
355
+ return {
356
+ ...state,
357
+ requestQuote: session.quote,
358
+ confirm: session.confirm,
359
+ confirmReceived: session.confirmReceived,
360
+ dispute: session.dispute,
361
+ resume: session.resume,
362
+ reset: session.reset,
363
+ session
364
+ };
365
+ }
366
+
367
+ // src/useRecoilIntent.ts
368
+ var import_intent_core3 = require("@recoilpay/intent-core");
369
+ var import_react3 = require("react");
64
370
  function useRecoilIntent(options = {}) {
65
- const [session] = (0, import_react.useState)(() => options.session ?? (0, import_intent_core.createIntentSession)({ apiUrl: options.apiUrl, hfAccessToken: options.hfAccessToken }));
66
- const state = (0, import_react.useSyncExternalStore)(session.subscribe, session.getState, session.getState);
371
+ const [session] = (0, import_react3.useState)(() => options.session ?? (0, import_intent_core3.createIntentSession)({ apiUrl: options.apiUrl, hfAccessToken: options.hfAccessToken }));
372
+ const state = (0, import_react3.useSyncExternalStore)(session.subscribe, session.getState, session.getState);
67
373
  const wallet = options.wallet ?? null;
68
- (0, import_react.useEffect)(() => session.setWallet(wallet), [session, wallet]);
374
+ (0, import_react3.useEffect)(() => session.setWallet(wallet), [session, wallet]);
69
375
  const hfAccessToken = options.hfAccessToken;
70
- (0, import_react.useEffect)(() => {
376
+ (0, import_react3.useEffect)(() => {
71
377
  if (hfAccessToken !== void 0) session.setHfAccessToken(hfAccessToken);
72
378
  }, [session, hfAccessToken]);
73
379
  return { ...state, run: session.run, confirm: session.confirm, reset: session.reset, session };
74
380
  }
75
381
 
76
382
  // src/RecoilIntent.tsx
77
- var import_jsx_runtime2 = require("react/jsx-runtime");
383
+ var import_jsx_runtime3 = require("react/jsx-runtime");
78
384
  var DEFAULT_EXAMPLES = [
79
385
  { label: "Swap 1 USDC from OP Sepolia to Base Sepolia", sentence: "swap 1 USDC on op sepolia for USDC on base sepolia" },
80
386
  { label: "Swap 5 USDC from Base Sepolia to OP Sepolia", sentence: "swap 5 USDC on base sepolia for USDC on op sepolia" }
81
387
  ];
82
- var BUSY = ["switchingChain", "approving", "signing", "submitting"];
83
- var CARD_PHASES = ["quoted", "needsWallet", ...BUSY];
388
+ var BUSY2 = ["switchingChain", "approving", "signing", "submitting"];
389
+ var CASH_OUT_UNDERWAY = ["switchingChain", "approving", "opening", "signing", "locking", "awaitingFiat", "awaitingConfirmation", "confirming", "disputing"];
390
+ var CARD_PHASES = ["quoted", "needsWallet", ...BUSY2];
84
391
  function themeVars(theme = {}) {
85
392
  const vars = {};
86
393
  if (theme.accent) vars["--rp-accent"] = theme.accent;
@@ -91,29 +398,49 @@ function themeVars(theme = {}) {
91
398
  }
92
399
  function RecoilIntent(props) {
93
400
  const intent = useRecoilIntent({ apiUrl: props.apiUrl, session: props.session, wallet: props.wallet, hfAccessToken: props.hfAccessToken });
94
- const [value, setValue] = (0, import_react2.useState)(props.defaultValue ?? "");
401
+ const [value, setValue] = (0, import_react4.useState)(props.defaultValue ?? "");
402
+ const offramp = useOfframp({ apiUrl: props.apiUrl, session: props.offrampSession, wallet: props.wallet });
95
403
  const examples = props.examples === false ? [] : props.examples ?? DEFAULT_EXAMPLES;
96
404
  useLifecycleCallbacks(intent, props);
405
+ const cashOutUnderway = CASH_OUT_UNDERWAY.includes(offramp.phase) && !(offramp.phase === "locking" && offramp.error);
406
+ const showOfframp = intent.phase === "offramp" || offramp.phase !== "idle";
407
+ const resumeId = props.resumeCashOut;
408
+ (0, import_react4.useEffect)(() => {
409
+ if (resumeId) void offramp.resume(resumeId);
410
+ }, [resumeId]);
411
+ const tradeId = offramp.trade?.id;
412
+ const cashOutCbs = (0, import_react4.useRef)(props);
413
+ cashOutCbs.current = props;
414
+ (0, import_react4.useEffect)(() => {
415
+ if (tradeId && tradeId !== resumeId) cashOutCbs.current.onCashOutStarted?.(tradeId);
416
+ }, [tradeId, resumeId]);
417
+ const ended = offramp.trade && ["settled_to_fiat_payer", "refunded_to_funder", "failed"].includes(offramp.trade.state) ? offramp.trade : null;
418
+ (0, import_react4.useEffect)(() => {
419
+ if (ended) cashOutCbs.current.onCashOutEnded?.(ended);
420
+ }, [ended?.id, ended?.state]);
97
421
  const submit = (sentence = value) => {
98
422
  const text = sentence.trim();
99
- if (text && intent.ready) void intent.run(text);
423
+ if (!text || !intent.ready) return;
424
+ offramp.reset();
425
+ void intent.run(text);
100
426
  };
101
427
  const startOver = () => {
102
428
  intent.reset();
429
+ offramp.reset();
103
430
  setValue("");
104
431
  };
105
432
  const connect = () => props.onConnectWallet?.();
106
433
  const showCard = intent.preview && (CARD_PHASES.includes(intent.phase) || intent.phase === "error" && intent.route);
107
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: ["rp-root", props.className].filter(Boolean).join(" "), "data-mode": props.theme?.mode ?? "dark", style: themeVars(props.theme), children: [
108
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-composer", children: [
109
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-composer-head", children: [
110
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "rp-eyebrow", children: [
111
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { "aria-hidden": "true", children: "/" }),
434
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: ["rp-root", props.className].filter(Boolean).join(" "), "data-mode": props.theme?.mode ?? "dark", style: themeVars(props.theme), children: [
435
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-composer", children: [
436
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-composer-head", children: [
437
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "rp-eyebrow", children: [
438
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": "true", children: "/" }),
112
439
  "intent"
113
440
  ] }),
114
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-powered", children: "RecoilPay" })
441
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "rp-powered", children: "RecoilPay" })
115
442
  ] }),
116
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
443
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
117
444
  "form",
118
445
  {
119
446
  className: "rp-composer-row",
@@ -122,26 +449,27 @@ function RecoilIntent(props) {
122
449
  submit();
123
450
  },
124
451
  children: [
125
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
452
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
126
453
  "input",
127
454
  {
128
455
  className: "rp-input",
129
456
  value,
130
457
  onChange: (e) => setValue(e.target.value),
131
- placeholder: props.placeholder ?? "swap 1 USDC on OP Sepolia for USDC on Base Sepolia",
458
+ placeholder: cashOutUnderway ? "Finish your cash-out first" : props.placeholder ?? "swap 1 USDC on OP Sepolia for USDC on Base Sepolia",
459
+ disabled: cashOutUnderway,
132
460
  "aria-label": "Describe a swap or send",
133
461
  autoComplete: "off",
134
462
  spellCheck: false,
135
463
  maxLength: 500
136
464
  }
137
465
  ),
138
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "submit", className: "rp-run", "aria-label": "Run intent", disabled: !intent.ready || !value.trim(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ArrowRight, {}) })
466
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "rp-run", "aria-label": "Run intent", disabled: !intent.ready || !value.trim() || cashOutUnderway, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ArrowRight, {}) })
139
467
  ]
140
468
  }
141
469
  ),
142
- intent.phase === "idle" && examples.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-examples", children: [
143
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-examples-label", children: "try" }),
144
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-example-list", children: examples.map((ex) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
470
+ intent.phase === "idle" && !showOfframp && examples.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-examples", children: [
471
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "rp-examples-label", children: "try" }),
472
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rp-example-list", children: examples.map((ex) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
145
473
  "button",
146
474
  {
147
475
  type: "button",
@@ -157,33 +485,43 @@ function RecoilIntent(props) {
157
485
  )) })
158
486
  ] })
159
487
  ] }),
160
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-results", "aria-live": "polite", children: [
161
- intent.assetsError && intent.phase === "idle" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Note, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Alert, {}), children: [
488
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-results", "aria-live": "polite", children: [
489
+ showOfframp && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
490
+ Offramp,
491
+ {
492
+ offramp,
493
+ request: intent.phase === "offramp" ? intent.offramp : null,
494
+ isConnected: intent.isConnected,
495
+ onConnect: props.onConnectWallet ? connect : void 0,
496
+ onDone: startOver
497
+ }
498
+ ),
499
+ intent.assetsError && intent.phase === "idle" && !showOfframp && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Note, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Alert, {}), children: [
162
500
  "Could not reach the solver network.",
163
501
  " ",
164
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-link", onClick: () => void intent.session.refreshAssets(), children: "Retry" })
502
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "rp-link", onClick: () => void intent.session.refreshAssets(), children: "Retry" })
165
503
  ] }),
166
- intent.phase === "parsing" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Note, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}), children: "Reading your intent\u2026" }),
167
- intent.phase === "offTemplate" && intent.hint && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Note, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Alert, {}), children: intent.hint }),
168
- intent.phase === "invalid" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: "rp-issues", children: intent.issues.map((issue, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { children: [
169
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Alert, {}),
170
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: issue.message })
504
+ intent.phase === "parsing" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Note, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, {}), children: "Reading your intent\u2026" }),
505
+ intent.phase === "offTemplate" && intent.hint && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Note, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Alert, {}), children: intent.hint }),
506
+ intent.phase === "invalid" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ul", { className: "rp-issues", children: intent.issues.map((issue, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { children: [
507
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Alert, {}),
508
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: issue.message })
171
509
  ] }, `${issue.field}-${i}`)) }),
172
- intent.phase === "quoting" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Note, { icon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Route, {}), tone: "accent", children: intent.queueTotal > 1 ? `Intent ${intent.queueIndex + 1} of ${intent.queueTotal}: asking solvers for a quote\u2026` : "Asking solvers for a quote\u2026" }),
173
- intent.phase === "needsWallet" && !intent.preview && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-connect", children: [
174
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: "Connect a wallet to get a quote." }),
175
- props.onConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-button", onClick: connect, children: "Connect wallet" })
510
+ intent.phase === "quoting" && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Note, { icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Route, {}), tone: "accent", children: intent.queueTotal > 1 ? `Intent ${intent.queueIndex + 1} of ${intent.queueTotal}: asking solvers for a quote\u2026` : "Asking solvers for a quote\u2026" }),
511
+ intent.phase === "needsWallet" && !intent.preview && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-connect", children: [
512
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "Connect a wallet to get a quote." }),
513
+ props.onConnectWallet && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "rp-button", onClick: connect, children: "Connect wallet" })
176
514
  ] }),
177
- intent.queueTotal > 1 && !["idle", "parsing", "offTemplate", "invalid"].includes(intent.phase) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-queue", children: [
178
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { children: [
515
+ intent.queueTotal > 1 && !["idle", "parsing", "offTemplate", "invalid"].includes(intent.phase) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-queue", children: [
516
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
179
517
  "Intent ",
180
518
  intent.queueIndex + 1,
181
519
  " of ",
182
520
  intent.queueTotal
183
521
  ] }),
184
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-queue-track", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { width: `${(intent.queueIndex + (intent.phase === "done" ? 1 : 0)) / intent.queueTotal * 100}%` } }) })
522
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rp-queue-track", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { width: `${(intent.queueIndex + (intent.phase === "done" ? 1 : 0)) / intent.queueTotal * 100}%` } }) })
185
523
  ] }),
186
- showCard && intent.preview && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
524
+ showCard && intent.preview && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
187
525
  ConfirmCard,
188
526
  {
189
527
  preview: intent.preview,
@@ -197,19 +535,19 @@ function RecoilIntent(props) {
197
535
  onCancel: startOver
198
536
  }
199
537
  ),
200
- (intent.phase === "tracking" || intent.phase === "done") && intent.orderId && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(OrderProgress, { status: intent.status, direct: intent.route === "direct", explorerUrl: intent.explorerUrl, onNew: startOver }),
201
- intent.phase === "error" && !intent.route && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-error", children: [
202
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: intent.error }),
203
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-button rp-button-quiet", onClick: startOver, children: "Dismiss" })
538
+ (intent.phase === "tracking" || intent.phase === "done") && intent.orderId && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(OrderProgress, { status: intent.status, direct: intent.route === "direct", explorerUrl: intent.explorerUrl, onNew: startOver }),
539
+ intent.phase === "error" && !intent.route && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-error", children: [
540
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: intent.error }),
541
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "rp-button rp-button-quiet", onClick: startOver, children: "Dismiss" })
204
542
  ] })
205
543
  ] })
206
544
  ] });
207
545
  }
208
546
  function useLifecycleCallbacks(intent, props) {
209
- const prev = (0, import_react2.useRef)(intent);
210
- const cbs = (0, import_react2.useRef)(props);
547
+ const prev = (0, import_react4.useRef)(intent);
548
+ const cbs = (0, import_react4.useRef)(props);
211
549
  cbs.current = props;
212
- (0, import_react2.useEffect)(() => {
550
+ (0, import_react4.useEffect)(() => {
213
551
  const before = prev.current;
214
552
  prev.current = intent;
215
553
  if (intent.orderId && intent.orderId !== before.orderId) cbs.current.onOrderSubmitted?.(intent.orderId);
@@ -218,9 +556,9 @@ function useLifecycleCallbacks(intent, props) {
218
556
  }, [intent]);
219
557
  }
220
558
  function Note({ icon, tone = "muted", children }) {
221
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "rp-note", "data-tone": tone, children: [
222
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-note-icon", children: icon }),
223
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children })
559
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "rp-note", "data-tone": tone, children: [
560
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "rp-note-icon", children: icon }),
561
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children })
224
562
  ] });
225
563
  }
226
564
  var shortAddr = (a) => a.length > 12 ? `${a.slice(0, 6)}\u2026${a.slice(-4)}` : a;
@@ -243,25 +581,25 @@ function actionLabel(phase, isConnected, needsApproval, symbol, direct) {
243
581
  }
244
582
  }
245
583
  function ConfirmCard(p) {
246
- const busy = BUSY.includes(p.phase);
584
+ const busy = BUSY2.includes(p.phase);
247
585
  const send = p.preview.action === "send";
248
586
  const wantsWallet = !p.isConnected || p.phase === "needsWallet";
249
587
  const { solverCount, solversQueried } = p.preview;
250
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card", children: [
251
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card-head", children: [
252
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
253
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-overline", children: "Review" }),
254
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-card-title", children: p.direct ? "Direct transfer" : "Best solver route" })
588
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-card", children: [
589
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-card-head", children: [
590
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
591
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rp-overline", children: "Review" }),
592
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rp-card-title", children: p.direct ? "Direct transfer" : "Best solver route" })
255
593
  ] }),
256
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "rp-badge", children: [
257
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Check, {}),
594
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "rp-badge", children: [
595
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Check, {}),
258
596
  " Quoted"
259
597
  ] })
260
598
  ] }),
261
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-route", children: [
262
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Amount, { label: send ? "You send" : "You pay", amount: p.preview.payAmount, symbol: p.preview.paySymbol, chain: p.preview.srcChainName }),
263
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-route-arrow", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ArrowRight, {}) }),
264
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
599
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-route", children: [
600
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Amount, { label: send ? "You send" : "You pay", amount: p.preview.payAmount, symbol: p.preview.paySymbol, chain: p.preview.srcChainName }),
601
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "rp-route-arrow", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ArrowRight, {}) }),
602
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
265
603
  Amount,
266
604
  {
267
605
  align: "end",
@@ -272,28 +610,28 @@ function ConfirmCard(p) {
272
610
  }
273
611
  )
274
612
  ] }),
275
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("dl", { className: "rp-meta", children: [
276
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
277
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "Settles in" }),
278
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { children: p.preview.etaSeconds ? `~${p.preview.etaSeconds}s` : "Fast" })
613
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("dl", { className: "rp-meta", children: [
614
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
615
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dt", { children: "Settles in" }),
616
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dd", { children: p.preview.etaSeconds ? `~${p.preview.etaSeconds}s` : "Fast" })
279
617
  ] }),
280
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
281
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: p.direct ? "Route" : "Solvers" }),
282
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { "data-accent": true, children: p.direct ? "Your wallet" : solversQueried && solversQueried > solverCount ? `${solverCount} of ${solversQueried} quoted` : `${solverCount} quoted` })
618
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
619
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dt", { children: p.direct ? "Route" : "Solvers" }),
620
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dd", { "data-accent": true, children: p.direct ? "Your wallet" : solversQueried && solversQueried > solverCount ? `${solverCount} of ${solversQueried} quoted` : `${solverCount} quoted` })
283
621
  ] }),
284
- send && p.preview.recipient && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
285
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dt", { children: "Recipient" }),
286
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("dd", { className: "rp-mono", children: shortAddr(p.preview.recipient) })
622
+ send && p.preview.recipient && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
623
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dt", { children: "Recipient" }),
624
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("dd", { className: "rp-mono", children: shortAddr(p.preview.recipient) })
287
625
  ] })
288
626
  ] }),
289
- p.needsApproval && !busy && !wantsWallet && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "rp-fineprint", children: [
627
+ p.needsApproval && !busy && !wantsWallet && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "rp-fineprint", children: [
290
628
  "First time with ",
291
629
  p.preview.paySymbol,
292
630
  ": your wallet will ask for a one-time approval, then a signature."
293
631
  ] }),
294
- p.error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "rp-card-error", children: p.error }),
295
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card-actions", children: [
296
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
632
+ p.error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "rp-card-error", children: p.error }),
633
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-card-actions", children: [
634
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
297
635
  "button",
298
636
  {
299
637
  type: "button",
@@ -301,31 +639,31 @@ function ConfirmCard(p) {
301
639
  disabled: busy || wantsWallet && !p.onConnect,
302
640
  onClick: wantsWallet ? p.onConnect : p.onConfirm,
303
641
  children: [
304
- busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}),
642
+ busy && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, {}),
305
643
  actionLabel(p.phase, p.isConnected, p.needsApproval, p.preview.paySymbol, p.direct)
306
644
  ]
307
645
  }
308
646
  ),
309
- !busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-link", onClick: p.onCancel, children: "Cancel" })
647
+ !busy && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "rp-link", onClick: p.onCancel, children: "Cancel" })
310
648
  ] })
311
649
  ] });
312
650
  }
313
651
  function Amount({ label, amount, symbol, chain, align = "start" }) {
314
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-amount", "data-align": align, children: [
315
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-overline", children: label }),
316
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-amount-value", children: [
652
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-amount", "data-align": align, children: [
653
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rp-overline", children: label }),
654
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-amount-value", children: [
317
655
  amount,
318
656
  " ",
319
657
  symbol
320
658
  ] }),
321
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-amount-chain", children: [
659
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-amount-chain", children: [
322
660
  "on ",
323
661
  chain
324
662
  ] })
325
663
  ] });
326
664
  }
327
- var STEPS = ["Submitted", "Filling", "Filled", "Settling", "Done"];
328
- function stepOf(status) {
665
+ var STEPS2 = ["Submitted", "Filling", "Filled", "Settling", "Done"];
666
+ function stepOf2(status) {
329
667
  switch (status) {
330
668
  case "executing":
331
669
  return 1;
@@ -344,38 +682,40 @@ function OrderProgress({ status, direct, explorerUrl, onNew }) {
344
682
  const failed = !!status && typeof status === "object" && "failed" in status;
345
683
  const refunded = status === "refunded";
346
684
  const finished = status === "finalized";
347
- const active = stepOf(status);
685
+ const active = stepOf2(status);
348
686
  const title = failed ? "Order failed" : refunded ? "Refunded" : finished ? direct ? "Sent" : "Settled" : "Settling\u2026";
349
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card", "data-state": failed || refunded ? "bad" : finished ? "good" : "pending", children: [
350
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rp-card-head", children: [
351
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-card-title", children: title }),
352
- explorerUrl && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("a", { className: "rp-link", href: explorerUrl, target: "_blank", rel: "noopener noreferrer", children: [
687
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-card", "data-state": failed || refunded ? "bad" : finished ? "good" : "pending", children: [
688
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rp-card-head", children: [
689
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rp-card-title", children: title }),
690
+ explorerUrl && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("a", { className: "rp-link", href: explorerUrl, target: "_blank", rel: "noopener noreferrer", children: [
353
691
  "View on explorer ",
354
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(External, {})
692
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(External, {})
355
693
  ] })
356
694
  ] }),
357
- !direct && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ol", { className: "rp-steps", children: STEPS.map((label, i) => {
695
+ !direct && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("ol", { className: "rp-steps", children: STEPS2.map((label, i) => {
358
696
  const state = failed || refunded ? "bad" : i < active || finished ? "done" : i === active ? "current" : "todo";
359
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { "data-state": state, children: [
360
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-step-dot", children: state === "bad" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Cross, {}) : state === "done" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Check, {}) : state === "current" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spinner, {}) : null }),
361
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "rp-step-label", children: label })
697
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("li", { "data-state": state, children: [
698
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "rp-step-dot", children: state === "bad" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Cross, {}) : state === "done" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Check, {}) : state === "current" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Spinner, {}) : null }),
699
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "rp-step-label", children: label })
362
700
  ] }, label);
363
701
  }) }),
364
- failed && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { className: "rp-card-error", children: [
702
+ failed && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "rp-card-error", children: [
365
703
  status.failed[0],
366
704
  ": ",
367
705
  status.failed[1]
368
706
  ] }),
369
- (finished || failed || refunded) && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rp-card-actions", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "rp-button rp-button-quiet", onClick: onNew, children: "New intent" }) })
707
+ (finished || failed || refunded) && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rp-card-actions", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "rp-button rp-button-quiet", onClick: onNew, children: "New intent" }) })
370
708
  ] });
371
709
  }
372
710
 
373
711
  // src/index.ts
374
- var import_intent_core2 = require("@recoilpay/intent-core");
712
+ var import_intent_core4 = require("@recoilpay/intent-core");
375
713
  // Annotate the CommonJS export names for ESM import in node:
376
714
  0 && (module.exports = {
377
715
  RecoilIntent,
378
716
  createIntentSession,
717
+ createOfframpSession,
718
+ useOfframp,
379
719
  useRecoilIntent,
380
720
  viemWallet
381
721
  });