@recoilpay/intent-react 0.2.0 → 0.4.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.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: () =>
|
|
24
|
+
createIntentSession: () => import_intent_core4.createIntentSession,
|
|
25
|
+
createOfframpSession: () => import_intent_core4.createOfframpSession,
|
|
26
|
+
useOfframp: () => useOfframp,
|
|
25
27
|
useRecoilIntent: () => useRecoilIntent,
|
|
26
|
-
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
|
|
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/
|
|
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,
|
|
66
|
-
const state = (0,
|
|
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,
|
|
374
|
+
(0, import_react3.useEffect)(() => session.setWallet(wallet), [session, wallet]);
|
|
69
375
|
const hfAccessToken = options.hfAccessToken;
|
|
70
|
-
(0,
|
|
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
|
|
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
|
|
83
|
-
var
|
|
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,
|
|
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
|
|
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,
|
|
108
|
-
/* @__PURE__ */ (0,
|
|
109
|
-
/* @__PURE__ */ (0,
|
|
110
|
-
/* @__PURE__ */ (0,
|
|
111
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
441
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "rp-powered", children: "RecoilPay" })
|
|
115
442
|
] }),
|
|
116
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
143
|
-
/* @__PURE__ */ (0,
|
|
144
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
161
|
-
|
|
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,
|
|
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,
|
|
167
|
-
intent.phase === "offTemplate" && intent.hint && /* @__PURE__ */ (0,
|
|
168
|
-
intent.phase === "invalid" && /* @__PURE__ */ (0,
|
|
169
|
-
/* @__PURE__ */ (0,
|
|
170
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
173
|
-
intent.phase === "needsWallet" && !intent.preview && /* @__PURE__ */ (0,
|
|
174
|
-
/* @__PURE__ */ (0,
|
|
175
|
-
props.onConnectWallet && /* @__PURE__ */ (0,
|
|
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,
|
|
178
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
201
|
-
intent.phase === "error" && !intent.route && /* @__PURE__ */ (0,
|
|
202
|
-
/* @__PURE__ */ (0,
|
|
203
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
210
|
-
const cbs = (0,
|
|
547
|
+
const prev = (0, import_react4.useRef)(intent);
|
|
548
|
+
const cbs = (0, import_react4.useRef)(props);
|
|
211
549
|
cbs.current = props;
|
|
212
|
-
(0,
|
|
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,
|
|
222
|
-
/* @__PURE__ */ (0,
|
|
223
|
-
/* @__PURE__ */ (0,
|
|
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 =
|
|
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,
|
|
251
|
-
/* @__PURE__ */ (0,
|
|
252
|
-
/* @__PURE__ */ (0,
|
|
253
|
-
/* @__PURE__ */ (0,
|
|
254
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
257
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
262
|
-
/* @__PURE__ */ (0,
|
|
263
|
-
/* @__PURE__ */ (0,
|
|
264
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
276
|
-
/* @__PURE__ */ (0,
|
|
277
|
-
/* @__PURE__ */ (0,
|
|
278
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
281
|
-
/* @__PURE__ */ (0,
|
|
282
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
285
|
-
/* @__PURE__ */ (0,
|
|
286
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
295
|
-
/* @__PURE__ */ (0,
|
|
296
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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,
|
|
315
|
-
/* @__PURE__ */ (0,
|
|
316
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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
|
|
328
|
-
function
|
|
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 =
|
|
685
|
+
const active = stepOf2(status);
|
|
348
686
|
const title = failed ? "Order failed" : refunded ? "Refunded" : finished ? direct ? "Sent" : "Settled" : "Settling\u2026";
|
|
349
|
-
return /* @__PURE__ */ (0,
|
|
350
|
-
/* @__PURE__ */ (0,
|
|
351
|
-
/* @__PURE__ */ (0,
|
|
352
|
-
explorerUrl && /* @__PURE__ */ (0,
|
|
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,
|
|
692
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(External, {})
|
|
355
693
|
] })
|
|
356
694
|
] }),
|
|
357
|
-
!direct && /* @__PURE__ */ (0,
|
|
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,
|
|
360
|
-
/* @__PURE__ */ (0,
|
|
361
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
});
|