@rhinestone/deposit-modal 0.8.1 → 0.9.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 +193 -29
- package/dist/{chunk-2JPB3PLB.mjs → DepositModalReown-6KUAO5ZC.mjs} +56 -4
- package/dist/{chunk-Q3W53BKR.cjs → DepositModalReown-XC5RIU7Z.cjs} +62 -10
- package/dist/{caip-C_ZYFIGa.d.cts → caip-523Zrc3r.d.cts} +1 -3
- package/dist/{caip-C_ZYFIGa.d.ts → caip-523Zrc3r.d.ts} +1 -3
- package/dist/{chunk-D3Y7ZBED.cjs → chunk-22RV33LK.cjs} +2170 -1460
- package/dist/chunk-4WB2FHGC.mjs +865 -0
- package/dist/chunk-A223BLVC.mjs +801 -0
- package/dist/{chunk-HQWZCOMS.cjs → chunk-DIX7M3SP.cjs} +232 -601
- package/dist/{chunk-T43VUEJH.mjs → chunk-E4G5BOZP.mjs} +167 -536
- package/dist/chunk-H577RJN5.cjs +801 -0
- package/dist/{chunk-DABKCJVL.mjs → chunk-ILT2PITN.mjs} +60 -3
- package/dist/{chunk-7KHEIMWD.mjs → chunk-KKHLNFSA.mjs} +2436 -1726
- package/dist/chunk-LGVJWVSS.mjs +81 -0
- package/dist/chunk-NEXUCY4B.cjs +11 -0
- package/dist/chunk-NMIMRASD.cjs +1785 -0
- package/dist/chunk-OSI2CFGL.mjs +11 -0
- package/dist/chunk-PAGMU4RQ.cjs +865 -0
- package/dist/chunk-T7LGQFP3.cjs +81 -0
- package/dist/chunk-VN4BLZYC.cjs +2273 -0
- package/dist/chunk-VOGZAZB2.mjs +2273 -0
- package/dist/chunk-WYXBY2MQ.mjs +1785 -0
- package/dist/{chunk-4NN7UTWQ.cjs → chunk-YEBXUUH3.cjs} +63 -6
- package/dist/claim.cjs +10 -0
- package/dist/claim.d.cts +8 -0
- package/dist/claim.d.ts +8 -0
- package/dist/claim.mjs +10 -0
- package/dist/constants.cjs +3 -3
- package/dist/constants.d.cts +4 -2
- package/dist/constants.d.ts +4 -2
- package/dist/constants.mjs +5 -5
- package/dist/deposit.cjs +8 -6
- package/dist/deposit.d.cts +2 -2
- package/dist/deposit.d.ts +2 -2
- package/dist/deposit.mjs +7 -5
- package/dist/index.cjs +22 -12
- package/dist/index.d.cts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.mjs +21 -11
- package/dist/polymarket.cjs +5 -6
- package/dist/polymarket.mjs +2 -3
- package/dist/server.cjs +96 -0
- package/dist/server.d.cts +65 -0
- package/dist/server.d.ts +65 -0
- package/dist/server.mjs +96 -0
- package/dist/styles.css +263 -12
- package/dist/types-C0SGf-21.d.cts +606 -0
- package/dist/types-C0SGf-21.d.ts +606 -0
- package/dist/withdraw.cjs +6 -5
- package/dist/withdraw.d.cts +3 -6
- package/dist/withdraw.d.ts +3 -6
- package/dist/withdraw.mjs +5 -4
- package/package.json +53 -6
- package/dist/DepositModalReown-4BSHOQ5Y.mjs +0 -63
- package/dist/DepositModalReown-UND3DEJH.cjs +0 -63
- package/dist/WithdrawModalReown-FVXSSGY5.mjs +0 -46
- package/dist/WithdrawModalReown-TVZWJKQI.cjs +0 -46
- package/dist/chunk-7OKA6GNA.cjs +0 -4537
- package/dist/chunk-NASHLEVQ.mjs +0 -4537
- package/dist/chunk-O5OKA27M.mjs +0 -800
- package/dist/chunk-U7SVYWVD.cjs +0 -800
- package/dist/chunk-WK5AFRSP.mjs +0 -295
- package/dist/chunk-XRWQMIBY.cjs +0 -295
- package/dist/types--LQWg_4W.d.cts +0 -468
- package/dist/types--LQWg_4W.d.ts +0 -468
|
@@ -0,0 +1,865 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ListRow
|
|
3
|
+
} from "./chunk-LGVJWVSS.mjs";
|
|
4
|
+
import {
|
|
5
|
+
AlertTriangleIcon,
|
|
6
|
+
BodyHeader,
|
|
7
|
+
Button,
|
|
8
|
+
Callout,
|
|
9
|
+
CdnIcon,
|
|
10
|
+
CheckIcon,
|
|
11
|
+
ChevronLeftIcon,
|
|
12
|
+
CloseIcon,
|
|
13
|
+
CoinsIcon,
|
|
14
|
+
ExternalLinkIcon,
|
|
15
|
+
HandCoinsIcon,
|
|
16
|
+
Modal,
|
|
17
|
+
PoweredBy,
|
|
18
|
+
RpcUrlsProvider,
|
|
19
|
+
TokenIcon,
|
|
20
|
+
applyTheme,
|
|
21
|
+
checkBackendUrl,
|
|
22
|
+
createDepositService,
|
|
23
|
+
debugError,
|
|
24
|
+
debugLog,
|
|
25
|
+
formatTokenAmount,
|
|
26
|
+
formatUserError,
|
|
27
|
+
useLatestRef,
|
|
28
|
+
useStableRpcUrls
|
|
29
|
+
} from "./chunk-VOGZAZB2.mjs";
|
|
30
|
+
import {
|
|
31
|
+
SERVICE_HEADERS
|
|
32
|
+
} from "./chunk-OSI2CFGL.mjs";
|
|
33
|
+
import {
|
|
34
|
+
getChainIcon,
|
|
35
|
+
getChainName,
|
|
36
|
+
getExplorerTxUrl,
|
|
37
|
+
getTokenDecimalsByAddress,
|
|
38
|
+
getTokenSymbol,
|
|
39
|
+
tokenIconUrl
|
|
40
|
+
} from "./chunk-A223BLVC.mjs";
|
|
41
|
+
|
|
42
|
+
// src/ClaimModal.tsx
|
|
43
|
+
import {
|
|
44
|
+
useCallback,
|
|
45
|
+
useEffect,
|
|
46
|
+
useMemo,
|
|
47
|
+
useReducer,
|
|
48
|
+
useRef,
|
|
49
|
+
useState
|
|
50
|
+
} from "react";
|
|
51
|
+
import { formatUnits, isAddress } from "viem";
|
|
52
|
+
|
|
53
|
+
// src/components/ui/Input.tsx
|
|
54
|
+
import { forwardRef } from "react";
|
|
55
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
56
|
+
var Input = forwardRef(
|
|
57
|
+
({ label, error, variant, className = "", ...props }, ref) => {
|
|
58
|
+
const inputVariant = error ? "error" : variant || "default";
|
|
59
|
+
return /* @__PURE__ */ jsxs("div", { className: "rs-input-wrapper", children: [
|
|
60
|
+
label && /* @__PURE__ */ jsx("label", { className: "rs-input-label", children: label }),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
"input",
|
|
63
|
+
{
|
|
64
|
+
ref,
|
|
65
|
+
className: `rs-input rs-input--${inputVariant} ${className}`,
|
|
66
|
+
...props
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
error && /* @__PURE__ */ jsxs("p", { className: "rs-input-error", children: [
|
|
70
|
+
/* @__PURE__ */ jsx(AlertTriangleIcon, { className: "rs-input-error-icon" }),
|
|
71
|
+
error
|
|
72
|
+
] })
|
|
73
|
+
] });
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
Input.displayName = "Input";
|
|
77
|
+
|
|
78
|
+
// src/core/recovery.ts
|
|
79
|
+
var RECOVER_DOMAIN = {
|
|
80
|
+
name: "Rhinestone Deposit Recovery",
|
|
81
|
+
version: "1"
|
|
82
|
+
};
|
|
83
|
+
var RECOVER_TYPES = {
|
|
84
|
+
RecoverDeposit: [
|
|
85
|
+
{ name: "depositId", type: "uint256" },
|
|
86
|
+
{ name: "destination", type: "address" }
|
|
87
|
+
]
|
|
88
|
+
};
|
|
89
|
+
var RecoveryError = class extends Error {
|
|
90
|
+
constructor(message, status, code, retryable = false) {
|
|
91
|
+
super(message);
|
|
92
|
+
this.name = "RecoveryError";
|
|
93
|
+
this.status = status;
|
|
94
|
+
this.code = code;
|
|
95
|
+
this.retryable = retryable;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
function formatRecoveryError(status, code, serverMessage) {
|
|
99
|
+
switch (code) {
|
|
100
|
+
case "DEPOSIT_NOT_RECOVERABLE":
|
|
101
|
+
return {
|
|
102
|
+
message: "This deposit can't be recovered \u2014 it may already have been claimed.",
|
|
103
|
+
retryable: false
|
|
104
|
+
};
|
|
105
|
+
case "RECOVERY_UNSUPPORTED":
|
|
106
|
+
return {
|
|
107
|
+
message: "This deposit can't be recovered automatically. Contact support to get your funds back.",
|
|
108
|
+
retryable: false
|
|
109
|
+
};
|
|
110
|
+
case "SIGNATURE_INVALID":
|
|
111
|
+
return {
|
|
112
|
+
message: "That signature wasn't accepted for this wallet. Contact support to recover this deposit.",
|
|
113
|
+
retryable: false
|
|
114
|
+
};
|
|
115
|
+
case "VERIFICATION_UNAVAILABLE":
|
|
116
|
+
return {
|
|
117
|
+
message: "Couldn't verify your signature just now. Try again shortly.",
|
|
118
|
+
retryable: true
|
|
119
|
+
};
|
|
120
|
+
case "REFUND_RECONCILIATION_REQUIRED":
|
|
121
|
+
return {
|
|
122
|
+
message: "Your recovery is being reviewed. Contact support with this deposit if it doesn't arrive.",
|
|
123
|
+
retryable: false
|
|
124
|
+
};
|
|
125
|
+
case "REFUND_FAILED":
|
|
126
|
+
return {
|
|
127
|
+
message: serverMessage ?? "The recovery couldn't be completed. Please try again or contact support.",
|
|
128
|
+
retryable: true
|
|
129
|
+
};
|
|
130
|
+
default:
|
|
131
|
+
if (status === 0) {
|
|
132
|
+
return {
|
|
133
|
+
message: "Couldn't reach the recovery service. Check your connection and try again.",
|
|
134
|
+
retryable: true
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
message: serverMessage ?? "The recovery couldn't be completed. Please try again or contact support.",
|
|
139
|
+
retryable: true
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async function submitSignedRecovery(params) {
|
|
144
|
+
const { backendUrl, depositId, signer, destination, signRecovery, debug } = params;
|
|
145
|
+
const scope = "service:recovery";
|
|
146
|
+
const typedData = {
|
|
147
|
+
domain: RECOVER_DOMAIN,
|
|
148
|
+
types: RECOVER_TYPES,
|
|
149
|
+
primaryType: "RecoverDeposit",
|
|
150
|
+
message: { depositId: BigInt(depositId), destination }
|
|
151
|
+
};
|
|
152
|
+
let signature;
|
|
153
|
+
try {
|
|
154
|
+
signature = await signRecovery({ typedData, signer, depositId, destination });
|
|
155
|
+
} catch (error) {
|
|
156
|
+
debugError(debug, scope, "signRecovery:failed", error);
|
|
157
|
+
throw new RecoveryError(
|
|
158
|
+
"Signature request was declined. Approve it in your wallet to recover this deposit.",
|
|
159
|
+
0,
|
|
160
|
+
void 0,
|
|
161
|
+
true
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
if (!signature) {
|
|
165
|
+
throw new RecoveryError(
|
|
166
|
+
"Signature request was declined. Approve it in your wallet to recover this deposit.",
|
|
167
|
+
0,
|
|
168
|
+
void 0,
|
|
169
|
+
true
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
const url = `${backendUrl.replace(/\/$/, "")}/deposits/recover`;
|
|
173
|
+
debugLog(debug, scope, "submitSignedRecovery:request", {
|
|
174
|
+
url,
|
|
175
|
+
depositId,
|
|
176
|
+
signer
|
|
177
|
+
});
|
|
178
|
+
let response;
|
|
179
|
+
try {
|
|
180
|
+
response = await fetch(url, {
|
|
181
|
+
method: "POST",
|
|
182
|
+
// The shared const, so recovery carries `x-deposit-modal-version` like
|
|
183
|
+
// every other backend call. Without it this path would be invisible in the
|
|
184
|
+
// per-client version telemetry the processor records.
|
|
185
|
+
headers: SERVICE_HEADERS,
|
|
186
|
+
// `depositId` as a string: it is a uint256 upstream and JSON numbers lose
|
|
187
|
+
// precision well before that range.
|
|
188
|
+
body: JSON.stringify({ depositId, destination, signature })
|
|
189
|
+
});
|
|
190
|
+
} catch (error) {
|
|
191
|
+
debugError(debug, scope, "submitSignedRecovery:network", error);
|
|
192
|
+
const { message, retryable } = formatRecoveryError(0);
|
|
193
|
+
throw new RecoveryError(message, 0, void 0, retryable);
|
|
194
|
+
}
|
|
195
|
+
if (!response.ok) {
|
|
196
|
+
const body = await response.json().catch(() => ({}));
|
|
197
|
+
debugError(debug, scope, "submitSignedRecovery:failed", body, {
|
|
198
|
+
status: response.status
|
|
199
|
+
});
|
|
200
|
+
const { message, retryable } = formatRecoveryError(
|
|
201
|
+
response.status,
|
|
202
|
+
body.code,
|
|
203
|
+
body.error
|
|
204
|
+
);
|
|
205
|
+
throw new RecoveryError(message, response.status, body.code, retryable);
|
|
206
|
+
}
|
|
207
|
+
const result = await response.json();
|
|
208
|
+
debugLog(debug, scope, "submitSignedRecovery:success", {
|
|
209
|
+
transactionHash: result.transactionHash
|
|
210
|
+
});
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// src/ClaimModal.tsx
|
|
215
|
+
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
216
|
+
function evmChainIdFromCaip2(chain) {
|
|
217
|
+
if (!chain?.startsWith("eip155:")) return null;
|
|
218
|
+
const id = Number.parseInt(chain.slice("eip155:".length), 10);
|
|
219
|
+
return Number.isFinite(id) ? id : null;
|
|
220
|
+
}
|
|
221
|
+
function isEligible(row) {
|
|
222
|
+
return row.status === "failed" || row.status === "rejected";
|
|
223
|
+
}
|
|
224
|
+
function describeDeposit(row) {
|
|
225
|
+
const chainId = evmChainIdFromCaip2(row.chain) ?? 0;
|
|
226
|
+
const decimals = getTokenDecimalsByAddress(row.token, chainId);
|
|
227
|
+
const symbol = getTokenSymbol(row.token, chainId);
|
|
228
|
+
const raw = BigInt(row.sourceAmount ?? row.amount ?? "0");
|
|
229
|
+
const human = Number(formatUnits(raw, decimals));
|
|
230
|
+
const amount = formatTokenAmount(human, symbol) ?? formatUnits(raw, decimals);
|
|
231
|
+
return {
|
|
232
|
+
chainId,
|
|
233
|
+
symbol,
|
|
234
|
+
amount,
|
|
235
|
+
chainName: getChainName(chainId),
|
|
236
|
+
chainIcon: getChainIcon(chainId)
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function shortenHash(hash) {
|
|
240
|
+
return `${hash.slice(0, 10)}\u2026${hash.slice(-8)}`;
|
|
241
|
+
}
|
|
242
|
+
function shortenAddress(addr) {
|
|
243
|
+
return addr.length > 12 ? `${addr.slice(0, 6)}\u2026${addr.slice(-4)}` : addr;
|
|
244
|
+
}
|
|
245
|
+
function humanizeStatus(status) {
|
|
246
|
+
if (!status) return void 0;
|
|
247
|
+
const spaced = status.replace(/[_-]+/g, " ").trim();
|
|
248
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
|
249
|
+
}
|
|
250
|
+
var INITIAL_STATE = {
|
|
251
|
+
step: "lookup",
|
|
252
|
+
deposits: [],
|
|
253
|
+
selected: null,
|
|
254
|
+
result: null,
|
|
255
|
+
error: null,
|
|
256
|
+
retryable: true
|
|
257
|
+
};
|
|
258
|
+
function claimReducer(state, action) {
|
|
259
|
+
switch (action.type) {
|
|
260
|
+
case "lookup/results":
|
|
261
|
+
return {
|
|
262
|
+
...state,
|
|
263
|
+
deposits: action.deposits,
|
|
264
|
+
selected: action.autoSelect,
|
|
265
|
+
step: action.autoSelect ? "review" : "select",
|
|
266
|
+
error: null
|
|
267
|
+
};
|
|
268
|
+
case "select":
|
|
269
|
+
return { ...state, selected: action.deposit, step: "review", error: null };
|
|
270
|
+
case "back":
|
|
271
|
+
if (state.step === "failed") return { ...state, step: "review", error: null };
|
|
272
|
+
if (state.step === "review")
|
|
273
|
+
return {
|
|
274
|
+
...state,
|
|
275
|
+
step: state.deposits.length > 1 ? "select" : "lookup",
|
|
276
|
+
error: null
|
|
277
|
+
};
|
|
278
|
+
if (state.step === "select") return { ...INITIAL_STATE };
|
|
279
|
+
return state;
|
|
280
|
+
case "submit":
|
|
281
|
+
return { ...state, step: "processing", error: null };
|
|
282
|
+
case "complete":
|
|
283
|
+
return {
|
|
284
|
+
...state,
|
|
285
|
+
step: "complete",
|
|
286
|
+
result: {
|
|
287
|
+
txHash: action.txHash,
|
|
288
|
+
amount: action.amount,
|
|
289
|
+
amountDisplay: action.amountDisplay,
|
|
290
|
+
symbol: action.symbol,
|
|
291
|
+
destination: action.destination,
|
|
292
|
+
chain: action.chain
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
case "failed":
|
|
296
|
+
return {
|
|
297
|
+
...state,
|
|
298
|
+
step: "failed",
|
|
299
|
+
error: action.error,
|
|
300
|
+
retryable: action.retryable ?? true
|
|
301
|
+
};
|
|
302
|
+
case "reset":
|
|
303
|
+
return { ...INITIAL_STATE };
|
|
304
|
+
default:
|
|
305
|
+
return state;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function ClaimModal({
|
|
309
|
+
signRecovery,
|
|
310
|
+
isOpen,
|
|
311
|
+
onClose,
|
|
312
|
+
inline,
|
|
313
|
+
closeOnOverlayClick,
|
|
314
|
+
backendUrl,
|
|
315
|
+
rpcUrls: rpcUrlsProp,
|
|
316
|
+
defaultTxHash,
|
|
317
|
+
defaultRefundDestination,
|
|
318
|
+
theme,
|
|
319
|
+
uiConfig,
|
|
320
|
+
className,
|
|
321
|
+
onReady,
|
|
322
|
+
onLifecycle,
|
|
323
|
+
onEvent,
|
|
324
|
+
onError,
|
|
325
|
+
debug
|
|
326
|
+
}) {
|
|
327
|
+
checkBackendUrl("ClaimModal", backendUrl);
|
|
328
|
+
const modalRef = useRef(null);
|
|
329
|
+
const onReadyRef = useLatestRef(onReady);
|
|
330
|
+
const onLifecycleRef = useLatestRef(onLifecycle);
|
|
331
|
+
const onEventRef = useLatestRef(onEvent);
|
|
332
|
+
const onErrorRef = useLatestRef(onError);
|
|
333
|
+
const rpcUrls = useStableRpcUrls(rpcUrlsProp);
|
|
334
|
+
const service = useMemo(
|
|
335
|
+
() => createDepositService(backendUrl, { debug, debugScope: "service:claim" }),
|
|
336
|
+
[backendUrl, debug]
|
|
337
|
+
);
|
|
338
|
+
const [state, dispatch] = useReducer(claimReducer, INITIAL_STATE);
|
|
339
|
+
const operationEpochRef = useRef(0);
|
|
340
|
+
const isOpenRef = useRef(isOpen);
|
|
341
|
+
isOpenRef.current = isOpen;
|
|
342
|
+
useEffect(() => {
|
|
343
|
+
if (isOpen && modalRef.current) applyTheme(modalRef.current, theme);
|
|
344
|
+
}, [isOpen, theme]);
|
|
345
|
+
useEffect(() => {
|
|
346
|
+
if (isOpen) {
|
|
347
|
+
onReadyRef.current?.();
|
|
348
|
+
onEventRef.current?.({ type: "claim_modal_open" });
|
|
349
|
+
}
|
|
350
|
+
}, [isOpen, onReadyRef, onEventRef]);
|
|
351
|
+
useEffect(() => {
|
|
352
|
+
if (!isOpen) {
|
|
353
|
+
operationEpochRef.current += 1;
|
|
354
|
+
dispatch({ type: "reset" });
|
|
355
|
+
}
|
|
356
|
+
}, [isOpen]);
|
|
357
|
+
const handleClose = useCallback(() => {
|
|
358
|
+
if (state.step !== "processing") {
|
|
359
|
+
operationEpochRef.current += 1;
|
|
360
|
+
onClose();
|
|
361
|
+
}
|
|
362
|
+
}, [state.step, onClose]);
|
|
363
|
+
const canGoBack = state.step === "select" || state.step === "review" || state.step === "failed";
|
|
364
|
+
const showBackButton = uiConfig?.showBackButton ?? true;
|
|
365
|
+
return /* @__PURE__ */ jsx2(RpcUrlsProvider, { value: rpcUrls, children: /* @__PURE__ */ jsx2(
|
|
366
|
+
Modal,
|
|
367
|
+
{
|
|
368
|
+
isOpen,
|
|
369
|
+
onClose: handleClose,
|
|
370
|
+
className,
|
|
371
|
+
inline,
|
|
372
|
+
closeOnOverlayClick,
|
|
373
|
+
children: /* @__PURE__ */ jsxs2("div", { ref: modalRef, className: "rs-modal", children: [
|
|
374
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-modal-header--redesigned", children: [
|
|
375
|
+
/* @__PURE__ */ jsx2("div", { className: "rs-modal-header-nav-left", children: showBackButton && canGoBack && /* @__PURE__ */ jsx2(
|
|
376
|
+
"button",
|
|
377
|
+
{
|
|
378
|
+
type: "button",
|
|
379
|
+
className: "rs-modal-header-back",
|
|
380
|
+
"aria-label": "Go back",
|
|
381
|
+
onClick: () => dispatch({ type: "back" }),
|
|
382
|
+
children: /* @__PURE__ */ jsx2(ChevronLeftIcon, {})
|
|
383
|
+
}
|
|
384
|
+
) }),
|
|
385
|
+
/* @__PURE__ */ jsx2("div", { className: "rs-modal-header-nav-right", children: /* @__PURE__ */ jsx2(
|
|
386
|
+
"button",
|
|
387
|
+
{
|
|
388
|
+
type: "button",
|
|
389
|
+
onClick: handleClose,
|
|
390
|
+
disabled: state.step === "processing",
|
|
391
|
+
className: "rs-modal-close",
|
|
392
|
+
"aria-label": "Close",
|
|
393
|
+
children: /* @__PURE__ */ jsx2(CloseIcon, {})
|
|
394
|
+
}
|
|
395
|
+
) })
|
|
396
|
+
] }),
|
|
397
|
+
/* @__PURE__ */ jsx2("div", { className: "rs-modal-body", children: /* @__PURE__ */ jsx2(
|
|
398
|
+
ClaimBody,
|
|
399
|
+
{
|
|
400
|
+
state,
|
|
401
|
+
dispatch,
|
|
402
|
+
service,
|
|
403
|
+
signRecovery,
|
|
404
|
+
backendUrl,
|
|
405
|
+
debug,
|
|
406
|
+
defaultTxHash,
|
|
407
|
+
defaultRefundDestination,
|
|
408
|
+
onClose: handleClose,
|
|
409
|
+
operationEpochRef,
|
|
410
|
+
isOpenRef,
|
|
411
|
+
onLifecycleRef,
|
|
412
|
+
onEventRef,
|
|
413
|
+
onErrorRef
|
|
414
|
+
}
|
|
415
|
+
) })
|
|
416
|
+
] })
|
|
417
|
+
}
|
|
418
|
+
) });
|
|
419
|
+
}
|
|
420
|
+
function ClaimBody({
|
|
421
|
+
state,
|
|
422
|
+
dispatch,
|
|
423
|
+
service,
|
|
424
|
+
signRecovery,
|
|
425
|
+
backendUrl,
|
|
426
|
+
debug,
|
|
427
|
+
defaultTxHash,
|
|
428
|
+
defaultRefundDestination,
|
|
429
|
+
onClose,
|
|
430
|
+
operationEpochRef,
|
|
431
|
+
isOpenRef,
|
|
432
|
+
onLifecycleRef,
|
|
433
|
+
onEventRef,
|
|
434
|
+
onErrorRef
|
|
435
|
+
}) {
|
|
436
|
+
switch (state.step) {
|
|
437
|
+
case "lookup":
|
|
438
|
+
return /* @__PURE__ */ jsx2(
|
|
439
|
+
LookupStep,
|
|
440
|
+
{
|
|
441
|
+
service,
|
|
442
|
+
defaultTxHash,
|
|
443
|
+
operationEpochRef,
|
|
444
|
+
isOpenRef,
|
|
445
|
+
onResults: (deposits) => {
|
|
446
|
+
const eligible = deposits.filter(isEligible);
|
|
447
|
+
const autoSelect = deposits.length === 1 && eligible.length === 1 ? deposits[0] : null;
|
|
448
|
+
dispatch({ type: "lookup/results", deposits, autoSelect });
|
|
449
|
+
},
|
|
450
|
+
onLifecycleRef,
|
|
451
|
+
onEventRef,
|
|
452
|
+
onErrorRef
|
|
453
|
+
}
|
|
454
|
+
);
|
|
455
|
+
case "select":
|
|
456
|
+
return /* @__PURE__ */ jsx2(
|
|
457
|
+
SelectStep,
|
|
458
|
+
{
|
|
459
|
+
deposits: state.deposits,
|
|
460
|
+
onSelect: (deposit) => dispatch({ type: "select", deposit })
|
|
461
|
+
}
|
|
462
|
+
);
|
|
463
|
+
case "review":
|
|
464
|
+
case "processing":
|
|
465
|
+
return /* @__PURE__ */ jsx2(
|
|
466
|
+
ReviewStep,
|
|
467
|
+
{
|
|
468
|
+
deposit: state.selected,
|
|
469
|
+
submitting: state.step === "processing",
|
|
470
|
+
defaultRefundDestination,
|
|
471
|
+
onSubmit: (destination) => submitRecoveryRequest(destination)
|
|
472
|
+
}
|
|
473
|
+
);
|
|
474
|
+
case "complete":
|
|
475
|
+
return /* @__PURE__ */ jsx2(ResultStep, { result: state.result, onClose, onReset: () => dispatch({ type: "reset" }) });
|
|
476
|
+
case "failed":
|
|
477
|
+
return /* @__PURE__ */ jsx2(
|
|
478
|
+
ResultStep,
|
|
479
|
+
{
|
|
480
|
+
error: state.error,
|
|
481
|
+
onClose,
|
|
482
|
+
onRetry: state.retryable ? () => dispatch({ type: "back" }) : void 0
|
|
483
|
+
}
|
|
484
|
+
);
|
|
485
|
+
default:
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
async function submitRecoveryRequest(destination) {
|
|
489
|
+
const deposit = state.selected;
|
|
490
|
+
if (!deposit) return;
|
|
491
|
+
const sourceChainId = evmChainIdFromCaip2(deposit.chain);
|
|
492
|
+
if (sourceChainId == null || !deposit.id || !deposit.recipient || !deposit.depositAddress || !deposit.token || !deposit.chain) {
|
|
493
|
+
dispatch({
|
|
494
|
+
type: "failed",
|
|
495
|
+
error: "Deposit is missing data required to recover it."
|
|
496
|
+
});
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const signer = deposit.recipient;
|
|
500
|
+
const account = deposit.depositAddress;
|
|
501
|
+
const token = deposit.token;
|
|
502
|
+
const operationEpoch = operationEpochRef.current;
|
|
503
|
+
const isCurrentOperation = () => isOpenRef.current && operationEpochRef.current === operationEpoch;
|
|
504
|
+
dispatch({ type: "submit" });
|
|
505
|
+
onEventRef.current?.({
|
|
506
|
+
type: "claim_modal_refund_click",
|
|
507
|
+
chain: `eip155:${sourceChainId}`
|
|
508
|
+
});
|
|
509
|
+
onLifecycleRef.current?.({
|
|
510
|
+
type: "refund_requested",
|
|
511
|
+
account,
|
|
512
|
+
destination,
|
|
513
|
+
chain: sourceChainId
|
|
514
|
+
});
|
|
515
|
+
try {
|
|
516
|
+
const result = await submitSignedRecovery({
|
|
517
|
+
backendUrl,
|
|
518
|
+
depositId: deposit.id,
|
|
519
|
+
signer,
|
|
520
|
+
destination,
|
|
521
|
+
signRecovery,
|
|
522
|
+
debug
|
|
523
|
+
});
|
|
524
|
+
if (!isCurrentOperation()) return;
|
|
525
|
+
const paidTo = destination;
|
|
526
|
+
const decimals = getTokenDecimalsByAddress(token, sourceChainId);
|
|
527
|
+
const symbol = getTokenSymbol(token, sourceChainId);
|
|
528
|
+
const refundedRaw = BigInt(
|
|
529
|
+
result.amount ?? deposit.sourceAmount ?? deposit.amount ?? "0"
|
|
530
|
+
);
|
|
531
|
+
const amountDisplay = formatTokenAmount(Number(formatUnits(refundedRaw, decimals)), symbol) ?? formatUnits(refundedRaw, decimals);
|
|
532
|
+
dispatch({
|
|
533
|
+
type: "complete",
|
|
534
|
+
txHash: result.transactionHash,
|
|
535
|
+
amount: result.amount,
|
|
536
|
+
amountDisplay,
|
|
537
|
+
symbol,
|
|
538
|
+
destination: paidTo,
|
|
539
|
+
chain: sourceChainId
|
|
540
|
+
});
|
|
541
|
+
onEventRef.current?.({
|
|
542
|
+
type: "claim_modal_complete",
|
|
543
|
+
chain: `eip155:${sourceChainId}`
|
|
544
|
+
});
|
|
545
|
+
onLifecycleRef.current?.({
|
|
546
|
+
type: "complete",
|
|
547
|
+
txHash: result.transactionHash,
|
|
548
|
+
account,
|
|
549
|
+
destination: paidTo,
|
|
550
|
+
chain: sourceChainId,
|
|
551
|
+
token,
|
|
552
|
+
amount: result.amount
|
|
553
|
+
});
|
|
554
|
+
} catch (err) {
|
|
555
|
+
if (!isCurrentOperation()) return;
|
|
556
|
+
const recoveryError = err instanceof RecoveryError ? err : void 0;
|
|
557
|
+
const status = recoveryError?.status;
|
|
558
|
+
const message = recoveryError?.message ?? formatUserError(
|
|
559
|
+
err instanceof Error ? err.message : "Recovery failed"
|
|
560
|
+
);
|
|
561
|
+
dispatch({
|
|
562
|
+
type: "failed",
|
|
563
|
+
error: message,
|
|
564
|
+
retryable: recoveryError?.retryable ?? true
|
|
565
|
+
});
|
|
566
|
+
onEventRef.current?.({
|
|
567
|
+
type: "claim_modal_failed",
|
|
568
|
+
chain: `eip155:${sourceChainId}`,
|
|
569
|
+
status
|
|
570
|
+
});
|
|
571
|
+
onLifecycleRef.current?.({ type: "failed", status, error: message });
|
|
572
|
+
onErrorRef.current?.({ message, code: "CLAIM_FAILED" });
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
function LookupStep({
|
|
577
|
+
service,
|
|
578
|
+
defaultTxHash,
|
|
579
|
+
operationEpochRef,
|
|
580
|
+
isOpenRef,
|
|
581
|
+
onResults,
|
|
582
|
+
onLifecycleRef,
|
|
583
|
+
onEventRef,
|
|
584
|
+
onErrorRef
|
|
585
|
+
}) {
|
|
586
|
+
const [txHash, setTxHash] = useState(defaultTxHash ?? "");
|
|
587
|
+
const [loading, setLoading] = useState(false);
|
|
588
|
+
const [error, setError] = useState(null);
|
|
589
|
+
const trimmed = txHash.trim();
|
|
590
|
+
const validTxHash = /^0x[a-fA-F0-9]{64}$/.test(trimmed);
|
|
591
|
+
const handleLookup = useCallback(async () => {
|
|
592
|
+
const operationEpoch = operationEpochRef.current;
|
|
593
|
+
const isCurrentOperation = () => isOpenRef.current && operationEpochRef.current === operationEpoch;
|
|
594
|
+
setError(null);
|
|
595
|
+
setLoading(true);
|
|
596
|
+
try {
|
|
597
|
+
const deposits = await service.lookupRecoverableDeposits({
|
|
598
|
+
txHash: trimmed
|
|
599
|
+
});
|
|
600
|
+
if (!isCurrentOperation()) return;
|
|
601
|
+
onLifecycleRef.current?.({
|
|
602
|
+
type: "lookup",
|
|
603
|
+
txHash: trimmed,
|
|
604
|
+
matches: deposits.length
|
|
605
|
+
});
|
|
606
|
+
onEventRef.current?.({
|
|
607
|
+
type: "claim_modal_lookup",
|
|
608
|
+
matches: deposits.length
|
|
609
|
+
});
|
|
610
|
+
if (deposits.length === 0) {
|
|
611
|
+
setError("No deposits found for this transaction.");
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
if (!deposits.some(isEligible)) {
|
|
615
|
+
setError(
|
|
616
|
+
"This transaction has no failed or rejected deposits available to recover."
|
|
617
|
+
);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
onResults(deposits);
|
|
621
|
+
} catch (err) {
|
|
622
|
+
if (!isCurrentOperation()) return;
|
|
623
|
+
const message = formatUserError(
|
|
624
|
+
err instanceof Error ? err.message : "Lookup failed"
|
|
625
|
+
);
|
|
626
|
+
setError(message);
|
|
627
|
+
onErrorRef.current?.({ message, code: "CLAIM_LOOKUP_FAILED" });
|
|
628
|
+
} finally {
|
|
629
|
+
if (isCurrentOperation()) setLoading(false);
|
|
630
|
+
}
|
|
631
|
+
}, [
|
|
632
|
+
trimmed,
|
|
633
|
+
service,
|
|
634
|
+
operationEpochRef,
|
|
635
|
+
isOpenRef,
|
|
636
|
+
onResults,
|
|
637
|
+
onLifecycleRef,
|
|
638
|
+
onEventRef,
|
|
639
|
+
onErrorRef
|
|
640
|
+
]);
|
|
641
|
+
return /* @__PURE__ */ jsxs2("div", { className: "rs-screen", children: [
|
|
642
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
|
|
643
|
+
/* @__PURE__ */ jsx2(
|
|
644
|
+
BodyHeader,
|
|
645
|
+
{
|
|
646
|
+
icon: /* @__PURE__ */ jsx2(HandCoinsIcon, {}),
|
|
647
|
+
title: "Claim a deposit",
|
|
648
|
+
subtitle: "Get funds from a failed deposit sent back to you on the source chain."
|
|
649
|
+
}
|
|
650
|
+
),
|
|
651
|
+
/* @__PURE__ */ jsx2(
|
|
652
|
+
Input,
|
|
653
|
+
{
|
|
654
|
+
label: "Transaction hash",
|
|
655
|
+
placeholder: "0x\u2026",
|
|
656
|
+
value: txHash,
|
|
657
|
+
onChange: (e) => setTxHash(e.target.value),
|
|
658
|
+
error: trimmed.length > 0 && !validTxHash ? "Enter a valid transaction hash" : void 0
|
|
659
|
+
}
|
|
660
|
+
),
|
|
661
|
+
error && /* @__PURE__ */ jsx2(Callout, { variant: "error", children: error }),
|
|
662
|
+
/* @__PURE__ */ jsx2(
|
|
663
|
+
Button,
|
|
664
|
+
{
|
|
665
|
+
onClick: handleLookup,
|
|
666
|
+
loading,
|
|
667
|
+
loadingText: "Searching\u2026",
|
|
668
|
+
disabled: !validTxHash,
|
|
669
|
+
fullWidth: true,
|
|
670
|
+
children: "Find deposit"
|
|
671
|
+
}
|
|
672
|
+
)
|
|
673
|
+
] }),
|
|
674
|
+
/* @__PURE__ */ jsx2(PoweredBy, {})
|
|
675
|
+
] });
|
|
676
|
+
}
|
|
677
|
+
function SelectStep({
|
|
678
|
+
deposits,
|
|
679
|
+
onSelect
|
|
680
|
+
}) {
|
|
681
|
+
return /* @__PURE__ */ jsxs2("div", { className: "rs-screen", children: [
|
|
682
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
|
|
683
|
+
/* @__PURE__ */ jsx2(
|
|
684
|
+
BodyHeader,
|
|
685
|
+
{
|
|
686
|
+
icon: /* @__PURE__ */ jsx2(CoinsIcon, {}),
|
|
687
|
+
title: "Select a deposit",
|
|
688
|
+
subtitle: "This transaction produced multiple deposits. Choose the one to claim."
|
|
689
|
+
}
|
|
690
|
+
),
|
|
691
|
+
/* @__PURE__ */ jsx2("div", { className: "rs-list", children: deposits.map((row) => {
|
|
692
|
+
const { symbol, amount, chainName } = describeDeposit(row);
|
|
693
|
+
const eligible = isEligible(row);
|
|
694
|
+
return /* @__PURE__ */ jsx2(
|
|
695
|
+
ListRow,
|
|
696
|
+
{
|
|
697
|
+
leadingMedia: tokenIconUrl(symbol),
|
|
698
|
+
title: `${amount} ${symbol}`,
|
|
699
|
+
subtitle: chainName,
|
|
700
|
+
meta: eligible ? void 0 : humanizeStatus(row.status),
|
|
701
|
+
disabled: !eligible,
|
|
702
|
+
onClick: () => eligible && onSelect(row)
|
|
703
|
+
},
|
|
704
|
+
row.id ?? `${row.depositAddress}:${row.token}`
|
|
705
|
+
);
|
|
706
|
+
}) })
|
|
707
|
+
] }),
|
|
708
|
+
/* @__PURE__ */ jsx2(PoweredBy, {})
|
|
709
|
+
] });
|
|
710
|
+
}
|
|
711
|
+
function ReviewStep({
|
|
712
|
+
deposit,
|
|
713
|
+
submitting,
|
|
714
|
+
defaultRefundDestination,
|
|
715
|
+
onSubmit
|
|
716
|
+
}) {
|
|
717
|
+
const { chainId, symbol, amount, chainName, chainIcon } = describeDeposit(deposit);
|
|
718
|
+
const [destination, setDestination] = useState(defaultRefundDestination ?? "");
|
|
719
|
+
const destinationValid = isAddress(destination);
|
|
720
|
+
return /* @__PURE__ */ jsxs2("div", { className: "rs-screen", children: [
|
|
721
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
|
|
722
|
+
/* @__PURE__ */ jsx2(
|
|
723
|
+
BodyHeader,
|
|
724
|
+
{
|
|
725
|
+
icon: /* @__PURE__ */ jsx2(HandCoinsIcon, {}),
|
|
726
|
+
title: "Review refund",
|
|
727
|
+
subtitle: "This returns the funds on the source chain. It does not retry the original bridge."
|
|
728
|
+
}
|
|
729
|
+
),
|
|
730
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-review-details", children: [
|
|
731
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-review-detail-row", children: [
|
|
732
|
+
/* @__PURE__ */ jsx2("span", { children: "Amount" }),
|
|
733
|
+
/* @__PURE__ */ jsxs2("span", { className: "rs-review-detail-value", children: [
|
|
734
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
735
|
+
amount,
|
|
736
|
+
" ",
|
|
737
|
+
symbol
|
|
738
|
+
] }),
|
|
739
|
+
/* @__PURE__ */ jsx2("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx2(TokenIcon, { symbol }) })
|
|
740
|
+
] })
|
|
741
|
+
] }),
|
|
742
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-review-detail-row", children: [
|
|
743
|
+
/* @__PURE__ */ jsx2("span", { children: "Source chain" }),
|
|
744
|
+
/* @__PURE__ */ jsxs2("span", { className: "rs-review-detail-value", children: [
|
|
745
|
+
/* @__PURE__ */ jsx2("span", { children: chainName }),
|
|
746
|
+
chainIcon && /* @__PURE__ */ jsx2("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx2(CdnIcon, { src: chainIcon }) })
|
|
747
|
+
] })
|
|
748
|
+
] }),
|
|
749
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-review-detail-row", children: [
|
|
750
|
+
/* @__PURE__ */ jsx2("span", { children: "Deposit transaction" }),
|
|
751
|
+
(() => {
|
|
752
|
+
const url = deposit.txHash ? getExplorerTxUrl(chainId, deposit.txHash) : null;
|
|
753
|
+
const short = deposit.txHash ? shortenHash(deposit.txHash) : "\u2014";
|
|
754
|
+
return url ? /* @__PURE__ */ jsxs2(
|
|
755
|
+
"a",
|
|
756
|
+
{
|
|
757
|
+
className: "rs-review-detail-value rs-link",
|
|
758
|
+
href: url,
|
|
759
|
+
target: "_blank",
|
|
760
|
+
rel: "noreferrer",
|
|
761
|
+
children: [
|
|
762
|
+
short,
|
|
763
|
+
/* @__PURE__ */ jsx2(ExternalLinkIcon, {})
|
|
764
|
+
]
|
|
765
|
+
}
|
|
766
|
+
) : /* @__PURE__ */ jsx2("span", { className: "rs-review-detail-value", children: short });
|
|
767
|
+
})()
|
|
768
|
+
] })
|
|
769
|
+
] }),
|
|
770
|
+
/* @__PURE__ */ jsx2(
|
|
771
|
+
Input,
|
|
772
|
+
{
|
|
773
|
+
label: "Send to",
|
|
774
|
+
placeholder: "0x\u2026",
|
|
775
|
+
value: destination,
|
|
776
|
+
onChange: (e) => setDestination(e.target.value),
|
|
777
|
+
error: destination.length > 0 && !destinationValid ? "Enter a valid address" : void 0
|
|
778
|
+
}
|
|
779
|
+
),
|
|
780
|
+
/* @__PURE__ */ jsx2(
|
|
781
|
+
Button,
|
|
782
|
+
{
|
|
783
|
+
onClick: () => destinationValid && onSubmit(destination),
|
|
784
|
+
loading: submitting,
|
|
785
|
+
loadingText: "Refunding\u2026",
|
|
786
|
+
disabled: !destinationValid,
|
|
787
|
+
fullWidth: true,
|
|
788
|
+
children: "Claim refund"
|
|
789
|
+
}
|
|
790
|
+
)
|
|
791
|
+
] }),
|
|
792
|
+
/* @__PURE__ */ jsx2(PoweredBy, {})
|
|
793
|
+
] });
|
|
794
|
+
}
|
|
795
|
+
function ResultStep({
|
|
796
|
+
result,
|
|
797
|
+
error,
|
|
798
|
+
onClose,
|
|
799
|
+
onReset,
|
|
800
|
+
onRetry
|
|
801
|
+
}) {
|
|
802
|
+
const success = !!result;
|
|
803
|
+
return /* @__PURE__ */ jsxs2("div", { className: "rs-screen", children: [
|
|
804
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
|
|
805
|
+
/* @__PURE__ */ jsx2(
|
|
806
|
+
BodyHeader,
|
|
807
|
+
{
|
|
808
|
+
icon: success ? /* @__PURE__ */ jsx2(CheckIcon, {}) : /* @__PURE__ */ jsx2(AlertTriangleIcon, {}),
|
|
809
|
+
variant: success ? "success" : "error",
|
|
810
|
+
title: success ? "Refund submitted" : "Refund failed",
|
|
811
|
+
subtitle: success ? "Your funds are being returned on the source chain." : void 0
|
|
812
|
+
}
|
|
813
|
+
),
|
|
814
|
+
success ? /* @__PURE__ */ jsxs2("div", { className: "rs-review-details", children: [
|
|
815
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-review-detail-row", children: [
|
|
816
|
+
/* @__PURE__ */ jsx2("span", { children: "Amount" }),
|
|
817
|
+
/* @__PURE__ */ jsxs2("span", { className: "rs-review-detail-value", children: [
|
|
818
|
+
/* @__PURE__ */ jsxs2("span", { children: [
|
|
819
|
+
result.amountDisplay,
|
|
820
|
+
" ",
|
|
821
|
+
result.symbol
|
|
822
|
+
] }),
|
|
823
|
+
/* @__PURE__ */ jsx2("span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ jsx2(TokenIcon, { symbol: result.symbol }) })
|
|
824
|
+
] })
|
|
825
|
+
] }),
|
|
826
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-review-detail-row", children: [
|
|
827
|
+
/* @__PURE__ */ jsx2("span", { children: "Sent to" }),
|
|
828
|
+
/* @__PURE__ */ jsx2("span", { className: "rs-review-detail-value", children: shortenAddress(result.destination) })
|
|
829
|
+
] }),
|
|
830
|
+
/* @__PURE__ */ jsxs2("div", { className: "rs-review-detail-row", children: [
|
|
831
|
+
/* @__PURE__ */ jsx2("span", { children: "Transaction" }),
|
|
832
|
+
(() => {
|
|
833
|
+
const url = getExplorerTxUrl(result.chain, result.txHash);
|
|
834
|
+
const short = shortenHash(result.txHash);
|
|
835
|
+
return url ? /* @__PURE__ */ jsxs2(
|
|
836
|
+
"a",
|
|
837
|
+
{
|
|
838
|
+
className: "rs-review-detail-value rs-link",
|
|
839
|
+
href: url,
|
|
840
|
+
target: "_blank",
|
|
841
|
+
rel: "noreferrer",
|
|
842
|
+
children: [
|
|
843
|
+
short,
|
|
844
|
+
/* @__PURE__ */ jsx2(ExternalLinkIcon, {})
|
|
845
|
+
]
|
|
846
|
+
}
|
|
847
|
+
) : /* @__PURE__ */ jsx2("span", { className: "rs-review-detail-value", children: short });
|
|
848
|
+
})()
|
|
849
|
+
] })
|
|
850
|
+
] }) : /* @__PURE__ */ jsx2(Callout, { variant: "error", children: error }),
|
|
851
|
+
/* @__PURE__ */ jsx2("div", { className: "rs-screen-button-row", children: success ? /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
852
|
+
onReset && /* @__PURE__ */ jsx2(Button, { variant: "outline", onClick: onReset, fullWidth: true, children: "Claim another deposit" }),
|
|
853
|
+
/* @__PURE__ */ jsx2(Button, { onClick: onClose, fullWidth: true, children: "Done" })
|
|
854
|
+
] }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
855
|
+
/* @__PURE__ */ jsx2(Button, { variant: "outline", onClick: onClose, fullWidth: true, children: "Cancel" }),
|
|
856
|
+
onRetry && /* @__PURE__ */ jsx2(Button, { onClick: onRetry, fullWidth: true, children: "Try again" })
|
|
857
|
+
] }) })
|
|
858
|
+
] }),
|
|
859
|
+
/* @__PURE__ */ jsx2(PoweredBy, {})
|
|
860
|
+
] });
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
export {
|
|
864
|
+
ClaimModal
|
|
865
|
+
};
|