@rhinestone/deposit-modal 0.12.2 → 0.14.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.
Files changed (68) hide show
  1. package/README.md +73 -18
  2. package/bridge-transcript.json +653 -0
  3. package/dist/ClaimModal-IKTJU43Y.cjs +13 -0
  4. package/dist/ClaimModal-SEKNWRMA.mjs +13 -0
  5. package/dist/{DepositModalReown-VG66OTIU.cjs → DepositModalReown-46LPVFB6.cjs} +58 -35
  6. package/dist/{DepositModalReown-TEC3MEZ4.mjs → DepositModalReown-Q2JMLT47.mjs} +45 -22
  7. package/dist/{QRCode-WUC652SH.mjs → QRCode-5RGIZZHL.mjs} +1 -1
  8. package/dist/{QRCode-5DXFNKI2.cjs → QRCode-JKXG4RHN.cjs} +2 -2
  9. package/dist/WithdrawModal-5ICGD4HJ.mjs +12 -0
  10. package/dist/WithdrawModal-VP6PMIRO.cjs +12 -0
  11. package/dist/{chunk-O7BCVQ6L.cjs → chunk-4KCSH4T3.cjs} +157 -199
  12. package/dist/chunk-6KG642KH.cjs +31 -0
  13. package/dist/{chunk-PWLEBV5V.cjs → chunk-7ICSHJFE.cjs} +296 -220
  14. package/dist/{chunk-J46WDSRD.mjs → chunk-7SR7ENVJ.mjs} +165 -89
  15. package/dist/{chunk-2TPSF77V.mjs → chunk-CFKC77SV.mjs} +455 -261
  16. package/dist/{chunk-75DVGSAX.cjs → chunk-DW2EQA2U.cjs} +6 -3
  17. package/dist/{chunk-FXXUIK4E.mjs → chunk-IN77XSWO.mjs} +899 -153
  18. package/dist/chunk-K4H6TGBE.mjs +31 -0
  19. package/dist/{chunk-SDSKIJC7.mjs → chunk-KTUVSKR4.mjs} +2410 -1177
  20. package/dist/{chunk-HL5NUKZW.cjs → chunk-LZFRL2AL.cjs} +3 -3
  21. package/dist/{chunk-UQIJU6HV.cjs → chunk-MTFJSE52.cjs} +499 -191
  22. package/dist/{chunk-FLVLYO64.mjs → chunk-PKML3XVS.mjs} +430 -122
  23. package/dist/{chunk-4ZXQPFNU.mjs → chunk-RN5VKWI6.mjs} +4 -1
  24. package/dist/{chunk-BRYNGLDM.cjs → chunk-V2OBGLJD.cjs} +961 -215
  25. package/dist/{chunk-3STTWRAN.mjs → chunk-VUATPOWJ.mjs} +147 -189
  26. package/dist/{chunk-JE4R5VA3.mjs → chunk-WUJIKCFU.mjs} +1 -1
  27. package/dist/chunk-X2IPAPXU.cjs +163 -0
  28. package/dist/{chunk-OIN4CXCP.cjs → chunk-YCQZJQO6.cjs} +2343 -1110
  29. package/dist/{chunk-TM7VGHAG.cjs → chunk-YWMWI7PZ.cjs} +462 -268
  30. package/dist/chunk-ZEO6ADM3.mjs +163 -0
  31. package/dist/claim.cjs +7 -6
  32. package/dist/claim.d.cts +11 -3
  33. package/dist/claim.d.ts +11 -3
  34. package/dist/claim.mjs +6 -5
  35. package/dist/{constants-FuzG3h4m.d.cts → constants-DBrWhJWE.d.cts} +12 -7
  36. package/dist/{constants-FuzG3h4m.d.ts → constants-DBrWhJWE.d.ts} +12 -7
  37. package/dist/constants.cjs +3 -9
  38. package/dist/constants.d.cts +2 -3
  39. package/dist/constants.d.ts +2 -3
  40. package/dist/constants.mjs +4 -10
  41. package/dist/deposit.cjs +8 -8
  42. package/dist/deposit.d.cts +2 -2
  43. package/dist/deposit.d.ts +2 -2
  44. package/dist/deposit.mjs +7 -7
  45. package/dist/embed.cjs +1476 -0
  46. package/dist/embed.d.cts +183 -0
  47. package/dist/embed.d.ts +183 -0
  48. package/dist/embed.mjs +1476 -0
  49. package/dist/index.cjs +11 -16
  50. package/dist/index.d.cts +3 -3
  51. package/dist/index.d.ts +3 -3
  52. package/dist/index.mjs +14 -19
  53. package/dist/modal-ui-state-OD1RmKkK.d.cts +30 -0
  54. package/dist/modal-ui-state-OD1RmKkK.d.ts +30 -0
  55. package/dist/polymarket.cjs +17 -7
  56. package/dist/polymarket.mjs +13 -3
  57. package/dist/styles.css +124 -98
  58. package/dist/types-Bho4OA03.d.ts +982 -0
  59. package/dist/types-DP_3KwlD.d.cts +982 -0
  60. package/dist/withdraw.cjs +6 -6
  61. package/dist/withdraw.d.cts +11 -3
  62. package/dist/withdraw.d.ts +11 -3
  63. package/dist/withdraw.mjs +5 -5
  64. package/package.json +59 -6
  65. package/dist/chunk-IAGFDSNC.mjs +0 -11
  66. package/dist/chunk-L32UI7LA.cjs +0 -11
  67. package/dist/types-BO4iP6fG.d.cts +0 -612
  68. package/dist/types-oFblf65g.d.ts +0 -612
@@ -1,9 +1,10 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
- var _chunkHL5NUKZWcjs = require('./chunk-HL5NUKZW.cjs');
4
3
 
4
+ var _chunkX2IPAPXUcjs = require('./chunk-X2IPAPXU.cjs');
5
5
 
6
6
 
7
+ var _chunkLZFRL2ALcjs = require('./chunk-LZFRL2AL.cjs');
7
8
 
8
9
 
9
10
 
@@ -28,17 +29,17 @@ var _chunkHL5NUKZWcjs = require('./chunk-HL5NUKZW.cjs');
28
29
 
29
30
 
30
31
 
31
- var _chunkBRYNGLDMcjs = require('./chunk-BRYNGLDM.cjs');
32
32
 
33
33
 
34
- var _chunkL32UI7LAcjs = require('./chunk-L32UI7LA.cjs');
35
34
 
35
+ var _chunkV2OBGLJDcjs = require('./chunk-V2OBGLJD.cjs');
36
36
 
37
37
 
38
38
 
39
39
 
40
40
 
41
- var _chunkO7BCVQ6Lcjs = require('./chunk-O7BCVQ6L.cjs');
41
+
42
+ var _chunk4KCSH4T3cjs = require('./chunk-4KCSH4T3.cjs');
42
43
 
43
44
  // src/ClaimModal.tsx
44
45
 
@@ -68,7 +69,7 @@ var Input = _react.forwardRef.call(void 0,
68
69
  }
69
70
  ),
70
71
  error && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "rs-input-error", children: [
71
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.AlertTriangleIcon, { className: "rs-input-error-icon" }),
72
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.AlertTriangleIcon, { className: "rs-input-error-icon" }),
72
73
  error
73
74
  ] })
74
75
  ] });
@@ -76,140 +77,189 @@ var Input = _react.forwardRef.call(void 0,
76
77
  );
77
78
  Input.displayName = "Input";
78
79
 
79
- // src/core/recovery.ts
80
- var RECOVER_DOMAIN = {
81
- name: "Rhinestone Deposit Recovery",
82
- version: "1"
83
- };
84
- var RECOVER_TYPES = {
85
- RecoverDeposit: [
86
- { name: "depositId", type: "uint256" },
87
- { name: "destination", type: "address" }
88
- ]
89
- };
90
- var RecoveryError = class extends Error {
91
- constructor(message, status, code, retryable = false) {
92
- super(message);
93
- this.name = "RecoveryError";
94
- this.status = status;
95
- this.code = code;
96
- this.retryable = retryable;
97
- }
98
- };
99
- function formatRecoveryError(status, code, serverMessage) {
100
- switch (code) {
80
+ // src/core/claim-analytics.tsx
81
+
82
+
83
+
84
+
85
+
86
+
87
+ function claimFailureReasonForError(error) {
88
+ if (!(error instanceof _chunkX2IPAPXUcjs.RecoveryError)) return "refund_failed";
89
+ switch (error.code) {
90
+ case "SIGNATURE_INVALID":
91
+ return "signature_invalid";
101
92
  case "DEPOSIT_NOT_RECOVERABLE":
102
- return {
103
- message: "This deposit can't be recovered \u2014 it may already have been claimed.",
104
- retryable: false
105
- };
93
+ return "recovery_deposit_not_recoverable";
106
94
  case "RECOVERY_UNSUPPORTED":
107
- return {
108
- message: "This deposit can't be recovered automatically. Contact support to get your funds back.",
109
- retryable: false
110
- };
111
- case "SIGNATURE_INVALID":
112
- return {
113
- message: "That signature wasn't accepted for this wallet. Contact support to recover this deposit.",
114
- retryable: false
115
- };
95
+ return "recovery_unsupported";
116
96
  case "VERIFICATION_UNAVAILABLE":
117
- return {
118
- message: "Couldn't verify your signature just now. Try again shortly.",
119
- retryable: true
120
- };
97
+ return "signature_verification_unavailable";
121
98
  case "REFUND_RECONCILIATION_REQUIRED":
122
- return {
123
- message: "Your recovery is being reviewed. Contact support with this deposit if it doesn't arrive.",
124
- retryable: false
125
- };
99
+ return "refund_reconciliation_required";
126
100
  case "REFUND_FAILED":
127
- return {
128
- message: _nullishCoalesce(serverMessage, () => ( "The recovery couldn't be completed. Please try again or contact support.")),
129
- retryable: true
130
- };
101
+ return "refund_failed";
131
102
  default:
132
- if (status === 0) {
133
- return {
134
- message: "Couldn't reach the recovery service. Check your connection and try again.",
135
- retryable: true
136
- };
137
- }
138
- return {
139
- message: _nullishCoalesce(serverMessage, () => ( "The recovery couldn't be completed. Please try again or contact support.")),
140
- retryable: true
141
- };
103
+ if (error.phase === "signature") return "signature_rejected";
104
+ if (error.phase === "request") return "refund_service_unreachable";
105
+ return "refund_failed";
142
106
  }
143
107
  }
144
- async function submitSignedRecovery(params) {
145
- const { backendUrl, depositId, signer, destination, signRecovery, debug } = params;
146
- const scope = "service:recovery";
147
- const typedData = {
148
- domain: RECOVER_DOMAIN,
149
- types: RECOVER_TYPES,
150
- primaryType: "RecoverDeposit",
151
- message: { depositId: BigInt(depositId), destination }
108
+ function createClaimAnalyticsController(emit) {
109
+ let step = null;
110
+ let afterHandoff = false;
111
+ let opened = false;
112
+ let closed = false;
113
+ const dedupe = /* @__PURE__ */ new Set();
114
+ const send = (payload) => {
115
+ controller.openSession();
116
+ emit(payload);
152
117
  };
153
- let signature;
154
- try {
155
- signature = await signRecovery({ typedData, signer, depositId, destination });
156
- } catch (error) {
157
- _chunkBRYNGLDMcjs.debugError.call(void 0, debug, scope, "signRecovery:failed", error);
158
- throw new RecoveryError(
159
- "Signature request was declined. Approve it in your wallet to recover this deposit.",
160
- 0,
161
- void 0,
162
- true
163
- );
164
- }
165
- if (!signature) {
166
- throw new RecoveryError(
167
- "Signature request was declined. Approve it in your wallet to recover this deposit.",
168
- 0,
169
- void 0,
170
- true
171
- );
172
- }
173
- const url = `${backendUrl.replace(/\/$/, "")}/deposits/recover`;
174
- _chunkBRYNGLDMcjs.debugLog.call(void 0, debug, scope, "submitSignedRecovery:request", {
175
- url,
176
- depositId,
177
- signer
178
- });
179
- let response;
180
- try {
181
- response = await fetch(url, {
182
- method: "POST",
183
- // The shared const, so recovery carries `x-deposit-modal-version` like
184
- // every other backend call. Without it this path would be invisible in the
185
- // per-client version telemetry the processor records.
186
- headers: _chunkL32UI7LAcjs.SERVICE_HEADERS,
187
- // `depositId` as a string: it is a uint256 upstream and JSON numbers lose
188
- // precision well before that range.
189
- body: JSON.stringify({ depositId, destination, signature })
190
- });
191
- } catch (error) {
192
- _chunkBRYNGLDMcjs.debugError.call(void 0, debug, scope, "submitSignedRecovery:network", error);
193
- const { message, retryable } = formatRecoveryError(0);
194
- throw new RecoveryError(message, 0, void 0, retryable);
195
- }
196
- if (!response.ok) {
197
- const body = await response.json().catch(() => ({}));
198
- _chunkBRYNGLDMcjs.debugError.call(void 0, debug, scope, "submitSignedRecovery:failed", body, {
199
- status: response.status
200
- });
201
- const { message, retryable } = formatRecoveryError(
202
- response.status,
203
- body.code,
204
- body.error
205
- );
206
- throw new RecoveryError(message, response.status, body.code, retryable);
207
- }
208
- const result = await response.json();
209
- _chunkBRYNGLDMcjs.debugLog.call(void 0, debug, scope, "submitSignedRecovery:success", {
210
- transactionHash: result.transactionHash
211
- });
212
- return result;
118
+ const emitOnce = (key, payload) => {
119
+ if (dedupe.has(key)) return;
120
+ dedupe.add(key);
121
+ send(payload);
122
+ };
123
+ const rearmStep = (rearmed) => {
124
+ for (const key of [...dedupe]) {
125
+ if (key.includes(`:${rearmed}:`)) dedupe.delete(key);
126
+ }
127
+ };
128
+ const controller = {
129
+ openSession() {
130
+ if (opened) return;
131
+ opened = true;
132
+ emit({ type: "claim_modal_open" });
133
+ },
134
+ openStep(nextStep) {
135
+ controller.openSession();
136
+ if (step === nextStep) return;
137
+ step = nextStep;
138
+ emitOnce(`step-open:${nextStep}`, {
139
+ type: "claim_modal_step_open",
140
+ step: nextStep
141
+ });
142
+ },
143
+ completeStep(completedStep = _nullishCoalesce(step, () => ( void 0))) {
144
+ if (!completedStep) return;
145
+ emitOnce(`step-complete:${completedStep}`, {
146
+ type: "claim_modal_step_complete",
147
+ step: completedStep
148
+ });
149
+ },
150
+ rearmStep(rearmed) {
151
+ rearmStep(rearmed);
152
+ },
153
+ // One per submitted search, never deduplicated: the searched hash is
154
+ // deliberately not in the stream, so collapsing two searches that returned
155
+ // the same counts would make the second one unrecoverable.
156
+ lookupResult(matches, eligible) {
157
+ send({
158
+ type: "claim_modal_lookup_result",
159
+ matches,
160
+ eligible
161
+ });
162
+ },
163
+ selectDeposit({ depositId, transactionHash, autoSelected }) {
164
+ emitOnce(`deposit-selected:${depositId}`, {
165
+ type: "claim_modal_deposit_selected",
166
+ deposit_id: depositId,
167
+ transaction_hash: transactionHash,
168
+ auto_selected: autoSelected
169
+ });
170
+ },
171
+ friction(reason, eventStep = _nullishCoalesce(step, () => ( void 0))) {
172
+ if (!eventStep) return;
173
+ emitOnce(`friction:${eventStep}:${reason}`, {
174
+ type: "claim_modal_friction",
175
+ step: eventStep,
176
+ reason
177
+ });
178
+ },
179
+ failure(reason, retryable, eventStep = _nullishCoalesce(step, () => ( void 0))) {
180
+ if (!eventStep) return;
181
+ emitOnce(`failure:${eventStep}:${reason}`, {
182
+ type: "claim_modal_failure",
183
+ step: eventStep,
184
+ reason,
185
+ retryable
186
+ });
187
+ },
188
+ retry(reason, eventStep = _nullishCoalesce(step, () => ( void 0))) {
189
+ if (!eventStep) return;
190
+ send({ type: "claim_modal_retry", step: eventStep, reason });
191
+ rearmStep(eventStep);
192
+ },
193
+ handoff({ depositId, transactionHash, refundTransactionHash }, eventStep) {
194
+ const handoffStep = _nullishCoalesce(_nullishCoalesce(eventStep, () => ( step)), () => ( "submit"));
195
+ if (step !== handoffStep) controller.openStep(handoffStep);
196
+ afterHandoff = true;
197
+ emitOnce(`handoff:${refundTransactionHash}`, {
198
+ type: "claim_modal_handoff",
199
+ step: handoffStep,
200
+ deposit_id: depositId,
201
+ transaction_hash: transactionHash,
202
+ refund_transaction_hash: refundTransactionHash
203
+ });
204
+ },
205
+ // Keyed by step so a retry re-arms it: a second failed submit is a second
206
+ // terminal outcome, not a duplicate of the first.
207
+ outcome(outcome) {
208
+ if (!step) return;
209
+ emitOnce(`outcome:${step}:${outcome}`, {
210
+ type: "claim_modal_ui_outcome",
211
+ step,
212
+ outcome
213
+ });
214
+ },
215
+ abandon(reason) {
216
+ if (!step || afterHandoff) return;
217
+ emitOnce(`abandon:${step}:${reason}`, {
218
+ type: "claim_modal_abandoned",
219
+ step,
220
+ reason
221
+ });
222
+ },
223
+ close(source) {
224
+ if (closed) return;
225
+ closed = true;
226
+ send({
227
+ type: "claim_modal_close",
228
+ source,
229
+ step,
230
+ after_handoff: afterHandoff
231
+ });
232
+ },
233
+ /** "Claim another deposit" on the success screen: a fresh attempt in the
234
+ * same session, so the envelope and its session id stay. */
235
+ resetAttempt() {
236
+ step = null;
237
+ afterHandoff = false;
238
+ dedupe.clear();
239
+ },
240
+ get step() {
241
+ return step;
242
+ },
243
+ get afterHandoff() {
244
+ return afterHandoff;
245
+ }
246
+ };
247
+ return controller;
248
+ }
249
+ var ClaimAnalyticsControllerContext = _react.createContext.call(void 0, null);
250
+ var noopController = createClaimAnalyticsController(() => {
251
+ });
252
+ function ClaimAnalyticsControllerProvider({
253
+ children,
254
+ controllerRef
255
+ }) {
256
+ const emit = _chunkV2OBGLJDcjs.useClaimAnalyticsEmitter.call(void 0, );
257
+ const controller = _react.useMemo.call(void 0, () => createClaimAnalyticsController(emit), [emit]);
258
+ if (controllerRef) controllerRef.current = controller;
259
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ClaimAnalyticsControllerContext.Provider, { value: controller, children });
260
+ }
261
+ function useClaimAnalyticsController() {
262
+ return _nullishCoalesce(_react.useContext.call(void 0, ClaimAnalyticsControllerContext), () => ( noopController));
213
263
  }
214
264
 
215
265
  // src/ClaimModal.tsx
@@ -224,17 +274,17 @@ function isEligible(row) {
224
274
  }
225
275
  function describeDeposit(row) {
226
276
  const chainId = _nullishCoalesce(evmChainIdFromCaip2(row.chain), () => ( 0));
227
- const decimals = _chunkO7BCVQ6Lcjs.getTokenDecimalsByAddress.call(void 0, row.token, chainId);
228
- const symbol = _chunkO7BCVQ6Lcjs.getTokenSymbol.call(void 0, row.token, chainId);
277
+ const decimals = _chunk4KCSH4T3cjs.getTokenDecimalsByAddress.call(void 0, row.token, chainId);
278
+ const symbol = _chunk4KCSH4T3cjs.getTokenSymbol.call(void 0, row.token, chainId);
229
279
  const raw = BigInt(_nullishCoalesce(_nullishCoalesce(row.sourceAmount, () => ( row.amount)), () => ( "0")));
230
280
  const human = Number(_viem.formatUnits.call(void 0, raw, decimals));
231
- const amount = _nullishCoalesce(_chunkBRYNGLDMcjs.formatTokenAmount.call(void 0, human, symbol), () => ( _viem.formatUnits.call(void 0, raw, decimals)));
281
+ const amount = _nullishCoalesce(_chunkV2OBGLJDcjs.formatTokenAmount.call(void 0, human, symbol), () => ( _viem.formatUnits.call(void 0, raw, decimals)));
232
282
  return {
233
283
  chainId,
234
284
  symbol,
235
285
  amount,
236
- chainName: _chunkO7BCVQ6Lcjs.getChainName.call(void 0, chainId),
237
- chainIcon: _chunkO7BCVQ6Lcjs.getChainIcon.call(void 0, chainId)
286
+ chainName: _chunk4KCSH4T3cjs.getChainName.call(void 0, chainId),
287
+ chainIcon: _chunk4KCSH4T3cjs.getChainIcon.call(void 0, chainId)
238
288
  };
239
289
  }
240
290
  function shortenHash(hash) {
@@ -306,6 +356,27 @@ function claimReducer(state, action) {
306
356
  return state;
307
357
  }
308
358
  }
359
+ function buildClaimAnalyticsSessionProperties({
360
+ inline = false,
361
+ closeOnOverlayClick = false,
362
+ defaultTxHash,
363
+ defaultRefundDestination
364
+ }) {
365
+ return {
366
+ presentation: inline ? "inline" : "overlay",
367
+ overlay_close_enabled: !inline && closeOnOverlayClick,
368
+ prefills: {
369
+ transaction_hash: defaultTxHash !== void 0,
370
+ refund_destination: defaultRefundDestination !== void 0
371
+ }
372
+ };
373
+ }
374
+ function analyticsStepForClaimStep(step) {
375
+ if (step === "lookup") return "lookup";
376
+ if (step === "select") return "select";
377
+ if (step === "review") return "review";
378
+ return "submit";
379
+ }
309
380
  function ClaimModal({
310
381
  signRecovery,
311
382
  isOpen,
@@ -323,17 +394,22 @@ function ClaimModal({
323
394
  onLifecycle,
324
395
  onEvent,
325
396
  onError,
326
- debug
397
+ enableAnalyticsIngest,
398
+ analyticsIngestUrl,
399
+ debug,
400
+ onUiState
327
401
  }) {
328
- _chunkBRYNGLDMcjs.checkBackendUrl.call(void 0, "ClaimModal", backendUrl);
402
+ _chunkV2OBGLJDcjs.checkBackendUrl.call(void 0, "ClaimModal", backendUrl);
329
403
  const modalRef = _react.useRef.call(void 0, null);
330
- const onReadyRef = _chunkBRYNGLDMcjs.useLatestRef.call(void 0, onReady);
331
- const onLifecycleRef = _chunkBRYNGLDMcjs.useLatestRef.call(void 0, onLifecycle);
332
- const onEventRef = _chunkBRYNGLDMcjs.useLatestRef.call(void 0, onEvent);
333
- const onErrorRef = _chunkBRYNGLDMcjs.useLatestRef.call(void 0, onError);
334
- const rpcUrls = _chunkBRYNGLDMcjs.useStableRpcUrls.call(void 0, rpcUrlsProp);
404
+ const onReadyRef = _chunkV2OBGLJDcjs.useLatestRef.call(void 0, onReady);
405
+ const onLifecycleRef = _chunkV2OBGLJDcjs.useLatestRef.call(void 0, onLifecycle);
406
+ const onErrorRef = _chunkV2OBGLJDcjs.useLatestRef.call(void 0, onError);
407
+ const analyticsControllerRef = _react.useRef.call(void 0, null);
408
+ const lastSubmitFailureRef = _react.useRef.call(void 0, null);
409
+ const previousOpenRef = _react.useRef.call(void 0, isOpen);
410
+ const rpcUrls = _chunkV2OBGLJDcjs.useStableRpcUrls.call(void 0, rpcUrlsProp);
335
411
  const service = _react.useMemo.call(void 0,
336
- () => _chunkBRYNGLDMcjs.createDepositService.call(void 0, backendUrl, { debug, debugScope: "service:claim" }),
412
+ () => _chunkV2OBGLJDcjs.createDepositService.call(void 0, backendUrl, { debug, debugScope: "service:claim" }),
337
413
  [backendUrl, debug]
338
414
  );
339
415
  const [state, dispatch] = _react.useReducer.call(void 0, claimReducer, INITIAL_STATE);
@@ -341,80 +417,144 @@ function ClaimModal({
341
417
  const isOpenRef = _react.useRef.call(void 0, isOpen);
342
418
  isOpenRef.current = isOpen;
343
419
  _react.useEffect.call(void 0, () => {
344
- if (isOpen && modalRef.current) _chunkBRYNGLDMcjs.applyTheme.call(void 0, modalRef.current, theme);
420
+ if (!isOpen || !modalRef.current) return;
421
+ return _chunkV2OBGLJDcjs.applyTheme.call(void 0, modalRef.current, theme);
345
422
  }, [isOpen, theme]);
346
423
  _react.useEffect.call(void 0, () => {
347
424
  if (isOpen) {
348
425
  _optionalChain([onReadyRef, 'access', _3 => _3.current, 'optionalCall', _4 => _4()]);
349
- _optionalChain([onEventRef, 'access', _5 => _5.current, 'optionalCall', _6 => _6({ type: "claim_modal_open" })]);
350
426
  }
351
- }, [isOpen, onReadyRef, onEventRef]);
427
+ }, [isOpen, onReadyRef]);
428
+ _react.useEffect.call(void 0, () => {
429
+ if (previousOpenRef.current && !isOpen) {
430
+ const analytics = analyticsControllerRef.current;
431
+ _optionalChain([analytics, 'optionalAccess', _5 => _5.abandon, 'call', _6 => _6("modal_close")]);
432
+ _optionalChain([analytics, 'optionalAccess', _7 => _7.close, 'call', _8 => _8("host_controlled")]);
433
+ }
434
+ previousOpenRef.current = isOpen;
435
+ }, [isOpen]);
352
436
  _react.useEffect.call(void 0, () => {
353
437
  if (!isOpen) {
354
438
  operationEpochRef.current += 1;
355
439
  dispatch({ type: "reset" });
356
440
  }
357
441
  }, [isOpen]);
358
- const handleClose = _react.useCallback.call(void 0, () => {
359
- if (state.step !== "processing") {
442
+ const closeWithSource = _react.useCallback.call(void 0,
443
+ (source) => {
444
+ const analytics = analyticsControllerRef.current;
445
+ if (state.step === "processing") {
446
+ _optionalChain([analytics, 'optionalAccess', _9 => _9.friction, 'call', _10 => _10("modal_close_refused_in_flight", "submit")]);
447
+ return;
448
+ }
449
+ _optionalChain([analytics, 'optionalAccess', _11 => _11.abandon, 'call', _12 => _12("modal_close")]);
450
+ _optionalChain([analytics, 'optionalAccess', _13 => _13.close, 'call', _14 => _14(source)]);
360
451
  operationEpochRef.current += 1;
361
452
  onClose();
453
+ },
454
+ [state.step, onClose]
455
+ );
456
+ const handleModalDismiss = _react.useCallback.call(void 0,
457
+ (reason) => {
458
+ closeWithSource(
459
+ reason === "escape" ? "escape" : reason === "overlay" ? "overlay" : "header_button"
460
+ );
461
+ },
462
+ [closeWithSource]
463
+ );
464
+ const goBack = _react.useCallback.call(void 0, () => {
465
+ const analytics = analyticsControllerRef.current;
466
+ const previousFailure = lastSubmitFailureRef.current;
467
+ if (state.step === "failed" && _optionalChain([previousFailure, 'optionalAccess', _15 => _15.retryable])) {
468
+ lastSubmitFailureRef.current = null;
469
+ _optionalChain([analytics, 'optionalAccess', _16 => _16.retry, 'call', _17 => _17(previousFailure.reason, "submit")]);
470
+ } else {
471
+ if (state.step === "failed") {
472
+ lastSubmitFailureRef.current = null;
473
+ _optionalChain([analytics, 'optionalAccess', _18 => _18.rearmStep, 'call', _19 => _19("submit")]);
474
+ }
475
+ _optionalChain([analytics, 'optionalAccess', _20 => _20.abandon, 'call', _21 => _21("back")]);
362
476
  }
363
- }, [state.step, onClose]);
477
+ dispatch({ type: "back" });
478
+ }, [state.step]);
364
479
  const canGoBack = state.step === "select" || state.step === "review" || state.step === "failed";
365
- const showBackButton = _nullishCoalesce(_optionalChain([uiConfig, 'optionalAccess', _7 => _7.showBackButton]), () => ( true));
366
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.RpcUrlsProvider, { value: rpcUrls, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.ChainCatalogProvider, { service, rpcUrls, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
367
- _chunkBRYNGLDMcjs.Modal,
480
+ const onUiStateRef = _chunkV2OBGLJDcjs.useLatestRef.call(void 0, onUiState);
481
+ _react.useEffect.call(void 0, () => {
482
+ _optionalChain([onUiStateRef, 'access', _22 => _22.current, 'optionalCall', _23 => _23({
483
+ screen: state.step,
484
+ back: canGoBack ? goBack : void 0,
485
+ submitting: state.step === "processing"
486
+ })]);
487
+ }, [state.step, canGoBack, goBack, onUiStateRef]);
488
+ const showBackButton = _nullishCoalesce(_optionalChain([uiConfig, 'optionalAccess', _24 => _24.showBackButton]), () => ( true));
489
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.RpcUrlsProvider, { value: rpcUrls, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.ChainCatalogProvider, { service, rpcUrls, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
490
+ _chunkV2OBGLJDcjs.Modal,
368
491
  {
369
492
  isOpen,
370
- onClose: handleClose,
493
+ onClose: handleModalDismiss,
371
494
  className,
372
495
  inline,
373
496
  closeOnOverlayClick,
374
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { ref: modalRef, className: "rs-modal", children: [
375
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-modal-header--redesigned", children: [
376
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rs-modal-header-nav-left", children: showBackButton && canGoBack && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
377
- "button",
378
- {
379
- type: "button",
380
- className: "rs-modal-header-back",
381
- "aria-label": "Go back",
382
- onClick: () => dispatch({ type: "back" }),
383
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.ChevronLeftIcon, {})
384
- }
385
- ) }),
386
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rs-modal-header-nav-right", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
387
- "button",
388
- {
389
- type: "button",
390
- onClick: handleClose,
391
- disabled: state.step === "processing",
392
- className: "rs-modal-close",
393
- "aria-label": "Close",
394
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.CloseIcon, {})
395
- }
396
- ) })
397
- ] }),
398
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rs-modal-body", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
399
- ClaimBody,
400
- {
401
- state,
402
- dispatch,
403
- service,
404
- signRecovery,
405
- backendUrl,
406
- debug,
497
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
498
+ _chunkV2OBGLJDcjs.AnalyticsSession,
499
+ {
500
+ modal: "claim",
501
+ sessionProperties: buildClaimAnalyticsSessionProperties({
502
+ inline,
503
+ closeOnOverlayClick,
407
504
  defaultTxHash,
408
- defaultRefundDestination,
409
- onClose: handleClose,
410
- operationEpochRef,
411
- isOpenRef,
412
- onLifecycleRef,
413
- onEventRef,
414
- onErrorRef
415
- }
416
- ) })
417
- ] })
505
+ defaultRefundDestination
506
+ }),
507
+ onEvent,
508
+ backendUrl,
509
+ enableIngest: enableAnalyticsIngest,
510
+ ingestUrl: analyticsIngestUrl,
511
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ClaimAnalyticsControllerProvider, { controllerRef: analyticsControllerRef, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { ref: modalRef, className: "rs-modal", children: [
512
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-modal-header--redesigned", children: [
513
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rs-modal-header-nav-left", children: showBackButton && canGoBack && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
514
+ "button",
515
+ {
516
+ type: "button",
517
+ className: "rs-modal-header-back",
518
+ "aria-label": "Go back",
519
+ onClick: goBack,
520
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.ChevronLeftIcon, {})
521
+ }
522
+ ) }),
523
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rs-modal-header-nav-right", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
524
+ "button",
525
+ {
526
+ type: "button",
527
+ onClick: () => closeWithSource("header_button"),
528
+ disabled: state.step === "processing",
529
+ className: "rs-modal-close",
530
+ "aria-label": "Close",
531
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.CloseIcon, {})
532
+ }
533
+ ) })
534
+ ] }),
535
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rs-modal-body", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
536
+ ClaimBody,
537
+ {
538
+ state,
539
+ dispatch,
540
+ service,
541
+ signRecovery,
542
+ backendUrl,
543
+ debug,
544
+ defaultTxHash,
545
+ defaultRefundDestination,
546
+ onClose: closeWithSource,
547
+ onBack: goBack,
548
+ operationEpochRef,
549
+ isOpenRef,
550
+ lastSubmitFailureRef,
551
+ onLifecycleRef,
552
+ onErrorRef
553
+ }
554
+ ) })
555
+ ] }) })
556
+ }
557
+ )
418
558
  }
419
559
  ) }) });
420
560
  }
@@ -428,12 +568,18 @@ function ClaimBody({
428
568
  defaultTxHash,
429
569
  defaultRefundDestination,
430
570
  onClose,
571
+ onBack,
431
572
  operationEpochRef,
432
573
  isOpenRef,
574
+ lastSubmitFailureRef,
433
575
  onLifecycleRef,
434
- onEventRef,
435
576
  onErrorRef
436
577
  }) {
578
+ const analytics = useClaimAnalyticsController();
579
+ _react.useEffect.call(void 0, () => {
580
+ analytics.openSession();
581
+ analytics.openStep(analyticsStepForClaimStep(state.step));
582
+ }, [analytics, state.step]);
437
583
  switch (state.step) {
438
584
  case "lookup":
439
585
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -446,10 +592,11 @@ function ClaimBody({
446
592
  onResults: (deposits) => {
447
593
  const eligible = deposits.filter(isEligible);
448
594
  const autoSelect = deposits.length === 1 && eligible.length === 1 ? deposits[0] : null;
595
+ analytics.completeStep("lookup");
596
+ if (autoSelect) reportSelection(autoSelect, true);
449
597
  dispatch({ type: "lookup/results", deposits, autoSelect });
450
598
  },
451
599
  onLifecycleRef,
452
- onEventRef,
453
600
  onErrorRef
454
601
  }
455
602
  );
@@ -458,7 +605,11 @@ function ClaimBody({
458
605
  SelectStep,
459
606
  {
460
607
  deposits: state.deposits,
461
- onSelect: (deposit) => dispatch({ type: "select", deposit })
608
+ onSelect: (deposit) => {
609
+ analytics.completeStep("select");
610
+ reportSelection(deposit, false);
611
+ dispatch({ type: "select", deposit });
612
+ }
462
613
  }
463
614
  );
464
615
  case "review":
@@ -473,27 +624,51 @@ function ClaimBody({
473
624
  }
474
625
  );
475
626
  case "complete":
476
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ResultStep, { result: state.result, onClose, onReset: () => dispatch({ type: "reset" }) });
627
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
628
+ ResultStep,
629
+ {
630
+ result: state.result,
631
+ onClose: () => onClose("success_done"),
632
+ onReset: () => {
633
+ analytics.resetAttempt();
634
+ dispatch({ type: "reset" });
635
+ }
636
+ }
637
+ );
477
638
  case "failed":
478
639
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
479
640
  ResultStep,
480
641
  {
481
642
  error: state.error,
482
- onClose,
483
- onRetry: state.retryable ? () => dispatch({ type: "back" }) : void 0
643
+ onClose: () => onClose("failure_cancel"),
644
+ onRetry: state.retryable ? onBack : void 0
484
645
  }
485
646
  );
486
647
  default:
487
648
  return null;
488
649
  }
650
+ function reportSelection(deposit, autoSelected) {
651
+ if (!deposit.id) return;
652
+ analytics.selectDeposit({
653
+ depositId: deposit.id,
654
+ transactionHash: _nullishCoalesce(deposit.txHash, () => ( null)),
655
+ autoSelected
656
+ });
657
+ }
489
658
  async function submitRecoveryRequest(destination) {
490
659
  const deposit = state.selected;
491
660
  if (!deposit) return;
492
661
  const sourceChainId = evmChainIdFromCaip2(deposit.chain);
493
662
  if (sourceChainId == null || !deposit.id || !deposit.recipient || !deposit.depositAddress || !deposit.token || !deposit.chain) {
663
+ analytics.failure("recovery_deposit_data_incomplete", false, "review");
664
+ analytics.outcome("failed");
494
665
  dispatch({
495
666
  type: "failed",
496
- error: "Deposit is missing data required to recover it."
667
+ error: "Deposit is missing data required to recover it.",
668
+ // The missing fields come off the backend row already in memory, so a
669
+ // retry re-reads nothing and fails identically. Offering one would be a
670
+ // dead end, and would also contradict the `retryable` reported above.
671
+ retryable: false
497
672
  });
498
673
  return;
499
674
  }
@@ -502,20 +677,19 @@ function ClaimBody({
502
677
  const token = deposit.token;
503
678
  const operationEpoch = operationEpochRef.current;
504
679
  const isCurrentOperation = () => isOpenRef.current && operationEpochRef.current === operationEpoch;
680
+ analytics.completeStep("review");
681
+ analytics.openStep("submit");
505
682
  dispatch({ type: "submit" });
506
- _optionalChain([onEventRef, 'access', _8 => _8.current, 'optionalCall', _9 => _9({
507
- type: "claim_modal_refund_click",
508
- chain: `eip155:${sourceChainId}`
509
- })]);
510
- _optionalChain([onLifecycleRef, 'access', _10 => _10.current, 'optionalCall', _11 => _11({
683
+ _optionalChain([onLifecycleRef, 'access', _25 => _25.current, 'optionalCall', _26 => _26({
511
684
  type: "refund_requested",
512
685
  account,
513
686
  destination,
514
687
  chain: sourceChainId
515
688
  })]);
516
689
  try {
517
- const result = await submitSignedRecovery({
690
+ const result = await _chunkX2IPAPXUcjs.submitSignedRecovery.call(void 0, {
518
691
  backendUrl,
692
+ chainId: sourceChainId,
519
693
  depositId: deposit.id,
520
694
  signer,
521
695
  destination,
@@ -524,12 +698,12 @@ function ClaimBody({
524
698
  });
525
699
  if (!isCurrentOperation()) return;
526
700
  const paidTo = destination;
527
- const decimals = _chunkO7BCVQ6Lcjs.getTokenDecimalsByAddress.call(void 0, token, sourceChainId);
528
- const symbol = _chunkO7BCVQ6Lcjs.getTokenSymbol.call(void 0, token, sourceChainId);
701
+ const decimals = _chunk4KCSH4T3cjs.getTokenDecimalsByAddress.call(void 0, token, sourceChainId);
702
+ const symbol = _chunk4KCSH4T3cjs.getTokenSymbol.call(void 0, token, sourceChainId);
529
703
  const refundedRaw = BigInt(
530
704
  _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(result.amount, () => ( deposit.sourceAmount)), () => ( deposit.amount)), () => ( "0"))
531
705
  );
532
- const amountDisplay = _nullishCoalesce(_chunkBRYNGLDMcjs.formatTokenAmount.call(void 0, Number(_viem.formatUnits.call(void 0, refundedRaw, decimals)), symbol), () => ( _viem.formatUnits.call(void 0, refundedRaw, decimals)));
706
+ const amountDisplay = _nullishCoalesce(_chunkV2OBGLJDcjs.formatTokenAmount.call(void 0, Number(_viem.formatUnits.call(void 0, refundedRaw, decimals)), symbol), () => ( _viem.formatUnits.call(void 0, refundedRaw, decimals)));
533
707
  dispatch({
534
708
  type: "complete",
535
709
  txHash: result.transactionHash,
@@ -539,11 +713,17 @@ function ClaimBody({
539
713
  destination: paidTo,
540
714
  chain: sourceChainId
541
715
  });
542
- _optionalChain([onEventRef, 'access', _12 => _12.current, 'optionalCall', _13 => _13({
543
- type: "claim_modal_complete",
544
- chain: `eip155:${sourceChainId}`
545
- })]);
546
- _optionalChain([onLifecycleRef, 'access', _14 => _14.current, 'optionalCall', _15 => _15({
716
+ analytics.handoff(
717
+ {
718
+ depositId: deposit.id,
719
+ transactionHash: _nullishCoalesce(deposit.txHash, () => ( null)),
720
+ refundTransactionHash: result.transactionHash
721
+ },
722
+ "submit"
723
+ );
724
+ analytics.completeStep("submit");
725
+ analytics.outcome("completed");
726
+ _optionalChain([onLifecycleRef, 'access', _27 => _27.current, 'optionalCall', _28 => _28({
547
727
  type: "complete",
548
728
  txHash: result.transactionHash,
549
729
  account,
@@ -554,23 +734,23 @@ function ClaimBody({
554
734
  })]);
555
735
  } catch (err) {
556
736
  if (!isCurrentOperation()) return;
557
- const recoveryError = err instanceof RecoveryError ? err : void 0;
558
- const status = _optionalChain([recoveryError, 'optionalAccess', _16 => _16.status]);
559
- const message = _nullishCoalesce(_optionalChain([recoveryError, 'optionalAccess', _17 => _17.message]), () => ( _chunkBRYNGLDMcjs.formatUserError.call(void 0,
737
+ const recoveryError = err instanceof _chunkX2IPAPXUcjs.RecoveryError ? err : void 0;
738
+ const status = _optionalChain([recoveryError, 'optionalAccess', _29 => _29.status]);
739
+ const message = _nullishCoalesce(_optionalChain([recoveryError, 'optionalAccess', _30 => _30.message]), () => ( _chunkV2OBGLJDcjs.formatUserError.call(void 0,
560
740
  err instanceof Error ? err.message : "Recovery failed"
561
741
  )));
742
+ const retryable = _nullishCoalesce(_optionalChain([recoveryError, 'optionalAccess', _31 => _31.retryable]), () => ( true));
562
743
  dispatch({
563
744
  type: "failed",
564
745
  error: message,
565
- retryable: _nullishCoalesce(_optionalChain([recoveryError, 'optionalAccess', _18 => _18.retryable]), () => ( true))
746
+ retryable
566
747
  });
567
- _optionalChain([onEventRef, 'access', _19 => _19.current, 'optionalCall', _20 => _20({
568
- type: "claim_modal_failed",
569
- chain: `eip155:${sourceChainId}`,
570
- status
571
- })]);
572
- _optionalChain([onLifecycleRef, 'access', _21 => _21.current, 'optionalCall', _22 => _22({ type: "failed", status, error: message })]);
573
- _optionalChain([onErrorRef, 'access', _23 => _23.current, 'optionalCall', _24 => _24({ message, code: "CLAIM_FAILED" })]);
748
+ const reason = claimFailureReasonForError(err);
749
+ lastSubmitFailureRef.current = { reason, retryable };
750
+ analytics.failure(reason, retryable, "submit");
751
+ analytics.outcome("failed");
752
+ _optionalChain([onLifecycleRef, 'access', _32 => _32.current, 'optionalCall', _33 => _33({ type: "failed", status, error: message })]);
753
+ _optionalChain([onErrorRef, 'access', _34 => _34.current, 'optionalCall', _35 => _35({ message, code: "CLAIM_FAILED" })]);
574
754
  }
575
755
  }
576
756
  }
@@ -581,38 +761,44 @@ function LookupStep({
581
761
  isOpenRef,
582
762
  onResults,
583
763
  onLifecycleRef,
584
- onEventRef,
585
764
  onErrorRef
586
765
  }) {
766
+ const analytics = useClaimAnalyticsController();
587
767
  const [txHash, setTxHash] = _react.useState.call(void 0, _nullishCoalesce(defaultTxHash, () => ( "")));
588
768
  const [loading, setLoading] = _react.useState.call(void 0, false);
589
769
  const [error, setError] = _react.useState.call(void 0, null);
590
770
  const trimmed = txHash.trim();
591
771
  const validTxHash = /^0x[a-fA-F0-9]{64}$/.test(trimmed);
772
+ _react.useEffect.call(void 0, () => {
773
+ if (trimmed.length > 0 && !validTxHash) {
774
+ analytics.friction("lookup_transaction_hash_invalid", "lookup");
775
+ }
776
+ }, [analytics, trimmed, validTxHash]);
592
777
  const handleLookup = _react.useCallback.call(void 0, async () => {
593
778
  const operationEpoch = operationEpochRef.current;
594
779
  const isCurrentOperation = () => isOpenRef.current && operationEpochRef.current === operationEpoch;
595
780
  setError(null);
596
781
  setLoading(true);
782
+ analytics.rearmStep("lookup");
597
783
  try {
598
784
  const deposits = await service.lookupRecoverableDeposits({
599
785
  txHash: trimmed
600
786
  });
601
787
  if (!isCurrentOperation()) return;
602
- _optionalChain([onLifecycleRef, 'access', _25 => _25.current, 'optionalCall', _26 => _26({
788
+ _optionalChain([onLifecycleRef, 'access', _36 => _36.current, 'optionalCall', _37 => _37({
603
789
  type: "lookup",
604
790
  txHash: trimmed,
605
791
  matches: deposits.length
606
792
  })]);
607
- _optionalChain([onEventRef, 'access', _27 => _27.current, 'optionalCall', _28 => _28({
608
- type: "claim_modal_lookup",
609
- matches: deposits.length
610
- })]);
793
+ const eligible = deposits.filter(isEligible);
794
+ analytics.lookupResult(deposits.length, eligible.length);
611
795
  if (deposits.length === 0) {
796
+ analytics.friction("lookup_no_deposits_found", "lookup");
612
797
  setError("No deposits found for this transaction.");
613
798
  return;
614
799
  }
615
- if (!deposits.some(isEligible)) {
800
+ if (eligible.length === 0) {
801
+ analytics.friction("lookup_no_eligible_deposits", "lookup");
616
802
  setError(
617
803
  "This transaction has no failed or rejected deposits available to recover."
618
804
  );
@@ -621,30 +807,31 @@ function LookupStep({
621
807
  onResults(deposits);
622
808
  } catch (err) {
623
809
  if (!isCurrentOperation()) return;
624
- const message = _chunkBRYNGLDMcjs.formatUserError.call(void 0,
810
+ const message = _chunkV2OBGLJDcjs.formatUserError.call(void 0,
625
811
  err instanceof Error ? err.message : "Lookup failed"
626
812
  );
813
+ analytics.failure("lookup_failed", true, "lookup");
627
814
  setError(message);
628
- _optionalChain([onErrorRef, 'access', _29 => _29.current, 'optionalCall', _30 => _30({ message, code: "CLAIM_LOOKUP_FAILED" })]);
815
+ _optionalChain([onErrorRef, 'access', _38 => _38.current, 'optionalCall', _39 => _39({ message, code: "CLAIM_LOOKUP_FAILED" })]);
629
816
  } finally {
630
817
  if (isCurrentOperation()) setLoading(false);
631
818
  }
632
819
  }, [
820
+ analytics,
633
821
  trimmed,
634
822
  service,
635
823
  operationEpochRef,
636
824
  isOpenRef,
637
825
  onResults,
638
826
  onLifecycleRef,
639
- onEventRef,
640
827
  onErrorRef
641
828
  ]);
642
829
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen", children: [
643
830
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
644
831
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
645
- _chunkBRYNGLDMcjs.BodyHeader,
832
+ _chunkV2OBGLJDcjs.BodyHeader,
646
833
  {
647
- icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.HandCoinsIcon, {}),
834
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.HandCoinsIcon, {}),
648
835
  title: "Claim a deposit",
649
836
  subtitle: "Get funds from a failed deposit sent back to you on the source chain."
650
837
  }
@@ -659,9 +846,9 @@ function LookupStep({
659
846
  error: trimmed.length > 0 && !validTxHash ? "Enter a valid transaction hash" : void 0
660
847
  }
661
848
  ),
662
- error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.Callout, { variant: "error", children: error }),
849
+ error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.Callout, { variant: "error", children: error }),
663
850
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
664
- _chunkBRYNGLDMcjs.Button,
851
+ _chunkV2OBGLJDcjs.Button,
665
852
  {
666
853
  onClick: handleLookup,
667
854
  loading,
@@ -672,7 +859,7 @@ function LookupStep({
672
859
  }
673
860
  )
674
861
  ] }),
675
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.PoweredBy, {})
862
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.PoweredBy, {})
676
863
  ] });
677
864
  }
678
865
  function SelectStep({
@@ -682,9 +869,9 @@ function SelectStep({
682
869
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen", children: [
683
870
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
684
871
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
685
- _chunkBRYNGLDMcjs.BodyHeader,
872
+ _chunkV2OBGLJDcjs.BodyHeader,
686
873
  {
687
- icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.CoinsIcon, {}),
874
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.CoinsIcon, {}),
688
875
  title: "Select a deposit",
689
876
  subtitle: "This transaction produced multiple deposits. Choose the one to claim."
690
877
  }
@@ -693,9 +880,9 @@ function SelectStep({
693
880
  const { symbol, amount, chainName } = describeDeposit(row);
694
881
  const eligible = isEligible(row);
695
882
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
696
- _chunkHL5NUKZWcjs.ListRow,
883
+ _chunkLZFRL2ALcjs.ListRow,
697
884
  {
698
- leadingMedia: _chunkO7BCVQ6Lcjs.tokenIconUrl.call(void 0, symbol),
885
+ leadingMedia: _chunk4KCSH4T3cjs.tokenIconUrl.call(void 0, symbol),
699
886
  title: `${amount} ${symbol}`,
700
887
  subtitle: chainName,
701
888
  meta: eligible ? void 0 : humanizeStatus(row.status),
@@ -706,7 +893,7 @@ function SelectStep({
706
893
  );
707
894
  }) })
708
895
  ] }),
709
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.PoweredBy, {})
896
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.PoweredBy, {})
710
897
  ] });
711
898
  }
712
899
  function ReviewStep({
@@ -715,16 +902,22 @@ function ReviewStep({
715
902
  defaultRefundDestination,
716
903
  onSubmit
717
904
  }) {
905
+ const analytics = useClaimAnalyticsController();
718
906
  const { chainId, symbol, amount, chainName, chainIcon } = describeDeposit(deposit);
719
- const explorerTxUrl = _chunkBRYNGLDMcjs.useExplorerTxUrl.call(void 0, );
907
+ const explorerTxUrl = _chunkV2OBGLJDcjs.useExplorerTxUrl.call(void 0, );
720
908
  const [destination, setDestination] = _react.useState.call(void 0, _nullishCoalesce(defaultRefundDestination, () => ( "")));
721
909
  const destinationValid = _viem.isAddress.call(void 0, destination);
910
+ _react.useEffect.call(void 0, () => {
911
+ if (destination.length > 0 && !destinationValid) {
912
+ analytics.friction("refund_destination_invalid", "review");
913
+ }
914
+ }, [analytics, destination, destinationValid]);
722
915
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen", children: [
723
916
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
724
917
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
725
- _chunkBRYNGLDMcjs.BodyHeader,
918
+ _chunkV2OBGLJDcjs.BodyHeader,
726
919
  {
727
- icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.HandCoinsIcon, {}),
920
+ icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.HandCoinsIcon, {}),
728
921
  title: "Review refund",
729
922
  subtitle: "This returns the funds on the source chain. It does not retry the original bridge."
730
923
  }
@@ -738,14 +931,14 @@ function ReviewStep({
738
931
  " ",
739
932
  symbol
740
933
  ] }),
741
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.TokenIcon, { symbol }) })
934
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.TokenIcon, { symbol }) })
742
935
  ] })
743
936
  ] }),
744
937
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-review-detail-row", children: [
745
938
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Source chain" }),
746
939
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "rs-review-detail-value", children: [
747
940
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: chainName }),
748
- chainIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.CdnIcon, { src: chainIcon }) })
941
+ chainIcon && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.CdnIcon, { src: chainIcon }) })
749
942
  ] })
750
943
  ] }),
751
944
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-review-detail-row", children: [
@@ -762,7 +955,7 @@ function ReviewStep({
762
955
  rel: "noreferrer",
763
956
  children: [
764
957
  short,
765
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.ExternalLinkIcon, {})
958
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.ExternalLinkIcon, {})
766
959
  ]
767
960
  }
768
961
  ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-value", children: short });
@@ -780,7 +973,7 @@ function ReviewStep({
780
973
  }
781
974
  ),
782
975
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
783
- _chunkBRYNGLDMcjs.Button,
976
+ _chunkV2OBGLJDcjs.Button,
784
977
  {
785
978
  onClick: () => destinationValid && onSubmit(destination),
786
979
  loading: submitting,
@@ -791,7 +984,7 @@ function ReviewStep({
791
984
  }
792
985
  )
793
986
  ] }),
794
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.PoweredBy, {})
987
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.PoweredBy, {})
795
988
  ] });
796
989
  }
797
990
  function ResultStep({
@@ -802,13 +995,13 @@ function ResultStep({
802
995
  onRetry
803
996
  }) {
804
997
  const success = !!result;
805
- const explorerTxUrl = _chunkBRYNGLDMcjs.useExplorerTxUrl.call(void 0, );
998
+ const explorerTxUrl = _chunkV2OBGLJDcjs.useExplorerTxUrl.call(void 0, );
806
999
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen", children: [
807
1000
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-screen-body rs-screen-body--gap-32", children: [
808
1001
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
809
- _chunkBRYNGLDMcjs.BodyHeader,
1002
+ _chunkV2OBGLJDcjs.BodyHeader,
810
1003
  {
811
- icon: success ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.CheckIcon, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.AlertTriangleIcon, {}),
1004
+ icon: success ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.CheckIcon, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.AlertTriangleIcon, {}),
812
1005
  variant: success ? "success" : "error",
813
1006
  title: success ? "Refund submitted" : "Refund failed",
814
1007
  subtitle: success ? "Your funds are being returned on the source chain." : void 0
@@ -823,7 +1016,7 @@ function ResultStep({
823
1016
  " ",
824
1017
  result.symbol
825
1018
  ] }),
826
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.TokenIcon, { symbol: result.symbol }) })
1019
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-icon", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.TokenIcon, { symbol: result.symbol }) })
827
1020
  ] })
828
1021
  ] }),
829
1022
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rs-review-detail-row", children: [
@@ -844,25 +1037,26 @@ function ResultStep({
844
1037
  rel: "noreferrer",
845
1038
  children: [
846
1039
  short,
847
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.ExternalLinkIcon, {})
1040
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.ExternalLinkIcon, {})
848
1041
  ]
849
1042
  }
850
1043
  ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "rs-review-detail-value", children: short });
851
1044
  })()
852
1045
  ] })
853
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.Callout, { variant: "error", children: error }),
1046
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.Callout, { variant: "error", children: error }),
854
1047
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rs-screen-button-row", children: success ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
855
- onReset && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.Button, { variant: "outline", onClick: onReset, fullWidth: true, children: "Claim another deposit" }),
856
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.Button, { onClick: onClose, fullWidth: true, children: "Done" })
1048
+ onReset && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.Button, { variant: "outline", onClick: onReset, fullWidth: true, children: "Claim another deposit" }),
1049
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.Button, { onClick: onClose, fullWidth: true, children: "Done" })
857
1050
  ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
858
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.Button, { variant: "outline", onClick: onClose, fullWidth: true, children: "Cancel" }),
859
- onRetry && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.Button, { onClick: onRetry, fullWidth: true, children: "Try again" })
1051
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.Button, { variant: "outline", onClick: onClose, fullWidth: true, children: "Cancel" }),
1052
+ onRetry && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.Button, { onClick: onRetry, fullWidth: true, children: "Try again" })
860
1053
  ] }) })
861
1054
  ] }),
862
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkBRYNGLDMcjs.PoweredBy, {})
1055
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkV2OBGLJDcjs.PoweredBy, {})
863
1056
  ] });
864
1057
  }
865
1058
 
866
1059
 
867
1060
 
868
- exports.ClaimModal = ClaimModal;
1061
+
1062
+ exports.buildClaimAnalyticsSessionProperties = buildClaimAnalyticsSessionProperties; exports.ClaimModal = ClaimModal;