kaleido-ui 0.1.71 → 0.1.73

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.
@@ -2245,7 +2245,7 @@ var LOGO_PATHS = /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runti
2245
2245
  ),
2246
2246
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("path", { d: "M274.479 0.104797H411.786L274.533 137.411H137.226L274.479 0.104797Z", fill: "#17B581" })
2247
2247
  ] });
2248
- function QrCode({ value, size = 160, className }) {
2248
+ function QrCode({ value, size = 160, className, tone = "onLight" }) {
2249
2249
  const svgContent = (0, import_react6.useMemo)(() => {
2250
2250
  if (!value) return null;
2251
2251
  const matrix = (0, import_qr.default)(value, "raw", { ecc: "medium", border: 0 });
@@ -2253,8 +2253,8 @@ function QrCode({ value, size = 160, className }) {
2253
2253
  const moduleSize = 10;
2254
2254
  const quietZone = moduleSize * 2;
2255
2255
  const svgSize = n * moduleSize + quietZone * 2;
2256
- const fg = "#040404";
2257
- const bg = "#ffffff";
2256
+ const fg = tone === "onDark" ? "#ffffff" : "#040404";
2257
+ const bg = tone === "onDark" ? "transparent" : "#ffffff";
2258
2258
  const logoModules = Math.ceil(n * 0.2);
2259
2259
  const logoZoneSize = logoModules % 2 === 0 ? logoModules + 1 : logoModules;
2260
2260
  const elements = [];
@@ -2308,7 +2308,7 @@ function QrCode({ value, size = 160, className }) {
2308
2308
  children: elements
2309
2309
  }
2310
2310
  );
2311
- }, [value]);
2311
+ }, [value, tone]);
2312
2312
  return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className, style: { width: size, height: size }, children: svgContent });
2313
2313
  }
2314
2314
 
@@ -4676,16 +4676,17 @@ function WithdrawDestinationInput({
4676
4676
  onChange: (event) => setDestination(event.target.value)
4677
4677
  }
4678
4678
  ),
4679
- /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "absolute right-4 top-1/2 flex -translate-y-1/2 items-center gap-2", children: [
4679
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "absolute right-3 top-1/2 flex -translate-y-1/2 items-center gap-1", children: [
4680
4680
  destination && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4681
4681
  "button",
4682
4682
  {
4683
4683
  type: "button",
4684
+ "aria-label": "Clear",
4684
4685
  onClick: () => {
4685
4686
  setDestination("");
4686
4687
  handleReset();
4687
4688
  },
4688
- className: "text-xs text-muted-foreground transition-colors hover:text-white",
4689
+ className: "rounded-lg p-2 text-muted-foreground transition-colors hover:text-white",
4689
4690
  children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "material-symbols-outlined text-icon-md", children: "close" })
4690
4691
  }
4691
4692
  ),
@@ -4693,9 +4694,10 @@ function WithdrawDestinationInput({
4693
4694
  "button",
4694
4695
  {
4695
4696
  type: "button",
4697
+ "aria-label": "Paste",
4696
4698
  onClick: handlePaste,
4697
- className: "rounded-lg bg-white/10 px-2.5 py-1 text-xs font-medium text-primary transition-colors hover:bg-white/20",
4698
- children: "Paste"
4699
+ className: "rounded-lg bg-white/5 p-2 text-muted-foreground transition-colors hover:text-primary",
4700
+ children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "material-symbols-outlined text-icon-md", children: "content_paste" })
4699
4701
  }
4700
4702
  )
4701
4703
  ] })
@@ -4808,7 +4810,7 @@ function WithdrawAmountInput({
4808
4810
  const value = parseInt(event.target.value, 10);
4809
4811
  if (!Number.isNaN(value)) setWitnessAmountSat(value);
4810
4812
  },
4811
- className: "w-full rounded-xl border bg-card px-4 py-3 text-sm text-white transition-colors focus:border-primary/50 focus:outline-none"
4813
+ className: "w-full rounded-xl bg-card px-4 py-3 text-sm text-white shadow-inner transition-all focus:outline focus:outline-2 focus:outline-primary/50"
4812
4814
  }
4813
4815
  ),
4814
4816
  /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "ml-1 text-xs text-muted-foreground", children: "Bitcoin amount sent to create the witness UTXO for the recipient." })
@@ -4820,7 +4822,7 @@ function WithdrawAmountInput({
4820
4822
  {
4821
4823
  type: "button",
4822
4824
  onClick: () => setFeeRate(rate),
4823
- className: `group relative overflow-hidden rounded-[16px] border px-3 py-3 shadow-sm transition-all active:scale-[0.98] ${feeRate === rate ? "border-primary/40 bg-primary/10" : "border-border bg-card/40 backdrop-blur-xl hover:border-primary/40"}`,
4825
+ className: `group relative overflow-hidden rounded-[16px] px-3 py-3 shadow-sm transition-all active:scale-[0.98] ${feeRate === rate ? "bg-primary/10" : "bg-card/40 backdrop-blur-xl hover:bg-card/60"}`,
4824
4826
  children: [
4825
4827
  /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4826
4828
  "div",
@@ -4852,7 +4854,7 @@ function WithdrawAmountInput({
4852
4854
  rate
4853
4855
  )) })
4854
4856
  ] }),
4855
- addressType === "rgb" && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center justify-between rounded-xl border bg-card p-3", children: [
4857
+ addressType === "rgb" && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center justify-between rounded-xl bg-card p-3", children: [
4856
4858
  /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { children: [
4857
4859
  /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-sm font-medium text-white", children: "Gift / Donation" }),
4858
4860
  /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-xs text-muted-foreground", children: "Skip amount checks for this transfer" })
@@ -4978,21 +4980,23 @@ function RouteChoiceCard({
4978
4980
  onClick,
4979
4981
  displayOnly
4980
4982
  }) {
4981
- const { disabled = false, disabledReason, accountIcon, balanceLabel } = route;
4982
- if (displayOnly) {
4983
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "rounded-2xl bg-card/50 px-4 py-3.5", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
4984
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex min-w-0 items-center gap-3", children: [
4985
- accountIcon && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "shrink-0", children: accountIcon }),
4986
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "min-w-0", children: [
4987
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-sm font-semibold text-white", children: route.accountTitle }),
4988
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-0.5 text-xs text-white/45", children: route.methodLabel })
4989
- ] })
4990
- ] }),
4991
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
4992
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xxs font-bold uppercase tracking-wider text-white/35", children: route.feeHint }),
4993
- balanceLabel && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "font-mono text-xxs text-white/50", children: balanceLabel })
4983
+ const { disabled = false, disabledReason, accountIcon, balanceLabel, accentClassName } = route;
4984
+ const body = /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
4985
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex min-w-0 items-start gap-3", children: [
4986
+ accountIcon && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "mt-0.5 shrink-0", children: accountIcon }),
4987
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "min-w-0", children: [
4988
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
4989
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-sm font-bold text-white", children: route.accountTitle }),
4990
+ recommended && !disabled && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xxs font-bold uppercase tracking-wider text-primary", children: "Recommended" }),
4991
+ disabled && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "rounded-full bg-danger/10 px-2 py-0.5 text-xxs font-bold uppercase tracking-wider text-danger", children: "Insufficient" })
4992
+ ] }),
4993
+ balanceLabel && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-0.5 font-mono text-xs text-white/55", children: balanceLabel })
4994
4994
  ] })
4995
- ] }) });
4995
+ ] }),
4996
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "shrink-0 text-xxs font-bold uppercase tracking-wider text-white/40", children: route.feeHint })
4997
+ ] });
4998
+ if (displayOnly) {
4999
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "rounded-2xl bg-card/50 px-4 py-3.5", children: body });
4996
5000
  }
4997
5001
  return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
4998
5002
  "button",
@@ -5004,28 +5008,11 @@ function RouteChoiceCard({
5004
5008
  "aria-disabled": disabled,
5005
5009
  title: disabled ? disabledReason : void 0,
5006
5010
  className: cn(
5007
- "w-full rounded-2xl border p-4 text-left transition-all",
5008
- disabled ? "cursor-not-allowed border-danger/15 bg-danger/5 opacity-60" : selected ? "border-primary/30 bg-primary/10" : "border-border bg-white/4 hover:border-white/20 hover:bg-white/6"
5011
+ "w-full rounded-2xl p-4 text-left transition-all",
5012
+ disabled ? "cursor-not-allowed bg-danger/5 opacity-60" : selected ? accentClassName ?? "bg-primary/10" : "bg-white/4 hover:bg-white/6"
5009
5013
  ),
5010
5014
  children: [
5011
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
5012
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex min-w-0 items-start gap-3", children: [
5013
- accountIcon && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "mt-0.5 shrink-0", children: accountIcon }),
5014
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "min-w-0", children: [
5015
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
5016
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-sm font-bold text-white", children: route.accountTitle }),
5017
- recommended && !disabled && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "rounded-full border border-primary/20 bg-primary/10 px-2 py-0.5 text-xxs font-bold uppercase tracking-wider text-primary", children: "Recommended" }),
5018
- disabled && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "rounded-full border border-danger/20 bg-danger/10 px-2 py-0.5 text-xxs font-bold uppercase tracking-wider text-danger", children: "Insufficient" })
5019
- ] }),
5020
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-1 text-xs text-white/45", children: route.methodLabel })
5021
- ] })
5022
- ] }),
5023
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
5024
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-xxs font-bold uppercase tracking-wider text-white/35", children: route.feeHint }),
5025
- balanceLabel && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "font-mono text-xxs text-white/50", children: balanceLabel })
5026
- ] })
5027
- ] }),
5028
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-3 text-xs leading-relaxed text-muted-foreground", children: route.summary }),
5015
+ body,
5029
5016
  disabled && disabledReason && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "mt-2 text-xxs leading-relaxed text-danger/80", children: disabledReason })
5030
5017
  ]
5031
5018
  }
@@ -7192,7 +7179,7 @@ var NETWORK_CONFIG = {
7192
7179
  border: "border-network-bitcoin/40",
7193
7180
  qrBorder: "border-network-bitcoin/30",
7194
7181
  qrGlow: qrGlowStyle(colors.network.bitcoin),
7195
- icon: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "material-symbols-outlined text-icon-xs leading-none", children: "link" })
7182
+ icon: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "material-symbols-outlined text-icon-xs leading-none", children: "currency_bitcoin" })
7196
7183
  },
7197
7184
  lightning: {
7198
7185
  label: "Lightning",
@@ -7604,13 +7591,13 @@ function DepositNetworkDefaultModal({
7604
7591
  }
7605
7592
 
7606
7593
  // src/web/components/btc-unified-receive.tsx
7594
+ var import_react16 = require("react");
7607
7595
  var import_jsx_runtime76 = require("react/jsx-runtime");
7608
7596
  function formatSatsForRow(value) {
7609
7597
  if (!value || value <= 0 || !Number.isFinite(value)) return null;
7610
7598
  return `${value.toLocaleString("en-US")} sats`;
7611
7599
  }
7612
7600
  function BtcUnifiedReceive({
7613
- btcSelectedAccount,
7614
7601
  accountReceiveResult,
7615
7602
  invoiceStatus,
7616
7603
  isInvoicePending,
@@ -7625,66 +7612,56 @@ function BtcUnifiedReceive({
7625
7612
  setAmount,
7626
7613
  setInvoiceStatus,
7627
7614
  setAccountReceiveResult,
7628
- handleDone,
7629
- showRegenerate = true
7615
+ showRegenerate = true,
7616
+ description,
7617
+ onDescriptionChange
7630
7618
  }) {
7631
- const accountNetwork = btcSelectedAccount === "SPARK" ? "spark" : btcSelectedAccount === "ARKADE" ? "arkade" : "onchain";
7632
- const qrNetwork = NETWORK_CONFIG[accountNetwork];
7619
+ const [showEdit, setShowEdit] = (0, import_react16.useState)(false);
7620
+ const isQrCopied = copied === accountReceiveResult.qrValue;
7621
+ const handleNewAddress = () => {
7622
+ setAddress("");
7623
+ setAmount("");
7624
+ setInvoiceStatus(null);
7625
+ setAccountReceiveResult(null);
7626
+ };
7633
7627
  return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "space-y-3 animate-in fade-in zoom-in-95 duration-300", children: [
7634
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex flex-col gap-1.5 rounded-xl border border-white/8 bg-white/3 p-2.5", children: [
7635
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "flex items-center justify-between px-1", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("label", { className: "text-xxs font-bold uppercase tracking-widest text-white/40", children: "Amount (optional)" }) }),
7636
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7637
- "input",
7638
- {
7639
- type: "text",
7640
- value: amount,
7641
- onChange: handleAmountChange,
7642
- placeholder: "Any amount",
7643
- className: "w-full rounded-lg border bg-white/5 px-3 py-1.5 font-mono text-xs font-bold text-white transition-all placeholder:text-white/25 focus:border-primary/40 focus:outline-none",
7644
- inputMode: "decimal"
7645
- }
7646
- ),
7647
- amount && loading && /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("p", { className: "flex items-center gap-1 text-xxs text-warning/70", children: [
7648
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "material-symbols-outlined animate-spin text-icon-xxs", children: "progress_activity" }),
7649
- "Updating invoice..."
7650
- ] })
7651
- ] }),
7652
7628
  /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex flex-col items-center gap-3", children: [
7653
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
7654
- "div",
7655
- {
7656
- className: cn(
7657
- "relative flex flex-col items-center rounded-2xl border-2 bg-white p-2 transition-all",
7658
- qrNetwork.qrBorder
7659
- ),
7660
- style: qrNetwork.qrGlow,
7661
- children: [
7662
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(QrCode, { value: accountReceiveResult.qrValue, size: 200 }),
7663
- isInvoicePaid && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(PaidOverlay, {})
7664
- ]
7665
- }
7666
- ),
7667
- (() => {
7668
- const isQrCopied = copied === accountReceiveResult.qrValue;
7669
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
7670
- "button",
7629
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "relative flex flex-col items-center p-2", children: [
7630
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(QrCode, { value: accountReceiveResult.qrValue, size: 200, tone: "onDark" }),
7631
+ isInvoicePaid && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(PaidOverlay, {})
7632
+ ] }),
7633
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex items-center justify-center gap-2.5", children: [
7634
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7635
+ Button,
7671
7636
  {
7672
- type: "button",
7673
- className: cn(
7674
- "flex items-center gap-1 rounded-full border px-2.5 py-1 text-xxs font-bold uppercase tracking-widest transition-all",
7675
- isQrCopied ? "border-primary/30 bg-primary/10 text-primary" : "border-border bg-white/5 text-muted-foreground hover:border-white/20 hover:bg-accent hover:text-white"
7676
- ),
7677
- onClick: (event) => {
7678
- event.stopPropagation();
7679
- void copyToClipboard(accountReceiveResult.qrValue);
7680
- },
7681
- children: [
7682
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Icon, { name: isQrCopied ? "check" : "content_copy", size: "xs" }),
7683
- isQrCopied ? "Copied" : `Copy ${accountReceiveResult.qrLabel}`
7684
- ]
7637
+ variant: "surface",
7638
+ size: "icon-xl",
7639
+ "aria-label": `Copy ${accountReceiveResult.qrLabel}`,
7640
+ onClick: () => void copyToClipboard(accountReceiveResult.qrValue),
7641
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Icon, { name: isQrCopied ? "check" : "content_copy", size: "lg" })
7685
7642
  }
7686
- );
7687
- })()
7643
+ ),
7644
+ showRegenerate && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7645
+ Button,
7646
+ {
7647
+ variant: "surface",
7648
+ size: "icon-xl",
7649
+ "aria-label": "New address",
7650
+ onClick: handleNewAddress,
7651
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Icon, { name: "refresh", size: "lg" })
7652
+ }
7653
+ ),
7654
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7655
+ Button,
7656
+ {
7657
+ variant: "surface",
7658
+ size: "icon-xl",
7659
+ "aria-label": "Edit amount and description",
7660
+ onClick: () => setShowEdit(true),
7661
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Icon, { name: "edit", size: "lg" })
7662
+ }
7663
+ )
7664
+ ] })
7688
7665
  ] }),
7689
7666
  invoiceStatus && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7690
7667
  InvoiceStatusBanner,
@@ -7703,9 +7680,8 @@ function BtcUnifiedReceive({
7703
7680
  "div",
7704
7681
  {
7705
7682
  className: cn(
7706
- "group flex cursor-pointer items-center gap-2 rounded-xl border bg-white/3 px-2.5 py-1.5",
7707
- "transition-all hover:bg-white/6 active:scale-[0.98]",
7708
- network.border
7683
+ "group flex cursor-pointer items-center gap-2 rounded-xl bg-white/3 px-2.5 py-1.5",
7684
+ "transition-all hover:bg-white/6 active:scale-[0.98]"
7709
7685
  ),
7710
7686
  style: { borderLeftWidth: 3, borderLeftColor: network.color },
7711
7687
  onClick: () => void copyToClipboard(address.value),
@@ -7729,36 +7705,48 @@ function BtcUnifiedReceive({
7729
7705
  })
7730
7706
  ] }),
7731
7707
  /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7732
- NetworkInfoDisclosure,
7708
+ BottomSheet,
7733
7709
  {
7734
- networks: Array.from(
7735
- new Set(accountReceiveResult.addresses.map((address) => address.network))
7736
- )
7710
+ open: showEdit,
7711
+ title: "Edit request",
7712
+ icon: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Icon, { name: "edit", size: "md" }),
7713
+ onClose: () => setShowEdit(false),
7714
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "space-y-4", children: [
7715
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "space-y-1.5", children: [
7716
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("label", { className: "text-xxs font-bold uppercase tracking-widest text-white/40", children: "Amount (optional)" }),
7717
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7718
+ "input",
7719
+ {
7720
+ type: "text",
7721
+ value: amount,
7722
+ onChange: handleAmountChange,
7723
+ placeholder: "Any amount",
7724
+ className: "w-full rounded-xl bg-white/5 px-3 py-2.5 font-mono text-sm font-bold text-white shadow-inner transition-all placeholder:text-white/25 focus:outline focus:outline-2 focus:outline-primary/40",
7725
+ inputMode: "decimal"
7726
+ }
7727
+ ),
7728
+ amount && loading && /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("p", { className: "flex items-center gap-1 text-xxs text-warning/70", children: [
7729
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "material-symbols-outlined animate-spin text-icon-xxs", children: "progress_activity" }),
7730
+ "Updating invoice..."
7731
+ ] })
7732
+ ] }),
7733
+ onDescriptionChange && /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "space-y-1.5", children: [
7734
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("label", { className: "text-xxs font-bold uppercase tracking-widest text-white/40", children: "Description (optional)" }),
7735
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7736
+ "input",
7737
+ {
7738
+ type: "text",
7739
+ value: description ?? "",
7740
+ onChange: (event) => onDescriptionChange(event.target.value),
7741
+ placeholder: "What's this for?",
7742
+ className: "w-full rounded-xl bg-white/5 px-3 py-2.5 text-sm text-white shadow-inner transition-all placeholder:text-white/25 focus:outline focus:outline-2 focus:outline-primary/40"
7743
+ }
7744
+ )
7745
+ ] }),
7746
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Button, { variant: "cta", className: "w-full", onClick: () => setShowEdit(false), children: "Done" })
7747
+ ] })
7737
7748
  }
7738
- ),
7739
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "flex gap-2.5 pt-1", children: [
7740
- showRegenerate && /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
7741
- "button",
7742
- {
7743
- type: "button",
7744
- onClick: () => {
7745
- setAddress("");
7746
- setAmount("");
7747
- setInvoiceStatus(null);
7748
- setAccountReceiveResult(null);
7749
- },
7750
- className: "flex flex-1 items-center justify-center gap-1.5 rounded-xl border py-3 text-xs font-bold text-muted-foreground transition-all hover:border-border hover:bg-accent hover:text-white active:scale-[0.98]",
7751
- children: [
7752
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "material-symbols-outlined text-icon-sm", children: "refresh" }),
7753
- "New Address"
7754
- ]
7755
- }
7756
- ),
7757
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(Button, { variant: "cta", onClick: handleDone, className: showRegenerate ? void 0 : "flex-1", children: [
7758
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "material-symbols-outlined text-icon-sm", children: "check" }),
7759
- "Done"
7760
- ] })
7761
- ] })
7749
+ )
7762
7750
  ] });
7763
7751
  }
7764
7752
 
@@ -8180,7 +8168,7 @@ function DepositPreGeneration({
8180
8168
  }
8181
8169
 
8182
8170
  // src/web/components/deposit-asset-selection.tsx
8183
- var import_react16 = require("react");
8171
+ var import_react17 = require("react");
8184
8172
  var import_jsx_runtime79 = require("react/jsx-runtime");
8185
8173
  var ADD_ASSET_SUBTITLE = {
8186
8174
  RGB: "RGB asset on Bitcoin",
@@ -8223,9 +8211,9 @@ function DepositAssetSelection({
8223
8211
  const ownedAssetsCount = ownedAssets.length;
8224
8212
  const noResults = filteredAssets.length === 0 && !!searchQuery;
8225
8213
  const isSearching = !!searchQuery;
8226
- const [assetsExpanded, setAssetsExpanded] = (0, import_react16.useState)(false);
8227
- const [showAddAssetModal, setShowAddAssetModal] = (0, import_react16.useState)(false);
8228
- (0, import_react16.useEffect)(() => {
8214
+ const [assetsExpanded, setAssetsExpanded] = (0, import_react17.useState)(false);
8215
+ const [showAddAssetModal, setShowAddAssetModal] = (0, import_react17.useState)(false);
8216
+ (0, import_react17.useEffect)(() => {
8229
8217
  if (isSearching) setAssetsExpanded(true);
8230
8218
  }, [isSearching]);
8231
8219
  const showOwnedAssets = isSearching ? true : assetsExpanded;
@@ -334,8 +334,14 @@ interface QrCodeProps {
334
334
  value: string;
335
335
  size?: number;
336
336
  className?: string;
337
+ /**
338
+ * 'onLight' (default) renders dark modules on a white card — use inside a
339
+ * white container. 'onDark' renders white modules on a transparent
340
+ * background so the QR sits directly on the app background.
341
+ */
342
+ tone?: 'onLight' | 'onDark';
337
343
  }
338
- declare function QrCode({ value, size, className }: QrCodeProps): react_jsx_runtime.JSX.Element;
344
+ declare function QrCode({ value, size, className, tone }: QrCodeProps): react_jsx_runtime.JSX.Element;
339
345
 
340
346
  interface BottomNavItem<TValue extends string = string> {
341
347
  id: TValue;
@@ -930,6 +936,9 @@ interface WithdrawRouteOption<TAccount extends string = string> {
930
936
  accountIcon?: ReactNode;
931
937
  /** Optional pre-formatted balance label (e.g. "1.23 BTC available") shown on the card. */
932
938
  balanceLabel?: string;
939
+ /** Optional protocol-tinted classes applied when the card is selected
940
+ * (e.g. "bg-network-spark/12"). Falls back to the brand primary tint. */
941
+ accentClassName?: string;
933
942
  }
934
943
  interface WithdrawRouteSummary {
935
944
  method: string;
@@ -1465,8 +1474,12 @@ interface BtcUnifiedReceiveProps {
1465
1474
  * button leads to a half-initialised state).
1466
1475
  */
1467
1476
  showRegenerate?: boolean;
1477
+ /** Optional request description/memo, edited alongside the amount in the
1478
+ * Edit modal. When omitted the description field is hidden. */
1479
+ description?: string;
1480
+ onDescriptionChange?: (value: string) => void;
1468
1481
  }
1469
- declare function BtcUnifiedReceive({ btcSelectedAccount, accountReceiveResult, invoiceStatus, isInvoicePending, isInvoicePaid, isInvoiceFailedOrExpired, amount, handleAmountChange, loading, copied, copyToClipboard, setAddress, setAmount, setInvoiceStatus, setAccountReceiveResult, handleDone, showRegenerate, }: BtcUnifiedReceiveProps): react_jsx_runtime.JSX.Element;
1482
+ declare function BtcUnifiedReceive({ accountReceiveResult, invoiceStatus, isInvoicePending, isInvoicePaid, isInvoiceFailedOrExpired, amount, handleAmountChange, loading, copied, copyToClipboard, setAddress, setAmount, setInvoiceStatus, setAccountReceiveResult, showRegenerate, description, onDescriptionChange, }: BtcUnifiedReceiveProps): react_jsx_runtime.JSX.Element;
1470
1483
 
1471
1484
  interface DepositGeneratedAsset {
1472
1485
  ticker?: string;
@@ -334,8 +334,14 @@ interface QrCodeProps {
334
334
  value: string;
335
335
  size?: number;
336
336
  className?: string;
337
+ /**
338
+ * 'onLight' (default) renders dark modules on a white card — use inside a
339
+ * white container. 'onDark' renders white modules on a transparent
340
+ * background so the QR sits directly on the app background.
341
+ */
342
+ tone?: 'onLight' | 'onDark';
337
343
  }
338
- declare function QrCode({ value, size, className }: QrCodeProps): react_jsx_runtime.JSX.Element;
344
+ declare function QrCode({ value, size, className, tone }: QrCodeProps): react_jsx_runtime.JSX.Element;
339
345
 
340
346
  interface BottomNavItem<TValue extends string = string> {
341
347
  id: TValue;
@@ -930,6 +936,9 @@ interface WithdrawRouteOption<TAccount extends string = string> {
930
936
  accountIcon?: ReactNode;
931
937
  /** Optional pre-formatted balance label (e.g. "1.23 BTC available") shown on the card. */
932
938
  balanceLabel?: string;
939
+ /** Optional protocol-tinted classes applied when the card is selected
940
+ * (e.g. "bg-network-spark/12"). Falls back to the brand primary tint. */
941
+ accentClassName?: string;
933
942
  }
934
943
  interface WithdrawRouteSummary {
935
944
  method: string;
@@ -1465,8 +1474,12 @@ interface BtcUnifiedReceiveProps {
1465
1474
  * button leads to a half-initialised state).
1466
1475
  */
1467
1476
  showRegenerate?: boolean;
1477
+ /** Optional request description/memo, edited alongside the amount in the
1478
+ * Edit modal. When omitted the description field is hidden. */
1479
+ description?: string;
1480
+ onDescriptionChange?: (value: string) => void;
1468
1481
  }
1469
- declare function BtcUnifiedReceive({ btcSelectedAccount, accountReceiveResult, invoiceStatus, isInvoicePending, isInvoicePaid, isInvoiceFailedOrExpired, amount, handleAmountChange, loading, copied, copyToClipboard, setAddress, setAmount, setInvoiceStatus, setAccountReceiveResult, handleDone, showRegenerate, }: BtcUnifiedReceiveProps): react_jsx_runtime.JSX.Element;
1482
+ declare function BtcUnifiedReceive({ accountReceiveResult, invoiceStatus, isInvoicePending, isInvoicePaid, isInvoiceFailedOrExpired, amount, handleAmountChange, loading, copied, copyToClipboard, setAddress, setAmount, setInvoiceStatus, setAccountReceiveResult, showRegenerate, description, onDescriptionChange, }: BtcUnifiedReceiveProps): react_jsx_runtime.JSX.Element;
1470
1483
 
1471
1484
  interface DepositGeneratedAsset {
1472
1485
  ticker?: string;
package/dist/web/index.js CHANGED
@@ -2067,7 +2067,7 @@ var LOGO_PATHS = /* @__PURE__ */ jsxs13(Fragment, { children: [
2067
2067
  ),
2068
2068
  /* @__PURE__ */ jsx26("path", { d: "M274.479 0.104797H411.786L274.533 137.411H137.226L274.479 0.104797Z", fill: "#17B581" })
2069
2069
  ] });
2070
- function QrCode({ value, size = 160, className }) {
2070
+ function QrCode({ value, size = 160, className, tone = "onLight" }) {
2071
2071
  const svgContent = useMemo(() => {
2072
2072
  if (!value) return null;
2073
2073
  const matrix = encodeQR(value, "raw", { ecc: "medium", border: 0 });
@@ -2075,8 +2075,8 @@ function QrCode({ value, size = 160, className }) {
2075
2075
  const moduleSize = 10;
2076
2076
  const quietZone = moduleSize * 2;
2077
2077
  const svgSize = n * moduleSize + quietZone * 2;
2078
- const fg = "#040404";
2079
- const bg = "#ffffff";
2078
+ const fg = tone === "onDark" ? "#ffffff" : "#040404";
2079
+ const bg = tone === "onDark" ? "transparent" : "#ffffff";
2080
2080
  const logoModules = Math.ceil(n * 0.2);
2081
2081
  const logoZoneSize = logoModules % 2 === 0 ? logoModules + 1 : logoModules;
2082
2082
  const elements = [];
@@ -2130,7 +2130,7 @@ function QrCode({ value, size = 160, className }) {
2130
2130
  children: elements
2131
2131
  }
2132
2132
  );
2133
- }, [value]);
2133
+ }, [value, tone]);
2134
2134
  return /* @__PURE__ */ jsx26("div", { className, style: { width: size, height: size }, children: svgContent });
2135
2135
  }
2136
2136
 
@@ -4498,16 +4498,17 @@ function WithdrawDestinationInput({
4498
4498
  onChange: (event) => setDestination(event.target.value)
4499
4499
  }
4500
4500
  ),
4501
- /* @__PURE__ */ jsxs32("div", { className: "absolute right-4 top-1/2 flex -translate-y-1/2 items-center gap-2", children: [
4501
+ /* @__PURE__ */ jsxs32("div", { className: "absolute right-3 top-1/2 flex -translate-y-1/2 items-center gap-1", children: [
4502
4502
  destination && /* @__PURE__ */ jsx45(
4503
4503
  "button",
4504
4504
  {
4505
4505
  type: "button",
4506
+ "aria-label": "Clear",
4506
4507
  onClick: () => {
4507
4508
  setDestination("");
4508
4509
  handleReset();
4509
4510
  },
4510
- className: "text-xs text-muted-foreground transition-colors hover:text-white",
4511
+ className: "rounded-lg p-2 text-muted-foreground transition-colors hover:text-white",
4511
4512
  children: /* @__PURE__ */ jsx45("span", { className: "material-symbols-outlined text-icon-md", children: "close" })
4512
4513
  }
4513
4514
  ),
@@ -4515,9 +4516,10 @@ function WithdrawDestinationInput({
4515
4516
  "button",
4516
4517
  {
4517
4518
  type: "button",
4519
+ "aria-label": "Paste",
4518
4520
  onClick: handlePaste,
4519
- className: "rounded-lg bg-white/10 px-2.5 py-1 text-xs font-medium text-primary transition-colors hover:bg-white/20",
4520
- children: "Paste"
4521
+ className: "rounded-lg bg-white/5 p-2 text-muted-foreground transition-colors hover:text-primary",
4522
+ children: /* @__PURE__ */ jsx45("span", { className: "material-symbols-outlined text-icon-md", children: "content_paste" })
4521
4523
  }
4522
4524
  )
4523
4525
  ] })
@@ -4630,7 +4632,7 @@ function WithdrawAmountInput({
4630
4632
  const value = parseInt(event.target.value, 10);
4631
4633
  if (!Number.isNaN(value)) setWitnessAmountSat(value);
4632
4634
  },
4633
- className: "w-full rounded-xl border bg-card px-4 py-3 text-sm text-white transition-colors focus:border-primary/50 focus:outline-none"
4635
+ className: "w-full rounded-xl bg-card px-4 py-3 text-sm text-white shadow-inner transition-all focus:outline focus:outline-2 focus:outline-primary/50"
4634
4636
  }
4635
4637
  ),
4636
4638
  /* @__PURE__ */ jsx46("p", { className: "ml-1 text-xs text-muted-foreground", children: "Bitcoin amount sent to create the witness UTXO for the recipient." })
@@ -4642,7 +4644,7 @@ function WithdrawAmountInput({
4642
4644
  {
4643
4645
  type: "button",
4644
4646
  onClick: () => setFeeRate(rate),
4645
- className: `group relative overflow-hidden rounded-[16px] border px-3 py-3 shadow-sm transition-all active:scale-[0.98] ${feeRate === rate ? "border-primary/40 bg-primary/10" : "border-border bg-card/40 backdrop-blur-xl hover:border-primary/40"}`,
4647
+ className: `group relative overflow-hidden rounded-[16px] px-3 py-3 shadow-sm transition-all active:scale-[0.98] ${feeRate === rate ? "bg-primary/10" : "bg-card/40 backdrop-blur-xl hover:bg-card/60"}`,
4646
4648
  children: [
4647
4649
  /* @__PURE__ */ jsx46(
4648
4650
  "div",
@@ -4674,7 +4676,7 @@ function WithdrawAmountInput({
4674
4676
  rate
4675
4677
  )) })
4676
4678
  ] }),
4677
- addressType === "rgb" && /* @__PURE__ */ jsxs33("div", { className: "flex items-center justify-between rounded-xl border bg-card p-3", children: [
4679
+ addressType === "rgb" && /* @__PURE__ */ jsxs33("div", { className: "flex items-center justify-between rounded-xl bg-card p-3", children: [
4678
4680
  /* @__PURE__ */ jsxs33("div", { children: [
4679
4681
  /* @__PURE__ */ jsx46("p", { className: "text-sm font-medium text-white", children: "Gift / Donation" }),
4680
4682
  /* @__PURE__ */ jsx46("p", { className: "text-xs text-muted-foreground", children: "Skip amount checks for this transfer" })
@@ -4800,21 +4802,23 @@ function RouteChoiceCard({
4800
4802
  onClick,
4801
4803
  displayOnly
4802
4804
  }) {
4803
- const { disabled = false, disabledReason, accountIcon, balanceLabel } = route;
4804
- if (displayOnly) {
4805
- return /* @__PURE__ */ jsx48("div", { className: "rounded-2xl bg-card/50 px-4 py-3.5", children: /* @__PURE__ */ jsxs35("div", { className: "flex items-center justify-between gap-3", children: [
4806
- /* @__PURE__ */ jsxs35("div", { className: "flex min-w-0 items-center gap-3", children: [
4807
- accountIcon && /* @__PURE__ */ jsx48("div", { className: "shrink-0", children: accountIcon }),
4808
- /* @__PURE__ */ jsxs35("div", { className: "min-w-0", children: [
4809
- /* @__PURE__ */ jsx48("span", { className: "text-sm font-semibold text-white", children: route.accountTitle }),
4810
- /* @__PURE__ */ jsx48("p", { className: "mt-0.5 text-xs text-white/45", children: route.methodLabel })
4811
- ] })
4812
- ] }),
4813
- /* @__PURE__ */ jsxs35("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
4814
- /* @__PURE__ */ jsx48("span", { className: "text-xxs font-bold uppercase tracking-wider text-white/35", children: route.feeHint }),
4815
- balanceLabel && /* @__PURE__ */ jsx48("span", { className: "font-mono text-xxs text-white/50", children: balanceLabel })
4805
+ const { disabled = false, disabledReason, accountIcon, balanceLabel, accentClassName } = route;
4806
+ const body = /* @__PURE__ */ jsxs35("div", { className: "flex items-start justify-between gap-3", children: [
4807
+ /* @__PURE__ */ jsxs35("div", { className: "flex min-w-0 items-start gap-3", children: [
4808
+ accountIcon && /* @__PURE__ */ jsx48("div", { className: "mt-0.5 shrink-0", children: accountIcon }),
4809
+ /* @__PURE__ */ jsxs35("div", { className: "min-w-0", children: [
4810
+ /* @__PURE__ */ jsxs35("div", { className: "flex flex-wrap items-center gap-2", children: [
4811
+ /* @__PURE__ */ jsx48("span", { className: "text-sm font-bold text-white", children: route.accountTitle }),
4812
+ recommended && !disabled && /* @__PURE__ */ jsx48("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-xxs font-bold uppercase tracking-wider text-primary", children: "Recommended" }),
4813
+ disabled && /* @__PURE__ */ jsx48("span", { className: "rounded-full bg-danger/10 px-2 py-0.5 text-xxs font-bold uppercase tracking-wider text-danger", children: "Insufficient" })
4814
+ ] }),
4815
+ balanceLabel && /* @__PURE__ */ jsx48("p", { className: "mt-0.5 font-mono text-xs text-white/55", children: balanceLabel })
4816
4816
  ] })
4817
- ] }) });
4817
+ ] }),
4818
+ /* @__PURE__ */ jsx48("span", { className: "shrink-0 text-xxs font-bold uppercase tracking-wider text-white/40", children: route.feeHint })
4819
+ ] });
4820
+ if (displayOnly) {
4821
+ return /* @__PURE__ */ jsx48("div", { className: "rounded-2xl bg-card/50 px-4 py-3.5", children: body });
4818
4822
  }
4819
4823
  return /* @__PURE__ */ jsxs35(
4820
4824
  "button",
@@ -4826,28 +4830,11 @@ function RouteChoiceCard({
4826
4830
  "aria-disabled": disabled,
4827
4831
  title: disabled ? disabledReason : void 0,
4828
4832
  className: cn(
4829
- "w-full rounded-2xl border p-4 text-left transition-all",
4830
- disabled ? "cursor-not-allowed border-danger/15 bg-danger/5 opacity-60" : selected ? "border-primary/30 bg-primary/10" : "border-border bg-white/4 hover:border-white/20 hover:bg-white/6"
4833
+ "w-full rounded-2xl p-4 text-left transition-all",
4834
+ disabled ? "cursor-not-allowed bg-danger/5 opacity-60" : selected ? accentClassName ?? "bg-primary/10" : "bg-white/4 hover:bg-white/6"
4831
4835
  ),
4832
4836
  children: [
4833
- /* @__PURE__ */ jsxs35("div", { className: "flex items-start justify-between gap-3", children: [
4834
- /* @__PURE__ */ jsxs35("div", { className: "flex min-w-0 items-start gap-3", children: [
4835
- accountIcon && /* @__PURE__ */ jsx48("div", { className: "mt-0.5 shrink-0", children: accountIcon }),
4836
- /* @__PURE__ */ jsxs35("div", { className: "min-w-0", children: [
4837
- /* @__PURE__ */ jsxs35("div", { className: "flex flex-wrap items-center gap-2", children: [
4838
- /* @__PURE__ */ jsx48("span", { className: "text-sm font-bold text-white", children: route.accountTitle }),
4839
- recommended && !disabled && /* @__PURE__ */ jsx48("span", { className: "rounded-full border border-primary/20 bg-primary/10 px-2 py-0.5 text-xxs font-bold uppercase tracking-wider text-primary", children: "Recommended" }),
4840
- disabled && /* @__PURE__ */ jsx48("span", { className: "rounded-full border border-danger/20 bg-danger/10 px-2 py-0.5 text-xxs font-bold uppercase tracking-wider text-danger", children: "Insufficient" })
4841
- ] }),
4842
- /* @__PURE__ */ jsx48("p", { className: "mt-1 text-xs text-white/45", children: route.methodLabel })
4843
- ] })
4844
- ] }),
4845
- /* @__PURE__ */ jsxs35("div", { className: "flex shrink-0 flex-col items-end gap-1", children: [
4846
- /* @__PURE__ */ jsx48("span", { className: "text-xxs font-bold uppercase tracking-wider text-white/35", children: route.feeHint }),
4847
- balanceLabel && /* @__PURE__ */ jsx48("span", { className: "font-mono text-xxs text-white/50", children: balanceLabel })
4848
- ] })
4849
- ] }),
4850
- /* @__PURE__ */ jsx48("p", { className: "mt-3 text-xs leading-relaxed text-muted-foreground", children: route.summary }),
4837
+ body,
4851
4838
  disabled && disabledReason && /* @__PURE__ */ jsx48("p", { className: "mt-2 text-xxs leading-relaxed text-danger/80", children: disabledReason })
4852
4839
  ]
4853
4840
  }
@@ -7014,7 +7001,7 @@ var NETWORK_CONFIG = {
7014
7001
  border: "border-network-bitcoin/40",
7015
7002
  qrBorder: "border-network-bitcoin/30",
7016
7003
  qrGlow: qrGlowStyle(colors.network.bitcoin),
7017
- icon: /* @__PURE__ */ jsx73("span", { className: "material-symbols-outlined text-icon-xs leading-none", children: "link" })
7004
+ icon: /* @__PURE__ */ jsx73("span", { className: "material-symbols-outlined text-icon-xs leading-none", children: "currency_bitcoin" })
7018
7005
  },
7019
7006
  lightning: {
7020
7007
  label: "Lightning",
@@ -7426,13 +7413,13 @@ function DepositNetworkDefaultModal({
7426
7413
  }
7427
7414
 
7428
7415
  // src/web/components/btc-unified-receive.tsx
7416
+ import { useState as useState15 } from "react";
7429
7417
  import { jsx as jsx76, jsxs as jsxs62 } from "react/jsx-runtime";
7430
7418
  function formatSatsForRow(value) {
7431
7419
  if (!value || value <= 0 || !Number.isFinite(value)) return null;
7432
7420
  return `${value.toLocaleString("en-US")} sats`;
7433
7421
  }
7434
7422
  function BtcUnifiedReceive({
7435
- btcSelectedAccount,
7436
7423
  accountReceiveResult,
7437
7424
  invoiceStatus,
7438
7425
  isInvoicePending,
@@ -7447,66 +7434,56 @@ function BtcUnifiedReceive({
7447
7434
  setAmount,
7448
7435
  setInvoiceStatus,
7449
7436
  setAccountReceiveResult,
7450
- handleDone,
7451
- showRegenerate = true
7437
+ showRegenerate = true,
7438
+ description,
7439
+ onDescriptionChange
7452
7440
  }) {
7453
- const accountNetwork = btcSelectedAccount === "SPARK" ? "spark" : btcSelectedAccount === "ARKADE" ? "arkade" : "onchain";
7454
- const qrNetwork = NETWORK_CONFIG[accountNetwork];
7441
+ const [showEdit, setShowEdit] = useState15(false);
7442
+ const isQrCopied = copied === accountReceiveResult.qrValue;
7443
+ const handleNewAddress = () => {
7444
+ setAddress("");
7445
+ setAmount("");
7446
+ setInvoiceStatus(null);
7447
+ setAccountReceiveResult(null);
7448
+ };
7455
7449
  return /* @__PURE__ */ jsxs62("div", { className: "space-y-3 animate-in fade-in zoom-in-95 duration-300", children: [
7456
- /* @__PURE__ */ jsxs62("div", { className: "flex flex-col gap-1.5 rounded-xl border border-white/8 bg-white/3 p-2.5", children: [
7457
- /* @__PURE__ */ jsx76("div", { className: "flex items-center justify-between px-1", children: /* @__PURE__ */ jsx76("label", { className: "text-xxs font-bold uppercase tracking-widest text-white/40", children: "Amount (optional)" }) }),
7458
- /* @__PURE__ */ jsx76(
7459
- "input",
7460
- {
7461
- type: "text",
7462
- value: amount,
7463
- onChange: handleAmountChange,
7464
- placeholder: "Any amount",
7465
- className: "w-full rounded-lg border bg-white/5 px-3 py-1.5 font-mono text-xs font-bold text-white transition-all placeholder:text-white/25 focus:border-primary/40 focus:outline-none",
7466
- inputMode: "decimal"
7467
- }
7468
- ),
7469
- amount && loading && /* @__PURE__ */ jsxs62("p", { className: "flex items-center gap-1 text-xxs text-warning/70", children: [
7470
- /* @__PURE__ */ jsx76("span", { className: "material-symbols-outlined animate-spin text-icon-xxs", children: "progress_activity" }),
7471
- "Updating invoice..."
7472
- ] })
7473
- ] }),
7474
7450
  /* @__PURE__ */ jsxs62("div", { className: "flex flex-col items-center gap-3", children: [
7475
- /* @__PURE__ */ jsxs62(
7476
- "div",
7477
- {
7478
- className: cn(
7479
- "relative flex flex-col items-center rounded-2xl border-2 bg-white p-2 transition-all",
7480
- qrNetwork.qrBorder
7481
- ),
7482
- style: qrNetwork.qrGlow,
7483
- children: [
7484
- /* @__PURE__ */ jsx76(QrCode, { value: accountReceiveResult.qrValue, size: 200 }),
7485
- isInvoicePaid && /* @__PURE__ */ jsx76(PaidOverlay, {})
7486
- ]
7487
- }
7488
- ),
7489
- (() => {
7490
- const isQrCopied = copied === accountReceiveResult.qrValue;
7491
- return /* @__PURE__ */ jsxs62(
7492
- "button",
7451
+ /* @__PURE__ */ jsxs62("div", { className: "relative flex flex-col items-center p-2", children: [
7452
+ /* @__PURE__ */ jsx76(QrCode, { value: accountReceiveResult.qrValue, size: 200, tone: "onDark" }),
7453
+ isInvoicePaid && /* @__PURE__ */ jsx76(PaidOverlay, {})
7454
+ ] }),
7455
+ /* @__PURE__ */ jsxs62("div", { className: "flex items-center justify-center gap-2.5", children: [
7456
+ /* @__PURE__ */ jsx76(
7457
+ Button,
7493
7458
  {
7494
- type: "button",
7495
- className: cn(
7496
- "flex items-center gap-1 rounded-full border px-2.5 py-1 text-xxs font-bold uppercase tracking-widest transition-all",
7497
- isQrCopied ? "border-primary/30 bg-primary/10 text-primary" : "border-border bg-white/5 text-muted-foreground hover:border-white/20 hover:bg-accent hover:text-white"
7498
- ),
7499
- onClick: (event) => {
7500
- event.stopPropagation();
7501
- void copyToClipboard(accountReceiveResult.qrValue);
7502
- },
7503
- children: [
7504
- /* @__PURE__ */ jsx76(Icon, { name: isQrCopied ? "check" : "content_copy", size: "xs" }),
7505
- isQrCopied ? "Copied" : `Copy ${accountReceiveResult.qrLabel}`
7506
- ]
7459
+ variant: "surface",
7460
+ size: "icon-xl",
7461
+ "aria-label": `Copy ${accountReceiveResult.qrLabel}`,
7462
+ onClick: () => void copyToClipboard(accountReceiveResult.qrValue),
7463
+ children: /* @__PURE__ */ jsx76(Icon, { name: isQrCopied ? "check" : "content_copy", size: "lg" })
7507
7464
  }
7508
- );
7509
- })()
7465
+ ),
7466
+ showRegenerate && /* @__PURE__ */ jsx76(
7467
+ Button,
7468
+ {
7469
+ variant: "surface",
7470
+ size: "icon-xl",
7471
+ "aria-label": "New address",
7472
+ onClick: handleNewAddress,
7473
+ children: /* @__PURE__ */ jsx76(Icon, { name: "refresh", size: "lg" })
7474
+ }
7475
+ ),
7476
+ /* @__PURE__ */ jsx76(
7477
+ Button,
7478
+ {
7479
+ variant: "surface",
7480
+ size: "icon-xl",
7481
+ "aria-label": "Edit amount and description",
7482
+ onClick: () => setShowEdit(true),
7483
+ children: /* @__PURE__ */ jsx76(Icon, { name: "edit", size: "lg" })
7484
+ }
7485
+ )
7486
+ ] })
7510
7487
  ] }),
7511
7488
  invoiceStatus && /* @__PURE__ */ jsx76(
7512
7489
  InvoiceStatusBanner,
@@ -7525,9 +7502,8 @@ function BtcUnifiedReceive({
7525
7502
  "div",
7526
7503
  {
7527
7504
  className: cn(
7528
- "group flex cursor-pointer items-center gap-2 rounded-xl border bg-white/3 px-2.5 py-1.5",
7529
- "transition-all hover:bg-white/6 active:scale-[0.98]",
7530
- network.border
7505
+ "group flex cursor-pointer items-center gap-2 rounded-xl bg-white/3 px-2.5 py-1.5",
7506
+ "transition-all hover:bg-white/6 active:scale-[0.98]"
7531
7507
  ),
7532
7508
  style: { borderLeftWidth: 3, borderLeftColor: network.color },
7533
7509
  onClick: () => void copyToClipboard(address.value),
@@ -7551,36 +7527,48 @@ function BtcUnifiedReceive({
7551
7527
  })
7552
7528
  ] }),
7553
7529
  /* @__PURE__ */ jsx76(
7554
- NetworkInfoDisclosure,
7530
+ BottomSheet,
7555
7531
  {
7556
- networks: Array.from(
7557
- new Set(accountReceiveResult.addresses.map((address) => address.network))
7558
- )
7532
+ open: showEdit,
7533
+ title: "Edit request",
7534
+ icon: /* @__PURE__ */ jsx76(Icon, { name: "edit", size: "md" }),
7535
+ onClose: () => setShowEdit(false),
7536
+ children: /* @__PURE__ */ jsxs62("div", { className: "space-y-4", children: [
7537
+ /* @__PURE__ */ jsxs62("div", { className: "space-y-1.5", children: [
7538
+ /* @__PURE__ */ jsx76("label", { className: "text-xxs font-bold uppercase tracking-widest text-white/40", children: "Amount (optional)" }),
7539
+ /* @__PURE__ */ jsx76(
7540
+ "input",
7541
+ {
7542
+ type: "text",
7543
+ value: amount,
7544
+ onChange: handleAmountChange,
7545
+ placeholder: "Any amount",
7546
+ className: "w-full rounded-xl bg-white/5 px-3 py-2.5 font-mono text-sm font-bold text-white shadow-inner transition-all placeholder:text-white/25 focus:outline focus:outline-2 focus:outline-primary/40",
7547
+ inputMode: "decimal"
7548
+ }
7549
+ ),
7550
+ amount && loading && /* @__PURE__ */ jsxs62("p", { className: "flex items-center gap-1 text-xxs text-warning/70", children: [
7551
+ /* @__PURE__ */ jsx76("span", { className: "material-symbols-outlined animate-spin text-icon-xxs", children: "progress_activity" }),
7552
+ "Updating invoice..."
7553
+ ] })
7554
+ ] }),
7555
+ onDescriptionChange && /* @__PURE__ */ jsxs62("div", { className: "space-y-1.5", children: [
7556
+ /* @__PURE__ */ jsx76("label", { className: "text-xxs font-bold uppercase tracking-widest text-white/40", children: "Description (optional)" }),
7557
+ /* @__PURE__ */ jsx76(
7558
+ "input",
7559
+ {
7560
+ type: "text",
7561
+ value: description ?? "",
7562
+ onChange: (event) => onDescriptionChange(event.target.value),
7563
+ placeholder: "What's this for?",
7564
+ className: "w-full rounded-xl bg-white/5 px-3 py-2.5 text-sm text-white shadow-inner transition-all placeholder:text-white/25 focus:outline focus:outline-2 focus:outline-primary/40"
7565
+ }
7566
+ )
7567
+ ] }),
7568
+ /* @__PURE__ */ jsx76(Button, { variant: "cta", className: "w-full", onClick: () => setShowEdit(false), children: "Done" })
7569
+ ] })
7559
7570
  }
7560
- ),
7561
- /* @__PURE__ */ jsxs62("div", { className: "flex gap-2.5 pt-1", children: [
7562
- showRegenerate && /* @__PURE__ */ jsxs62(
7563
- "button",
7564
- {
7565
- type: "button",
7566
- onClick: () => {
7567
- setAddress("");
7568
- setAmount("");
7569
- setInvoiceStatus(null);
7570
- setAccountReceiveResult(null);
7571
- },
7572
- className: "flex flex-1 items-center justify-center gap-1.5 rounded-xl border py-3 text-xs font-bold text-muted-foreground transition-all hover:border-border hover:bg-accent hover:text-white active:scale-[0.98]",
7573
- children: [
7574
- /* @__PURE__ */ jsx76("span", { className: "material-symbols-outlined text-icon-sm", children: "refresh" }),
7575
- "New Address"
7576
- ]
7577
- }
7578
- ),
7579
- /* @__PURE__ */ jsxs62(Button, { variant: "cta", onClick: handleDone, className: showRegenerate ? void 0 : "flex-1", children: [
7580
- /* @__PURE__ */ jsx76("span", { className: "material-symbols-outlined text-icon-sm", children: "check" }),
7581
- "Done"
7582
- ] })
7583
- ] })
7571
+ )
7584
7572
  ] });
7585
7573
  }
7586
7574
 
@@ -8002,7 +7990,7 @@ function DepositPreGeneration({
8002
7990
  }
8003
7991
 
8004
7992
  // src/web/components/deposit-asset-selection.tsx
8005
- import { useEffect as useEffect10, useState as useState15 } from "react";
7993
+ import { useEffect as useEffect10, useState as useState16 } from "react";
8006
7994
  import { jsx as jsx79, jsxs as jsxs65 } from "react/jsx-runtime";
8007
7995
  var ADD_ASSET_SUBTITLE = {
8008
7996
  RGB: "RGB asset on Bitcoin",
@@ -8045,8 +8033,8 @@ function DepositAssetSelection({
8045
8033
  const ownedAssetsCount = ownedAssets.length;
8046
8034
  const noResults = filteredAssets.length === 0 && !!searchQuery;
8047
8035
  const isSearching = !!searchQuery;
8048
- const [assetsExpanded, setAssetsExpanded] = useState15(false);
8049
- const [showAddAssetModal, setShowAddAssetModal] = useState15(false);
8036
+ const [assetsExpanded, setAssetsExpanded] = useState16(false);
8037
+ const [showAddAssetModal, setShowAddAssetModal] = useState16(false);
8050
8038
  useEffect10(() => {
8051
8039
  if (isSearching) setAssetsExpanded(true);
8052
8040
  }, [isSearching]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaleido-ui",
3
- "version": "0.1.71",
3
+ "version": "0.1.73",
4
4
  "description": "KaleidoSwap shared UI library — design tokens, web components (Tailwind + Radix), and React Native components extending WDK UI Kit",
5
5
  "license": "MIT",
6
6
  "type": "module",