@rhinestone/deposit-modal 0.18.0 → 0.19.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 (48) hide show
  1. package/README.md +49 -8
  2. package/dist/{DepositModalReown-TVO3ZQQK.cjs → DepositModalReown-UITYXJ6W.cjs} +16 -16
  3. package/dist/{DepositModalReown-VCY65DJX.mjs → DepositModalReown-XBNY6QCI.mjs} +3 -3
  4. package/dist/{WithdrawModal-RMCYJJ4S.mjs → WithdrawModal-DY6A55OA.mjs} +3 -3
  5. package/dist/WithdrawModal-V42OK7L3.cjs +11 -0
  6. package/dist/{chunk-AIZKGFVA.mjs → chunk-5NWLS5BQ.mjs} +69 -19
  7. package/dist/{chunk-R2B6VD4E.mjs → chunk-BIL4ENC3.mjs} +1 -1
  8. package/dist/{chunk-34JVJZEZ.cjs → chunk-EG4H7OMC.cjs} +71 -71
  9. package/dist/{chunk-N3AAT6BS.cjs → chunk-HMUGY66O.cjs} +226 -176
  10. package/dist/{chunk-O4JZKKCZ.cjs → chunk-ISLVD5HQ.cjs} +2 -2
  11. package/dist/{chunk-EKC2IRQG.mjs → chunk-NITKDXHR.mjs} +211 -31
  12. package/dist/{chunk-JV5OGG53.cjs → chunk-OCWSMLOP.cjs} +724 -544
  13. package/dist/{chunk-N6JJG57R.cjs → chunk-PYOC6K24.cjs} +1 -1
  14. package/dist/{chunk-3TEVMP76.mjs → chunk-X6N2XPTO.mjs} +1 -1
  15. package/dist/{chunk-X4EUXBHJ.mjs → chunk-ZGHVJ2XM.mjs} +1 -1
  16. package/dist/compliance.cjs +4 -4
  17. package/dist/compliance.mjs +2 -2
  18. package/dist/constants.cjs +2 -2
  19. package/dist/constants.d.cts +1 -1
  20. package/dist/constants.d.ts +1 -1
  21. package/dist/constants.mjs +1 -1
  22. package/dist/deposit.cjs +4 -4
  23. package/dist/deposit.d.cts +2 -2
  24. package/dist/deposit.d.ts +2 -2
  25. package/dist/deposit.mjs +3 -3
  26. package/dist/embed.cjs +14 -14
  27. package/dist/embed.d.cts +1 -1
  28. package/dist/embed.d.ts +1 -1
  29. package/dist/embed.mjs +4 -4
  30. package/dist/index.cjs +5 -5
  31. package/dist/index.d.cts +1 -1
  32. package/dist/index.d.ts +1 -1
  33. package/dist/index.mjs +4 -4
  34. package/dist/offramp.cjs +9 -9
  35. package/dist/offramp.mjs +7 -7
  36. package/dist/onramp.cjs +24 -11
  37. package/dist/onramp.d.cts +24 -6
  38. package/dist/onramp.d.ts +24 -6
  39. package/dist/onramp.mjs +22 -9
  40. package/dist/styles.css +25 -0
  41. package/dist/{types-CZYypODQ.d.ts → types-BOxa1DE-.d.ts} +37 -2
  42. package/dist/{types-CbUs4boj.d.cts → types-BShYNpvO.d.cts} +37 -2
  43. package/dist/withdraw.cjs +4 -4
  44. package/dist/withdraw.d.cts +2 -2
  45. package/dist/withdraw.d.ts +2 -2
  46. package/dist/withdraw.mjs +3 -3
  47. package/package.json +5 -5
  48. package/dist/WithdrawModal-GR3HLYXU.cjs +0 -11
package/README.md CHANGED
@@ -114,6 +114,31 @@ time, it does not emit the `submitted` lifecycle event with the processor's
114
114
  internal tracking key. Its `complete` event reports the settled source and
115
115
  destination transaction hashes once they exist.
116
116
 
117
+ ## Checkout payments
118
+
119
+ Pass `payment` when the modal funds one merchant order:
120
+
121
+ ```tsx
122
+ <DepositModal
123
+ {...depositProps}
124
+ payment={{ salt: order.accountSalt, amount: order.amountBaseUnits }}
125
+ />
126
+ ```
127
+
128
+ Register the order's managed account on your server first, then pass its 32-byte
129
+ salt to the modal. The same salt must resolve to the account address stored with
130
+ the order. `amount` is the required **destination token amount in base units**,
131
+ not a USD amount. The modal asks `/quotes/preview` for an `exactOut` quote and
132
+ shows the source amount the payer should send; the backend proxy must forward
133
+ that route to a processor with `exactOut` support.
134
+
135
+ Reconcile using the account on processor webhooks or `GET /deposits?account=`.
136
+ `destinationAmount` on the `complete` event is the amount actually delivered in
137
+ destination token base units. Quotes are estimates, and a payer using a QR,
138
+ exchange, or card can send a different amount, so compare the delivered amount
139
+ with the order amount before marking it paid. Checkout mode withholds the
140
+ recipient's deposit history from the payer.
141
+
117
142
  ## Withdraw
118
143
 
119
144
  `WithdrawModal` lives at `@rhinestone/deposit-modal/withdraw` and reports through the same `onLifecycle` + `onError` callbacks. It needs no wallet: you give it the account holding the funds and a function that performs one transfer.
@@ -375,21 +400,24 @@ const options = {
375
400
  };
376
401
  const onramp = createOnrampService(options);
377
402
  const offramp = createOfframpService(options);
378
- const interaction = await onramp.createSession({
403
+ const setup = await onramp.createSetup({
379
404
  purpose: 'account_setup',
380
405
  country: 'DE',
381
406
  currency: 'EUR',
382
407
  paymentMethod: 'bank_transfer',
383
408
  });
384
- // The hosted journey handles verification through interaction.nextAction.
409
+ // Setup completes in this call and returns the account it configured.
410
+ // Show the customer their bank details through a separate, repeatable call:
411
+ const { nextAction } = await onramp.getAccountDetails(setup.account.id);
385
412
  const status = await getComplianceStatus(options);
386
413
  ```
387
414
 
388
- The onramp client has `createSession`, `getSession`, `getOptions`, `listAccounts`,
389
- `getAccount`, `listPayments` and `getPayment`. The offramp client has the same
390
- session/options/payment methods, without accounts. `getComplianceStatus` retains
391
- the existing `/compliance/status` read separately; it is not a preliminary step.
392
- Shared types include `RampSession`, `RampOption` and `RampCurrency`.
415
+ The onramp client has `createSetup`, `getSetup`, `getOptions`, `listAccounts`,
416
+ `getAccount`, `getAccountDetails`, `listPayments` and `getPayment`. The offramp
417
+ client has session/options/payment methods, without accounts.
418
+ `getComplianceStatus` retains the existing `/compliance/status` read separately;
419
+ it is not a preliminary step. Shared types include `RampSession` (offramp),
420
+ `OnrampSetup`, `RampOption` and `RampCurrency`.
393
421
  `CustomerSession` remains the browser bearer/expiry pair. Catch `ScopedRequestError`
394
422
  and inspect its `status` for HTTP failures; response bodies are not included.
395
423
 
@@ -403,7 +431,20 @@ until explicitly invoked, so existing modals and Swapped flows remain unchanged.
403
431
  There is no preliminary capability request. Support/recovery methods belong to
404
432
  the future provider lifecycle implementation and are not exposed here.
405
433
 
406
- The initial contracts support EUR/USD bank transfers only. Onramp hosted setup
434
+ **An onramp setup is not a session.** It completes in the call that creates it
435
+ and returns `{ id, account }` — no status to poll, no expiry, no `nextAction`.
436
+ Bank details are read separately through `getAccountDetails`, because a customer
437
+ reads them before every transfer while setup happens once; that call returns a
438
+ hosted address and never the coordinates themselves. An offramp session keeps
439
+ `RampSession` with its status, expiry and `nextAction`, because it really is one
440
+ interaction.
441
+
442
+ Routes are scoped to the provider that serves them — `/onramp/noah/*` and
443
+ `/offramp/noah/*` here, while the existing Swapped flows keep their own paths.
444
+ A proxy must allow each one explicitly; an unlisted path 404s before reaching
445
+ the processor.
446
+
447
+ The initial contracts support EUR/USD bank transfers only. Onramp setup
407
448
  uses `purpose: 'account_setup'` without an amount; the actual transfer determines
408
449
  fiat sent. Offramp hosted beneficiary collection uses
409
450
  `purpose: 'beneficiary_collection'`, separately from quoting and funding.
@@ -1,7 +1,7 @@
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
3
 
4
- var _chunkJV5OGG53cjs = require('./chunk-JV5OGG53.cjs');
4
+ var _chunkOCWSMLOPcjs = require('./chunk-OCWSMLOP.cjs');
5
5
  require('./chunk-LVCD6RHF.cjs');
6
6
 
7
7
 
@@ -11,12 +11,12 @@ require('./chunk-LVCD6RHF.cjs');
11
11
 
12
12
 
13
13
 
14
- var _chunkN3AAT6BScjs = require('./chunk-N3AAT6BS.cjs');
14
+ var _chunkHMUGY66Ocjs = require('./chunk-HMUGY66O.cjs');
15
15
 
16
16
 
17
17
 
18
18
  var _chunkOY5N3E6Lcjs = require('./chunk-OY5N3E6L.cjs');
19
- require('./chunk-N6JJG57R.cjs');
19
+ require('./chunk-PYOC6K24.cjs');
20
20
 
21
21
  // src/DepositModalReown.tsx
22
22
  var _react = require('react');
@@ -44,7 +44,7 @@ var {
44
44
  unichain,
45
45
  katana,
46
46
  hyperEvm
47
- } = _chunkJV5OGG53cjs.getReownDependencies.call(void 0, )[1];
47
+ } = _chunkOCWSMLOPcjs.getReownDependencies.call(void 0, )[1];
48
48
  var APPKIT_NETWORK_BY_ID = {
49
49
  [mainnet.id]: mainnet,
50
50
  [optimism.id]: optimism,
@@ -76,7 +76,7 @@ function getAppKitNetwork(chainId) {
76
76
 
77
77
  // src/core/reown-theme.ts
78
78
  function mapTheme(theme) {
79
- const themeMode = _chunkN3AAT6BScjs.resolveThemeMode.call(void 0, _optionalChain([theme, 'optionalAccess', _ => _.mode])) === "light" ? "light" : "dark";
79
+ const themeMode = _chunkHMUGY66Ocjs.resolveThemeMode.call(void 0, _optionalChain([theme, 'optionalAccess', _ => _.mode])) === "light" ? "light" : "dark";
80
80
  const themeVariables = {
81
81
  "--apkt-accent": _optionalChain([theme, 'optionalAccess', _2 => _2.ctaColor])
82
82
  };
@@ -93,7 +93,7 @@ function setAppKitTheme(appKit, theme) {
93
93
 
94
94
  // src/core/reown.tsx
95
95
  var _jsxruntime = require('react/jsx-runtime');
96
- var [appKitReact, appKitNetworks, wagmiAdapter, solanaAdapter] = _chunkJV5OGG53cjs.getReownDependencies.call(void 0, );
96
+ var [appKitReact, appKitNetworks, wagmiAdapter, solanaAdapter] = _chunkOCWSMLOPcjs.getReownDependencies.call(void 0, );
97
97
  var {
98
98
  createAppKit,
99
99
  useAppKit,
@@ -109,14 +109,14 @@ function buildTransports(rpcUrls, networks = EVM_NETWORKS) {
109
109
  const transports = {};
110
110
  for (const network of networks) {
111
111
  const id = Number(network.id);
112
- transports[id] = _viem.http.call(void 0, _chunkN3AAT6BScjs.rpcUrlFor.call(void 0, rpcUrls, id));
112
+ transports[id] = _viem.http.call(void 0, _chunkHMUGY66Ocjs.rpcUrlFor.call(void 0, rpcUrls, id));
113
113
  }
114
114
  return transports;
115
115
  }
116
116
  function getEvmRpcFingerprint(rpcUrls, networks) {
117
117
  return networks.map((network) => {
118
118
  const id = Number(network.id);
119
- return `${id}=${_nullishCoalesce(_chunkN3AAT6BScjs.rpcUrlFor.call(void 0, rpcUrls, id), () => ( ""))}`;
119
+ return `${id}=${_nullishCoalesce(_chunkHMUGY66Ocjs.rpcUrlFor.call(void 0, rpcUrls, id), () => ( ""))}`;
120
120
  }).join("|");
121
121
  }
122
122
  var cachedAdapter = null;
@@ -187,7 +187,7 @@ function ReownWalletProvider({
187
187
  backendUrl,
188
188
  children
189
189
  }) {
190
- const rpcUrls = _chunkN3AAT6BScjs.useStableRpcUrls.call(void 0, rpcUrlsProp);
190
+ const rpcUrls = _chunkHMUGY66Ocjs.useStableRpcUrls.call(void 0, rpcUrlsProp);
191
191
  const [queryClient] = _react.useState.call(void 0, () => new (0, _reactquery.QueryClient)());
192
192
  const overrides = _react.useMemo.call(void 0, () => {
193
193
  if (!rpcUrls) return void 0;
@@ -199,14 +199,14 @@ function ReownWalletProvider({
199
199
  return out;
200
200
  }, [rpcUrls]);
201
201
  const [state, setState] = _react.useState.call(void 0, () => {
202
- const primed = _chunkN3AAT6BScjs.peekRuntimeChains.call(void 0, backendUrl, overrides);
202
+ const primed = _chunkHMUGY66Ocjs.peekRuntimeChains.call(void 0, backendUrl, overrides);
203
203
  return { ready: primed !== null, chains: _nullishCoalesce(primed, () => ( [])) };
204
204
  });
205
205
  _react.useEffect.call(void 0, () => {
206
206
  let active = true;
207
- const primed = _chunkN3AAT6BScjs.peekRuntimeChains.call(void 0, backendUrl, overrides);
207
+ const primed = _chunkHMUGY66Ocjs.peekRuntimeChains.call(void 0, backendUrl, overrides);
208
208
  setState({ ready: primed !== null, chains: _nullishCoalesce(primed, () => ( [])) });
209
- _chunkN3AAT6BScjs.primeRuntimeChains.call(void 0, backendUrl, overrides).then((chains) => {
209
+ _chunkHMUGY66Ocjs.primeRuntimeChains.call(void 0, backendUrl, overrides).then((chains) => {
210
210
  if (active) setState({ ready: true, chains });
211
211
  });
212
212
  return () => {
@@ -215,7 +215,7 @@ function ReownWalletProvider({
215
215
  }, [backendUrl, overrides]);
216
216
  _react.useEffect.call(void 0, () => {
217
217
  setAppKitTheme(appKitReact.modal, theme);
218
- return _chunkN3AAT6BScjs.followSystemAppearance.call(void 0,
218
+ return _chunkHMUGY66Ocjs.followSystemAppearance.call(void 0,
219
219
  _optionalChain([theme, 'optionalAccess', _7 => _7.mode]),
220
220
  () => setAppKitTheme(appKitReact.modal, theme)
221
221
  );
@@ -279,7 +279,7 @@ function useReownWalletSession() {
279
279
  await switchChainAsync({ chainId });
280
280
  }
281
281
  } catch (err) {
282
- if (_chunkN3AAT6BScjs.isUnsupportedChainSwitchError.call(void 0, err)) {
282
+ if (_chunkHMUGY66Ocjs.isUnsupportedChainSwitchError.call(void 0, err)) {
283
283
  throw new Error(
284
284
  `Switch to ${chainDisplayName(chainId)} in your wallet to continue`
285
285
  );
@@ -292,7 +292,7 @@ function useReownWalletSession() {
292
292
 
293
293
  // src/DepositModalReown.tsx
294
294
 
295
- var [appKitReact2, , , , solanaAdapterReact] = _chunkJV5OGG53cjs.getReownDependencies.call(void 0, );
295
+ var [appKitReact2, , , , solanaAdapterReact] = _chunkOCWSMLOPcjs.getReownDependencies.call(void 0, );
296
296
  var { useAppKitProvider } = appKitReact2;
297
297
  var { useAppKitConnection } = solanaAdapterReact;
298
298
  function DepositModalWithReown(props) {
@@ -314,7 +314,7 @@ function DepositModalWithReown(props) {
314
314
  reown.disconnect();
315
315
  }, [reown.disconnect]);
316
316
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
317
- _chunkJV5OGG53cjs.DepositModalInner,
317
+ _chunkOCWSMLOPcjs.DepositModalInner,
318
318
  {
319
319
  ...props,
320
320
  walletSession: reownWithSolana,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DepositModalInner,
3
3
  getReownDependencies
4
- } from "./chunk-EKC2IRQG.mjs";
4
+ } from "./chunk-NITKDXHR.mjs";
5
5
  import "./chunk-FTWKAJGN.mjs";
6
6
  import {
7
7
  followSystemAppearance,
@@ -11,12 +11,12 @@ import {
11
11
  resolveThemeMode,
12
12
  rpcUrlFor,
13
13
  useStableRpcUrls
14
- } from "./chunk-AIZKGFVA.mjs";
14
+ } from "./chunk-5NWLS5BQ.mjs";
15
15
  import {
16
16
  SUPPORTED_CHAIN_IDS,
17
17
  getChainName
18
18
  } from "./chunk-EAGMY3QE.mjs";
19
- import "./chunk-3TEVMP76.mjs";
19
+ import "./chunk-X6N2XPTO.mjs";
20
20
 
21
21
  // src/DepositModalReown.tsx
22
22
  import { useCallback, useMemo as useMemo2 } from "react";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  WithdrawModal,
3
3
  buildWithdrawAnalyticsSessionProperties
4
- } from "./chunk-R2B6VD4E.mjs";
5
- import "./chunk-AIZKGFVA.mjs";
4
+ } from "./chunk-BIL4ENC3.mjs";
5
+ import "./chunk-5NWLS5BQ.mjs";
6
6
  import "./chunk-EAGMY3QE.mjs";
7
- import "./chunk-3TEVMP76.mjs";
7
+ import "./chunk-X6N2XPTO.mjs";
8
8
  export {
9
9
  WithdrawModal,
10
10
  buildWithdrawAnalyticsSessionProperties
@@ -0,0 +1,11 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+ var _chunkEG4H7OMCcjs = require('./chunk-EG4H7OMC.cjs');
5
+ require('./chunk-HMUGY66O.cjs');
6
+ require('./chunk-OY5N3E6L.cjs');
7
+ require('./chunk-PYOC6K24.cjs');
8
+
9
+
10
+
11
+ exports.WithdrawModal = _chunkEG4H7OMCcjs.WithdrawModal; exports.buildWithdrawAnalyticsSessionProperties = _chunkEG4H7OMCcjs.buildWithdrawAnalyticsSessionProperties;
@@ -35,7 +35,7 @@ import {
35
35
  import {
36
36
  MODAL_VERSION,
37
37
  serviceHeaders
38
- } from "./chunk-3TEVMP76.mjs";
38
+ } from "./chunk-X6N2XPTO.mjs";
39
39
 
40
40
  // src/components/ui/Modal.tsx
41
41
  import {
@@ -625,6 +625,8 @@ function parseQuotePreview(raw) {
625
625
  }
626
626
  const output = parseQuoteOutput(obj.output);
627
627
  if (!output) return null;
628
+ const input = obj.input === void 0 ? void 0 : parseQuoteOutput(obj.input);
629
+ if (obj.input !== void 0 && !input) return null;
628
630
  const fees = obj.fees;
629
631
  if (typeof fees !== "object" || fees === null) return null;
630
632
  const total = fees.total;
@@ -657,6 +659,7 @@ function parseQuotePreview(raw) {
657
659
  estimatedFillTimeSeconds: obj.estimatedFillTimeSeconds,
658
660
  fees: { total: { usd: totalUsd }, breakdown },
659
661
  output,
662
+ ...input ? { input } : {},
660
663
  ...timing ? { timing } : {}
661
664
  };
662
665
  }
@@ -1351,13 +1354,18 @@ function createDepositService(baseUrl, options) {
1351
1354
  // chain, and a HyperCore source token is a 16-byte Core spot tokenId.
1352
1355
  sourceChainId: params.sourceChainId === "hypercore" ? HYPERCORE_SPOT_CAIP2 : `eip155:${params.sourceChainId}`,
1353
1356
  sourceToken: params.sourceToken,
1354
- amount: params.amount
1357
+ // Each direction carries its own amount field and omits the other, which
1358
+ // is what the processor's "exactly one of" refinement checks. Sending
1359
+ // both is a 400, so spread rather than always emitting `amount`.
1360
+ ...params.direction === "exactOut" ? { direction: "exactOut", amountOut: params.amountOut } : { amount: params.amount }
1355
1361
  };
1356
1362
  debugLog(debug, scope, "getQuotePreview:request", {
1357
1363
  url,
1358
1364
  sourceChainId: body.sourceChainId,
1359
1365
  sourceToken: params.sourceToken,
1360
- amount: params.amount
1366
+ direction: params.direction ?? "exactIn",
1367
+ amount: params.amount,
1368
+ amountOut: params.amountOut
1361
1369
  });
1362
1370
  return withPreflightTimeout("getQuotePreview", null, async (signal) => {
1363
1371
  try {
@@ -3203,6 +3211,7 @@ function toRecoverableDeposit(row, options = {}) {
3203
3211
  depositId: row.id,
3204
3212
  signer,
3205
3213
  destinationPrefill: signer,
3214
+ depositAddress: row.depositAddress,
3206
3215
  sourceChainId,
3207
3216
  targetChainId,
3208
3217
  token: row.token,
@@ -3210,6 +3219,12 @@ function toRecoverableDeposit(row, options = {}) {
3210
3219
  sourceTxHash: sourceDepositTxHash(row)
3211
3220
  };
3212
3221
  }
3222
+ function isDepositSelfDestination(row, destination) {
3223
+ const depositAddress = row.depositAddress?.trim();
3224
+ const candidate = destination.trim();
3225
+ if (!depositAddress || !candidate) return false;
3226
+ return depositAddress.toLowerCase() === candidate.toLowerCase();
3227
+ }
3213
3228
  function recoveryFailureCause(sourceChainName) {
3214
3229
  return sourceChainName ? `This deposit couldn't be completed. Your funds are still on ${sourceChainName}.` : "This deposit couldn't be completed and your funds were not moved.";
3215
3230
  }
@@ -5168,9 +5183,11 @@ function RecoveryReviewScreen({
5168
5183
  txHash,
5169
5184
  defaultDestination,
5170
5185
  destinationHint,
5186
+ depositAddress,
5171
5187
  submitting,
5172
5188
  onSubmit,
5173
- onDestinationInvalid
5189
+ onDestinationInvalid,
5190
+ onDestinationIsDepositAddress
5174
5191
  }) {
5175
5192
  const { symbol, amount, chainName, chainIcon } = describeRecoveryDeposit({
5176
5193
  chainId,
@@ -5181,13 +5198,30 @@ function RecoveryReviewScreen({
5181
5198
  const [destination, setDestination] = useState6(
5182
5199
  defaultDestination ?? ""
5183
5200
  );
5184
- const destinationValid = isAddress2(destination);
5201
+ const isSelfDestination = isDepositSelfDestination(
5202
+ { depositAddress },
5203
+ destination
5204
+ );
5205
+ const destinationValid = isAddress2(destination) && !isSelfDestination;
5185
5206
  const onDestinationInvalidRef = useLatestRef(onDestinationInvalid);
5207
+ const onDestinationIsDepositAddressRef = useLatestRef(
5208
+ onDestinationIsDepositAddress
5209
+ );
5186
5210
  useEffect8(() => {
5187
- if (destination.length > 0 && !destinationValid) {
5211
+ if (destination.length === 0) return;
5212
+ if (isSelfDestination) {
5213
+ onDestinationIsDepositAddressRef.current?.();
5214
+ } else if (!destinationValid) {
5188
5215
  onDestinationInvalidRef.current?.();
5189
5216
  }
5190
- }, [destination, destinationValid, onDestinationInvalidRef]);
5217
+ }, [
5218
+ destination,
5219
+ destinationValid,
5220
+ isSelfDestination,
5221
+ onDestinationInvalidRef,
5222
+ onDestinationIsDepositAddressRef
5223
+ ]);
5224
+ const selfDestinationError = `${shortenAddress(destination)} is this deposit's own address. Enter a different address.`;
5191
5225
  const txUrl = txHash ? explorerTxUrl(chainId, txHash) : null;
5192
5226
  const txShort = txHash ? shortenHash2(txHash) : "\u2014";
5193
5227
  return /* @__PURE__ */ jsxs14("div", { className: "rs-screen", children: [
@@ -5244,7 +5278,7 @@ function RecoveryReviewScreen({
5244
5278
  value: destination,
5245
5279
  onChange: (e) => setDestination(e.target.value),
5246
5280
  hint: destinationHint,
5247
- error: destination.length > 0 && !destinationValid ? "Enter a valid address" : void 0
5281
+ error: isSelfDestination ? selfDestinationError : destination.length > 0 && !destinationValid ? "Enter a valid address" : void 0
5248
5282
  }
5249
5283
  ),
5250
5284
  /* @__PURE__ */ jsx20(
@@ -5422,9 +5456,14 @@ function HistoryRecoveryFlow({
5422
5456
  txHash: deposit.sourceTxHash,
5423
5457
  defaultDestination: deposit.destinationPrefill,
5424
5458
  destinationHint: "Prefilled with the account this deposit was for. Editable.",
5459
+ depositAddress: deposit.depositAddress,
5425
5460
  submitting,
5426
5461
  onSubmit: submit,
5427
- onDestinationInvalid: () => analytics.friction("refund_destination_invalid", "review")
5462
+ onDestinationInvalid: () => analytics.friction("refund_destination_invalid", "review"),
5463
+ onDestinationIsDepositAddress: () => analytics.friction(
5464
+ "refund_destination_is_deposit_address",
5465
+ "review"
5466
+ )
5428
5467
  }
5429
5468
  ),
5430
5469
  phase === "success" && outcome && /* @__PURE__ */ jsx21(
@@ -6891,6 +6930,10 @@ function getCurrentPhaseId(state, phaseTimings) {
6891
6930
  if (state.lastEvent?.type === "deposit-received") return "received";
6892
6931
  return "confirming";
6893
6932
  }
6933
+ function getCompletionDestinationAmount(event) {
6934
+ const amount = event?.data?.destination?.amount;
6935
+ return typeof amount === "string" ? amount : void 0;
6936
+ }
6894
6937
  function getCompletionDestinationTxHash(event) {
6895
6938
  const eventData = event?.data;
6896
6939
  const swapTxHash = eventData?.swap?.transactionHash;
@@ -6901,7 +6944,8 @@ function getTerminalProcessingOutcome(event) {
6901
6944
  if (event?.type === "post-bridge-swap-complete") {
6902
6945
  return {
6903
6946
  type: "complete",
6904
- destinationTxHash: getCompletionDestinationTxHash(event)
6947
+ destinationTxHash: getCompletionDestinationTxHash(event),
6948
+ destinationAmount: getCompletionDestinationAmount(event)
6905
6949
  };
6906
6950
  }
6907
6951
  if (event?.type === "post-bridge-swap-failed") {
@@ -6913,7 +6957,8 @@ function getTerminalProcessingOutcome(event) {
6913
6957
  if (event?.type === "bridge-complete") {
6914
6958
  return {
6915
6959
  type: "complete",
6916
- destinationTxHash: getCompletionDestinationTxHash(event)
6960
+ destinationTxHash: getCompletionDestinationTxHash(event),
6961
+ destinationAmount: getCompletionDestinationAmount(event)
6917
6962
  };
6918
6963
  }
6919
6964
  if (event?.type === "bridge-failed") {
@@ -7100,7 +7145,8 @@ function ProcessingStep({
7100
7145
  sourceDecimals: context.sourceDecimals,
7101
7146
  amountUsd: context.amountUsd,
7102
7147
  targetChain: context.targetChain,
7103
- targetToken: context.targetToken
7148
+ targetToken: context.targetToken,
7149
+ destinationAmount: outcome.destinationAmount
7104
7150
  }
7105
7151
  );
7106
7152
  return;
@@ -7241,7 +7287,8 @@ function ProcessingStep({
7241
7287
  eventForCurrentTx,
7242
7288
  txHash
7243
7289
  );
7244
- const destinationTxHash2 = eventForCurrentTx.data?.destination?.transactionHash;
7290
+ const destination = eventForCurrentTx.data?.destination;
7291
+ const destinationTxHash2 = destination?.transactionHash;
7245
7292
  debugLog(debug, "processing", "state:complete", {
7246
7293
  txHash,
7247
7294
  sourceTxHash: sourceTxHash2,
@@ -7256,7 +7303,8 @@ function ProcessingStep({
7256
7303
  sourceDecimals: context.sourceDecimals,
7257
7304
  amountUsd: context.amountUsd,
7258
7305
  targetChain: context.targetChain,
7259
- targetToken: context.targetToken
7306
+ targetToken: context.targetToken,
7307
+ destinationAmount: typeof destination?.amount === "string" ? destination.amount : void 0
7260
7308
  });
7261
7309
  return;
7262
7310
  }
@@ -7342,8 +7390,8 @@ function ProcessingStep({
7342
7390
  const lastEvent = state.lastEvent;
7343
7391
  const failureMessage = state.type === "failed" ? state.message : void 0;
7344
7392
  const timelineNowMs = phaseTimings.endedAt ?? Date.now();
7345
- const flowNoun = flowLabel === "withdraw" ? "withdrawal" : "deposit";
7346
- const flowCapitalized = flowLabel === "withdraw" ? "Withdrawal" : "Deposit";
7393
+ const flowNoun = flowLabel === "withdraw" ? "withdrawal" : flowLabel === "payment" ? "payment" : "deposit";
7394
+ const flowCapitalized = flowLabel === "withdraw" ? "Withdrawal" : flowLabel === "payment" ? "Payment" : "Deposit";
7347
7395
  const destinationTxHash = lastEvent?.data?.destination?.transactionHash || null;
7348
7396
  const sourceTxHash = getSettledSourceTxHash(lastEvent, txHash);
7349
7397
  const sourceDetails = getEventSourceDetails(lastEvent);
@@ -7797,7 +7845,8 @@ function computeRequestKey(input) {
7797
7845
  recipient: normalizeKeyToken(input.recipient),
7798
7846
  outputTokenRules: input.outputTokenRules ?? null,
7799
7847
  rejectUnmapped: input.rejectUnmapped ?? null,
7800
- forceRegister: input.forceRegister ?? false
7848
+ forceRegister: input.forceRegister ?? false,
7849
+ salt: input.salt ?? null
7801
7850
  });
7802
7851
  }
7803
7852
  function computeCacheKey(input) {
@@ -7806,7 +7855,8 @@ function computeCacheKey(input) {
7806
7855
  targetToken: normalizeKeyToken(input.targetToken),
7807
7856
  recipient: normalizeKeyToken(input.recipient),
7808
7857
  outputTokenRules: input.outputTokenRules ?? null,
7809
- rejectUnmapped: input.rejectUnmapped ?? null
7858
+ rejectUnmapped: input.rejectUnmapped ?? null,
7859
+ salt: input.salt ?? null
7810
7860
  });
7811
7861
  }
7812
7862
  function computeIsCacheable(input) {
@@ -7838,7 +7888,7 @@ async function runAccountSetup(input, deps) {
7838
7888
  );
7839
7889
  }
7840
7890
  try {
7841
- const salt = deriveAccountSalt(input);
7891
+ const salt = input.salt ?? deriveAccountSalt(input);
7842
7892
  debugLog(debug, "account-setup", "setup:start", {
7843
7893
  salt,
7844
7894
  recipient: input.recipient,
@@ -44,7 +44,7 @@ import {
44
44
  useTokenPrices,
45
45
  useWithdrawAnalyticsEmitter,
46
46
  warnRemovedProps
47
- } from "./chunk-AIZKGFVA.mjs";
47
+ } from "./chunk-5NWLS5BQ.mjs";
48
48
  import {
49
49
  NATIVE_TOKEN_ADDRESS,
50
50
  getChainIcon,