@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/README.md +11 -1
- package/dist/index.cjs +439 -99
- package/dist/index.d.cts +38 -3
- package/dist/index.d.ts +38 -3
- package/dist/index.js +433 -94
- package/dist/styles.css +94 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/RecoilIntent.tsx
|
|
2
|
-
import { useEffect as
|
|
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] =
|
|
37
|
-
const state =
|
|
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
|
-
|
|
343
|
+
useEffect3(() => session.setWallet(wallet), [session, wallet]);
|
|
40
344
|
const hfAccessToken = options.hfAccessToken;
|
|
41
|
-
|
|
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
|
|
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
|
|
54
|
-
var
|
|
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] =
|
|
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
|
|
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__ */
|
|
79
|
-
/* @__PURE__ */
|
|
80
|
-
/* @__PURE__ */
|
|
81
|
-
/* @__PURE__ */
|
|
82
|
-
/* @__PURE__ */
|
|
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__ */
|
|
410
|
+
/* @__PURE__ */ jsx3("span", { className: "rp-powered", children: "RecoilPay" })
|
|
86
411
|
] }),
|
|
87
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
114
|
-
/* @__PURE__ */
|
|
115
|
-
/* @__PURE__ */
|
|
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__ */
|
|
132
|
-
|
|
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__ */
|
|
471
|
+
/* @__PURE__ */ jsx3("button", { type: "button", className: "rp-link", onClick: () => void intent.session.refreshAssets(), children: "Retry" })
|
|
136
472
|
] }),
|
|
137
|
-
intent.phase === "parsing" && /* @__PURE__ */
|
|
138
|
-
intent.phase === "offTemplate" && intent.hint && /* @__PURE__ */
|
|
139
|
-
intent.phase === "invalid" && /* @__PURE__ */
|
|
140
|
-
/* @__PURE__ */
|
|
141
|
-
/* @__PURE__ */
|
|
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__ */
|
|
144
|
-
intent.phase === "needsWallet" && !intent.preview && /* @__PURE__ */
|
|
145
|
-
/* @__PURE__ */
|
|
146
|
-
props.onConnectWallet && /* @__PURE__ */
|
|
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__ */
|
|
149
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
172
|
-
intent.phase === "error" && !intent.route && /* @__PURE__ */
|
|
173
|
-
/* @__PURE__ */
|
|
174
|
-
/* @__PURE__ */
|
|
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
|
-
|
|
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__ */
|
|
193
|
-
/* @__PURE__ */
|
|
194
|
-
/* @__PURE__ */
|
|
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 =
|
|
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__ */
|
|
222
|
-
/* @__PURE__ */
|
|
223
|
-
/* @__PURE__ */
|
|
224
|
-
/* @__PURE__ */
|
|
225
|
-
/* @__PURE__ */
|
|
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__ */
|
|
228
|
-
/* @__PURE__ */
|
|
563
|
+
/* @__PURE__ */ jsxs3("span", { className: "rp-badge", children: [
|
|
564
|
+
/* @__PURE__ */ jsx3(Check, {}),
|
|
229
565
|
" Quoted"
|
|
230
566
|
] })
|
|
231
567
|
] }),
|
|
232
|
-
/* @__PURE__ */
|
|
233
|
-
/* @__PURE__ */
|
|
234
|
-
/* @__PURE__ */
|
|
235
|
-
/* @__PURE__ */
|
|
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__ */
|
|
247
|
-
/* @__PURE__ */
|
|
248
|
-
/* @__PURE__ */
|
|
249
|
-
/* @__PURE__ */
|
|
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__ */
|
|
252
|
-
/* @__PURE__ */
|
|
253
|
-
/* @__PURE__ */
|
|
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__ */
|
|
256
|
-
/* @__PURE__ */
|
|
257
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
266
|
-
/* @__PURE__ */
|
|
267
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
286
|
-
/* @__PURE__ */
|
|
287
|
-
/* @__PURE__ */
|
|
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__ */
|
|
628
|
+
/* @__PURE__ */ jsxs3("div", { className: "rp-amount-chain", children: [
|
|
293
629
|
"on ",
|
|
294
630
|
chain
|
|
295
631
|
] })
|
|
296
632
|
] });
|
|
297
633
|
}
|
|
298
|
-
var
|
|
299
|
-
function
|
|
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 =
|
|
654
|
+
const active = stepOf2(status);
|
|
319
655
|
const title = failed ? "Order failed" : refunded ? "Refunded" : finished ? direct ? "Sent" : "Settled" : "Settling\u2026";
|
|
320
|
-
return /* @__PURE__ */
|
|
321
|
-
/* @__PURE__ */
|
|
322
|
-
/* @__PURE__ */
|
|
323
|
-
explorerUrl && /* @__PURE__ */
|
|
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__ */
|
|
661
|
+
/* @__PURE__ */ jsx3(External, {})
|
|
326
662
|
] })
|
|
327
663
|
] }),
|
|
328
|
-
!direct && /* @__PURE__ */
|
|
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__ */
|
|
331
|
-
/* @__PURE__ */
|
|
332
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
};
|