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