@medialane/ui 0.174.0 → 0.176.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 (93) hide show
  1. package/dist/components/account/account-section.cjs +50 -0
  2. package/dist/components/account/account-section.cjs.map +1 -0
  3. package/dist/components/account/account-section.d.cts +14 -0
  4. package/dist/components/account/account-section.d.ts +14 -0
  5. package/dist/components/account/account-section.js +26 -0
  6. package/dist/components/account/account-section.js.map +1 -0
  7. package/dist/components/account/account.test.cjs +86 -0
  8. package/dist/components/account/account.test.cjs.map +1 -0
  9. package/dist/components/account/account.test.d.cts +2 -0
  10. package/dist/components/account/account.test.d.ts +2 -0
  11. package/dist/components/account/account.test.js +85 -0
  12. package/dist/components/account/account.test.js.map +1 -0
  13. package/dist/components/account/add-guardian-dialog.cjs +90 -0
  14. package/dist/components/account/add-guardian-dialog.cjs.map +1 -0
  15. package/dist/components/account/add-guardian-dialog.d.cts +14 -0
  16. package/dist/components/account/add-guardian-dialog.d.ts +14 -0
  17. package/dist/components/account/add-guardian-dialog.js +66 -0
  18. package/dist/components/account/add-guardian-dialog.js.map +1 -0
  19. package/dist/components/account/device-approval-dialog.cjs +120 -0
  20. package/dist/components/account/device-approval-dialog.cjs.map +1 -0
  21. package/dist/components/account/device-approval-dialog.d.cts +14 -0
  22. package/dist/components/account/device-approval-dialog.d.ts +14 -0
  23. package/dist/components/account/device-approval-dialog.js +96 -0
  24. package/dist/components/account/device-approval-dialog.js.map +1 -0
  25. package/dist/components/account/devices-section.cjs +117 -0
  26. package/dist/components/account/devices-section.cjs.map +1 -0
  27. package/dist/components/account/devices-section.d.cts +12 -0
  28. package/dist/components/account/devices-section.d.ts +12 -0
  29. package/dist/components/account/devices-section.js +93 -0
  30. package/dist/components/account/devices-section.js.map +1 -0
  31. package/dist/components/account/email-code-entry.cjs +85 -0
  32. package/dist/components/account/email-code-entry.cjs.map +1 -0
  33. package/dist/components/account/email-code-entry.d.cts +11 -0
  34. package/dist/components/account/email-code-entry.d.ts +11 -0
  35. package/dist/components/account/email-code-entry.js +61 -0
  36. package/dist/components/account/email-code-entry.js.map +1 -0
  37. package/dist/components/account/guardian-recovery-section.cjs +161 -0
  38. package/dist/components/account/guardian-recovery-section.cjs.map +1 -0
  39. package/dist/components/account/guardian-recovery-section.d.cts +14 -0
  40. package/dist/components/account/guardian-recovery-section.d.ts +14 -0
  41. package/dist/components/account/guardian-recovery-section.js +130 -0
  42. package/dist/components/account/guardian-recovery-section.js.map +1 -0
  43. package/dist/components/account/input-otp.cjs +89 -0
  44. package/dist/components/account/input-otp.cjs.map +1 -0
  45. package/dist/components/account/input-otp.d.cts +37 -0
  46. package/dist/components/account/input-otp.d.ts +37 -0
  47. package/dist/components/account/input-otp.js +52 -0
  48. package/dist/components/account/input-otp.js.map +1 -0
  49. package/dist/components/account/wallet-types.cjs +17 -0
  50. package/dist/components/account/wallet-types.cjs.map +1 -0
  51. package/dist/components/account/wallet-types.d.cts +7 -0
  52. package/dist/components/account/wallet-types.d.ts +7 -0
  53. package/dist/components/account/wallet-types.js +1 -0
  54. package/dist/components/account/wallet-types.js.map +1 -0
  55. package/dist/components/button.d.cts +1 -1
  56. package/dist/components/button.d.ts +1 -1
  57. package/dist/index.cjs +56 -0
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.d.cts +15 -1
  60. package/dist/index.d.ts +15 -1
  61. package/dist/index.js +40 -0
  62. package/dist/index.js.map +1 -1
  63. package/dist/utils/app-wallet.cjs +84 -0
  64. package/dist/utils/app-wallet.cjs.map +1 -0
  65. package/dist/utils/app-wallet.d.cts +26 -0
  66. package/dist/utils/app-wallet.d.ts +26 -0
  67. package/dist/utils/app-wallet.js +65 -0
  68. package/dist/utils/app-wallet.js.map +1 -0
  69. package/dist/utils/email-code.cjs +58 -0
  70. package/dist/utils/email-code.cjs.map +1 -0
  71. package/dist/utils/email-code.d.cts +32 -0
  72. package/dist/utils/email-code.d.ts +32 -0
  73. package/dist/utils/email-code.js +30 -0
  74. package/dist/utils/email-code.js.map +1 -0
  75. package/dist/utils/passkey-support.cjs +37 -0
  76. package/dist/utils/passkey-support.cjs.map +1 -0
  77. package/dist/utils/passkey-support.d.cts +7 -0
  78. package/dist/utils/passkey-support.d.ts +7 -0
  79. package/dist/utils/passkey-support.js +13 -0
  80. package/dist/utils/passkey-support.js.map +1 -0
  81. package/dist/utils/use-email-code.cjs +75 -0
  82. package/dist/utils/use-email-code.cjs.map +1 -0
  83. package/dist/utils/use-email-code.d.cts +20 -0
  84. package/dist/utils/use-email-code.d.ts +20 -0
  85. package/dist/utils/use-email-code.js +51 -0
  86. package/dist/utils/use-email-code.js.map +1 -0
  87. package/dist/utils/wallet-failure.cjs +63 -0
  88. package/dist/utils/wallet-failure.cjs.map +1 -0
  89. package/dist/utils/wallet-failure.d.cts +12 -0
  90. package/dist/utils/wallet-failure.d.ts +12 -0
  91. package/dist/utils/wallet-failure.js +38 -0
  92. package/dist/utils/wallet-failure.js.map +1 -0
  93. package/package.json +3 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/account/email-code-entry.tsx"],"sourcesContent":["\"use client\";\n\nimport { Loader2, AlertCircle } from \"lucide-react\";\nimport { Button } from \"../button.js\";\nimport { Alert, AlertDescription } from \"../alert.js\";\nimport { InputOTP, InputOTPGroup, InputOTPSlot } from \"./input-otp.js\";\nimport { canResendCode, canVerifyCode } from \"../../utils/email-code.js\";\nimport type { EmailCode } from \"../../utils/use-email-code.js\";\n\nexport interface EmailCodeEntryProps {\n emailCode: EmailCode;\n onVerify: (code?: string) => void;\n}\n\nexport function EmailCodeEntry({ emailCode, onVerify }: EmailCodeEntryProps) {\n const { state, setCode, send } = emailCode;\n const verifying = state.status === \"verifying\";\n\n return (\n <div className=\"flex w-full flex-col items-center gap-4\">\n {state.error ? (\n <Alert variant=\"destructive\" className=\"w-full\">\n <AlertCircle className=\"h-4 w-4\" />\n <AlertDescription>{state.error}</AlertDescription>\n </Alert>\n ) : null}\n {state.status === \"sending\" ? (\n <div className=\"flex items-center gap-2 py-2.5 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Sending code…\n </div>\n ) : (\n <>\n <InputOTP\n maxLength={6}\n value={state.code}\n onChange={setCode}\n onComplete={(value) => onVerify(value)}\n disabled={verifying}\n autoFocus\n >\n <InputOTPGroup>\n {[0, 1, 2, 3, 4, 5].map((i) => (\n <InputOTPSlot key={i} index={i} className=\"h-12 w-11 text-lg font-semibold\" />\n ))}\n </InputOTPGroup>\n </InputOTP>\n <Button size=\"lg\" className=\"w-full gap-2\" onClick={() => onVerify()} disabled={!canVerifyCode(state)}>\n {verifying ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : null}\n Verify\n </Button>\n <p className=\"text-center text-xs leading-relaxed text-muted-foreground\">\n Didn&apos;t receive it? Check your spam, or{\" \"}\n {state.cooldown > 0 ? (\n <span>resend in {state.cooldown}s</span>\n ) : (\n <button\n type=\"button\"\n onClick={() => void send()}\n disabled={!canResendCode(state)}\n className=\"underline underline-offset-2 hover:text-foreground disabled:opacity-50\"\n >\n resend the code\n </button>\n )}\n .\n </p>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBQ;AAnBR,0BAAqC;AACrC,oBAAuB;AACvB,mBAAwC;AACxC,uBAAsD;AACtD,wBAA6C;AAQtC,SAAS,eAAe,EAAE,WAAW,SAAS,GAAwB;AAC3E,QAAM,EAAE,OAAO,SAAS,KAAK,IAAI;AACjC,QAAM,YAAY,MAAM,WAAW;AAEnC,SACE,6CAAC,SAAI,WAAU,2CACZ;AAAA,UAAM,QACL,6CAAC,sBAAM,SAAQ,eAAc,WAAU,UACrC;AAAA,kDAAC,mCAAY,WAAU,WAAU;AAAA,MACjC,4CAAC,iCAAkB,gBAAM,OAAM;AAAA,OACjC,IACE;AAAA,IACH,MAAM,WAAW,YAChB,6CAAC,SAAI,WAAU,gEACb;AAAA,kDAAC,+BAAQ,WAAU,wBAAuB;AAAA,MAAE;AAAA,OAE9C,IAEA,4EACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,UACX,OAAO,MAAM;AAAA,UACb,UAAU;AAAA,UACV,YAAY,CAAC,UAAU,SAAS,KAAK;AAAA,UACrC,UAAU;AAAA,UACV,WAAS;AAAA,UAET,sDAAC,kCACE,WAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACvB,4CAAC,iCAAqB,OAAO,GAAG,WAAU,qCAAvB,CAAyD,CAC7E,GACH;AAAA;AAAA,MACF;AAAA,MACA,6CAAC,wBAAO,MAAK,MAAK,WAAU,gBAAe,SAAS,MAAM,SAAS,GAAG,UAAU,KAAC,iCAAc,KAAK,GACjG;AAAA,oBAAY,4CAAC,+BAAQ,WAAU,wBAAuB,IAAK;AAAA,QAAK;AAAA,SAEnE;AAAA,MACA,6CAAC,OAAE,WAAU,6DAA4D;AAAA;AAAA,QAC3B;AAAA,QAC3C,MAAM,WAAW,IAChB,6CAAC,UAAK;AAAA;AAAA,UAAW,MAAM;AAAA,UAAS;AAAA,WAAC,IAEjC;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,KAAK,KAAK;AAAA,YACzB,UAAU,KAAC,iCAAc,KAAK;AAAA,YAC9B,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,QACA;AAAA,SAEJ;AAAA,OACF;AAAA,KAEJ;AAEJ;","names":[]}
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { EmailCode } from '../../utils/use-email-code.cjs';
3
+ import '../../utils/email-code.cjs';
4
+
5
+ interface EmailCodeEntryProps {
6
+ emailCode: EmailCode;
7
+ onVerify: (code?: string) => void;
8
+ }
9
+ declare function EmailCodeEntry({ emailCode, onVerify }: EmailCodeEntryProps): react_jsx_runtime.JSX.Element;
10
+
11
+ export { EmailCodeEntry, type EmailCodeEntryProps };
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { EmailCode } from '../../utils/use-email-code.js';
3
+ import '../../utils/email-code.js';
4
+
5
+ interface EmailCodeEntryProps {
6
+ emailCode: EmailCode;
7
+ onVerify: (code?: string) => void;
8
+ }
9
+ declare function EmailCodeEntry({ emailCode, onVerify }: EmailCodeEntryProps): react_jsx_runtime.JSX.Element;
10
+
11
+ export { EmailCodeEntry, type EmailCodeEntryProps };
@@ -0,0 +1,61 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { Loader2, AlertCircle } from "lucide-react";
4
+ import { Button } from "../button.js";
5
+ import { Alert, AlertDescription } from "../alert.js";
6
+ import { InputOTP, InputOTPGroup, InputOTPSlot } from "./input-otp.js";
7
+ import { canResendCode, canVerifyCode } from "../../utils/email-code.js";
8
+ function EmailCodeEntry({ emailCode, onVerify }) {
9
+ const { state, setCode, send } = emailCode;
10
+ const verifying = state.status === "verifying";
11
+ return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col items-center gap-4", children: [
12
+ state.error ? /* @__PURE__ */ jsxs(Alert, { variant: "destructive", className: "w-full", children: [
13
+ /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
14
+ /* @__PURE__ */ jsx(AlertDescription, { children: state.error })
15
+ ] }) : null,
16
+ state.status === "sending" ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 py-2.5 text-sm text-muted-foreground", children: [
17
+ /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
18
+ "Sending code\u2026"
19
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
20
+ /* @__PURE__ */ jsx(
21
+ InputOTP,
22
+ {
23
+ maxLength: 6,
24
+ value: state.code,
25
+ onChange: setCode,
26
+ onComplete: (value) => onVerify(value),
27
+ disabled: verifying,
28
+ autoFocus: true,
29
+ children: /* @__PURE__ */ jsx(InputOTPGroup, { children: [0, 1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsx(InputOTPSlot, { index: i, className: "h-12 w-11 text-lg font-semibold" }, i)) })
30
+ }
31
+ ),
32
+ /* @__PURE__ */ jsxs(Button, { size: "lg", className: "w-full gap-2", onClick: () => onVerify(), disabled: !canVerifyCode(state), children: [
33
+ verifying ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : null,
34
+ "Verify"
35
+ ] }),
36
+ /* @__PURE__ */ jsxs("p", { className: "text-center text-xs leading-relaxed text-muted-foreground", children: [
37
+ "Didn't receive it? Check your spam, or",
38
+ " ",
39
+ state.cooldown > 0 ? /* @__PURE__ */ jsxs("span", { children: [
40
+ "resend in ",
41
+ state.cooldown,
42
+ "s"
43
+ ] }) : /* @__PURE__ */ jsx(
44
+ "button",
45
+ {
46
+ type: "button",
47
+ onClick: () => void send(),
48
+ disabled: !canResendCode(state),
49
+ className: "underline underline-offset-2 hover:text-foreground disabled:opacity-50",
50
+ children: "resend the code"
51
+ }
52
+ ),
53
+ "."
54
+ ] })
55
+ ] })
56
+ ] });
57
+ }
58
+ export {
59
+ EmailCodeEntry
60
+ };
61
+ //# sourceMappingURL=email-code-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/account/email-code-entry.tsx"],"sourcesContent":["\"use client\";\n\nimport { Loader2, AlertCircle } from \"lucide-react\";\nimport { Button } from \"../button.js\";\nimport { Alert, AlertDescription } from \"../alert.js\";\nimport { InputOTP, InputOTPGroup, InputOTPSlot } from \"./input-otp.js\";\nimport { canResendCode, canVerifyCode } from \"../../utils/email-code.js\";\nimport type { EmailCode } from \"../../utils/use-email-code.js\";\n\nexport interface EmailCodeEntryProps {\n emailCode: EmailCode;\n onVerify: (code?: string) => void;\n}\n\nexport function EmailCodeEntry({ emailCode, onVerify }: EmailCodeEntryProps) {\n const { state, setCode, send } = emailCode;\n const verifying = state.status === \"verifying\";\n\n return (\n <div className=\"flex w-full flex-col items-center gap-4\">\n {state.error ? (\n <Alert variant=\"destructive\" className=\"w-full\">\n <AlertCircle className=\"h-4 w-4\" />\n <AlertDescription>{state.error}</AlertDescription>\n </Alert>\n ) : null}\n {state.status === \"sending\" ? (\n <div className=\"flex items-center gap-2 py-2.5 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n Sending code…\n </div>\n ) : (\n <>\n <InputOTP\n maxLength={6}\n value={state.code}\n onChange={setCode}\n onComplete={(value) => onVerify(value)}\n disabled={verifying}\n autoFocus\n >\n <InputOTPGroup>\n {[0, 1, 2, 3, 4, 5].map((i) => (\n <InputOTPSlot key={i} index={i} className=\"h-12 w-11 text-lg font-semibold\" />\n ))}\n </InputOTPGroup>\n </InputOTP>\n <Button size=\"lg\" className=\"w-full gap-2\" onClick={() => onVerify()} disabled={!canVerifyCode(state)}>\n {verifying ? <Loader2 className=\"h-4 w-4 animate-spin\" /> : null}\n Verify\n </Button>\n <p className=\"text-center text-xs leading-relaxed text-muted-foreground\">\n Didn&apos;t receive it? Check your spam, or{\" \"}\n {state.cooldown > 0 ? (\n <span>resend in {state.cooldown}s</span>\n ) : (\n <button\n type=\"button\"\n onClick={() => void send()}\n disabled={!canResendCode(state)}\n className=\"underline underline-offset-2 hover:text-foreground disabled:opacity-50\"\n >\n resend the code\n </button>\n )}\n .\n </p>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";AAqBQ,SAWA,UAVE,KADF;AAnBR,SAAS,SAAS,mBAAmB;AACrC,SAAS,cAAc;AACvB,SAAS,OAAO,wBAAwB;AACxC,SAAS,UAAU,eAAe,oBAAoB;AACtD,SAAS,eAAe,qBAAqB;AAQtC,SAAS,eAAe,EAAE,WAAW,SAAS,GAAwB;AAC3E,QAAM,EAAE,OAAO,SAAS,KAAK,IAAI;AACjC,QAAM,YAAY,MAAM,WAAW;AAEnC,SACE,qBAAC,SAAI,WAAU,2CACZ;AAAA,UAAM,QACL,qBAAC,SAAM,SAAQ,eAAc,WAAU,UACrC;AAAA,0BAAC,eAAY,WAAU,WAAU;AAAA,MACjC,oBAAC,oBAAkB,gBAAM,OAAM;AAAA,OACjC,IACE;AAAA,IACH,MAAM,WAAW,YAChB,qBAAC,SAAI,WAAU,gEACb;AAAA,0BAAC,WAAQ,WAAU,wBAAuB;AAAA,MAAE;AAAA,OAE9C,IAEA,iCACE;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,UACX,OAAO,MAAM;AAAA,UACb,UAAU;AAAA,UACV,YAAY,CAAC,UAAU,SAAS,KAAK;AAAA,UACrC,UAAU;AAAA,UACV,WAAS;AAAA,UAET,8BAAC,iBACE,WAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,MACvB,oBAAC,gBAAqB,OAAO,GAAG,WAAU,qCAAvB,CAAyD,CAC7E,GACH;AAAA;AAAA,MACF;AAAA,MACA,qBAAC,UAAO,MAAK,MAAK,WAAU,gBAAe,SAAS,MAAM,SAAS,GAAG,UAAU,CAAC,cAAc,KAAK,GACjG;AAAA,oBAAY,oBAAC,WAAQ,WAAU,wBAAuB,IAAK;AAAA,QAAK;AAAA,SAEnE;AAAA,MACA,qBAAC,OAAE,WAAU,6DAA4D;AAAA;AAAA,QAC3B;AAAA,QAC3C,MAAM,WAAW,IAChB,qBAAC,UAAK;AAAA;AAAA,UAAW,MAAM;AAAA,UAAS;AAAA,WAAC,IAEjC;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,MAAM,KAAK,KAAK;AAAA,YACzB,UAAU,CAAC,cAAc,KAAK;AAAA,YAC9B,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,QACA;AAAA,SAEJ;AAAA,OACF;AAAA,KAEJ;AAEJ;","names":[]}
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var guardian_recovery_section_exports = {};
31
+ __export(guardian_recovery_section_exports, {
32
+ GuardianRecoverySection: () => GuardianRecoverySection
33
+ });
34
+ module.exports = __toCommonJS(guardian_recovery_section_exports);
35
+ var import_jsx_runtime = require("react/jsx-runtime");
36
+ var import_react = require("react");
37
+ var import_lucide_react = require("lucide-react");
38
+ var import_starknet = require("@medialane/sdk/starknet");
39
+ var import_link = __toESM(require("../link.js"), 1);
40
+ var import_button = require("../button.js");
41
+ var import_badge = require("../badge.js");
42
+ var import_alert = require("../alert.js");
43
+ var import_describe_error = require("../../utils/describe-error.js");
44
+ var import_add_guardian_dialog = require("./add-guardian-dialog.js");
45
+ const short = (a) => `${a.slice(0, 6)}\u2026${a.slice(-4)}`;
46
+ function GuardianRecoverySection({
47
+ walletAddress,
48
+ wallet,
49
+ loadSealed,
50
+ guardianRecoveryAvailable,
51
+ recoverHref = "/recover"
52
+ }) {
53
+ const [guardians, setGuardians] = (0, import_react.useState)(null);
54
+ const [escape, setEscape] = (0, import_react.useState)(null);
55
+ const [addOpen, setAddOpen] = (0, import_react.useState)(false);
56
+ const [cancelBusy, setCancelBusy] = (0, import_react.useState)(false);
57
+ const [cancelError, setCancelError] = (0, import_react.useState)(null);
58
+ const refresh = (0, import_react.useCallback)(() => {
59
+ wallet.getGuardians(walletAddress).then(setGuardians).catch(() => setGuardians([]));
60
+ wallet.getEscape(walletAddress).then(setEscape).catch(() => setEscape(null));
61
+ }, [walletAddress, wallet]);
62
+ (0, import_react.useEffect)(() => {
63
+ refresh();
64
+ }, [refresh]);
65
+ const handleCancel = async () => {
66
+ const sealed2 = loadSealed();
67
+ if (!sealed2) return;
68
+ setCancelBusy(true);
69
+ setCancelError(null);
70
+ try {
71
+ await wallet.cancelEscape(sealed2);
72
+ refresh();
73
+ } catch (e) {
74
+ setCancelError((0, import_describe_error.describeError)(e, "We couldn't cancel recovery. Please try again.").message);
75
+ } finally {
76
+ setCancelBusy(false);
77
+ }
78
+ };
79
+ const status = guardians ? (0, import_starknet.describeGuardianStatus)(guardians) : null;
80
+ const recoveryAction = escape ? (0, import_starknet.describeRecoveryAction)(escape) : "none";
81
+ const inProgress = escape?.escapeType === "Owner" && recoveryAction !== "none" ? escape : null;
82
+ const sealed = loadSealed();
83
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rounded-2xl border border-border/60 bg-card p-5 sm:p-6 space-y-5", children: [
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start gap-3", children: [
85
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-10 w-10 shrink-0 rounded-full bg-emerald-500/10 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Shield, { className: "h-5 w-5 text-emerald-600 dark:text-emerald-400" }) }),
86
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
87
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-base font-bold text-foreground", children: "Security & Recovery" }),
88
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm text-muted-foreground mt-0.5", children: "A guardian can help you get back into this wallet if you ever lose this device." })
89
+ ] })
90
+ ] }),
91
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "space-y-3", children: [
92
+ inProgress && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_alert.Alert, { variant: "destructive", children: [
93
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ShieldAlert, { className: "h-4 w-4" }),
94
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_alert.AlertDescription, { children: [
95
+ "A guardian has started replacing this wallet's owner key.",
96
+ " ",
97
+ inProgress.status === "Ready" ? "It can complete at any time." : `It can complete on ${new Date(inProgress.readyAt * 1e3).toLocaleString()}.`,
98
+ " ",
99
+ "If this wasn't you, cancel it now.",
100
+ cancelError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-1 text-destructive", children: cancelError }),
101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
102
+ import_button.Button,
103
+ {
104
+ onClick: handleCancel,
105
+ disabled: cancelBusy,
106
+ variant: "destructive",
107
+ size: "sm",
108
+ className: "mt-2 w-full",
109
+ children: [
110
+ cancelBusy ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "mr-1.5 h-3.5 w-3.5 animate-spin" }) : null,
111
+ "Cancel recovery"
112
+ ]
113
+ }
114
+ )
115
+ ] })
116
+ ] }),
117
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between gap-3 rounded-xl border border-border/60 p-4 flex-wrap", children: [
118
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
119
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Guardian recovery" }),
120
+ status === null ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Checking\u2026" }) : status.kind === "none" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: guardianRecoveryAvailable ? "Not set up \u2014 add one from another device you trust." : "Not available yet." }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-muted-foreground mt-0.5", children: [
121
+ "Active: ",
122
+ status.guardian.type,
123
+ " guardian ",
124
+ short(status.guardian.storedValue)
125
+ ] })
126
+ ] }),
127
+ status?.kind === "none" && sealed && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { onClick: () => setAddOpen(true), variant: "outline", size: "sm", disabled: !guardianRecoveryAvailable, children: "Add guardian" }),
128
+ status?.kind === "active" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_badge.Badge, { variant: "outline", className: "border-emerald-500/40 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 text-[10px]", children: "Configured" })
129
+ ] }),
130
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
131
+ import_link.default,
132
+ {
133
+ href: recoverHref,
134
+ className: "flex items-center justify-between gap-3 rounded-xl border border-border/60 p-4 transition-colors hover:bg-foreground/[0.03]",
135
+ children: [
136
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
137
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-medium text-foreground", children: "Recover a wallet" }),
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Lost this device, or acting as someone's guardian?" })
139
+ ] }),
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronRight, { className: "h-4 w-4 text-muted-foreground shrink-0" })
141
+ ]
142
+ }
143
+ )
144
+ ] }),
145
+ sealed && guardianRecoveryAvailable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
146
+ import_add_guardian_dialog.AddGuardianDialog,
147
+ {
148
+ open: addOpen,
149
+ onOpenChange: setAddOpen,
150
+ sealed,
151
+ onAdded: refresh,
152
+ wallet
153
+ }
154
+ )
155
+ ] });
156
+ }
157
+ // Annotate the CommonJS export names for ESM import in node:
158
+ 0 && (module.exports = {
159
+ GuardianRecoverySection
160
+ });
161
+ //# sourceMappingURL=guardian-recovery-section.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/account/guardian-recovery-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Shield, ShieldAlert, ChevronRight, Loader2 } from \"lucide-react\";\nimport {\n describeGuardianStatus,\n describeRecoveryAction,\n type EscapeInfo,\n type GuardianInfo,\n} from \"@medialane/sdk/starknet\";\nimport Link from \"../link.js\";\nimport { Button } from \"../button.js\";\nimport { Badge } from \"../badge.js\";\nimport { Alert, AlertDescription } from \"../alert.js\";\nimport { describeError } from \"../../utils/describe-error.js\";\nimport { AddGuardianDialog } from \"./add-guardian-dialog.js\";\nimport type { GuardianWallet, LoadSealedOwner } from \"./wallet-types.js\";\n\nconst short = (a: string) => `${a.slice(0, 6)}…${a.slice(-4)}`;\n\nexport interface GuardianRecoverySectionProps {\n walletAddress: string;\n wallet: GuardianWallet;\n loadSealed: LoadSealedOwner;\n guardianRecoveryAvailable: boolean;\n recoverHref?: string;\n}\n\nexport function GuardianRecoverySection({\n walletAddress,\n wallet,\n loadSealed,\n guardianRecoveryAvailable,\n recoverHref = \"/recover\",\n}: GuardianRecoverySectionProps) {\n const [guardians, setGuardians] = useState<GuardianInfo[] | null>(null);\n const [escape, setEscape] = useState<EscapeInfo | null>(null);\n const [addOpen, setAddOpen] = useState(false);\n const [cancelBusy, setCancelBusy] = useState(false);\n const [cancelError, setCancelError] = useState<string | null>(null);\n\n const refresh = useCallback(() => {\n wallet.getGuardians(walletAddress).then(setGuardians).catch(() => setGuardians([]));\n wallet.getEscape(walletAddress).then(setEscape).catch(() => setEscape(null));\n }, [walletAddress, wallet]);\n\n useEffect(() => { refresh(); }, [refresh]);\n\n const handleCancel = async () => {\n const sealed = loadSealed();\n if (!sealed) return;\n setCancelBusy(true);\n setCancelError(null);\n try {\n await wallet.cancelEscape(sealed);\n refresh();\n } catch (e) {\n setCancelError(describeError(e, \"We couldn't cancel recovery. Please try again.\").message);\n } finally {\n setCancelBusy(false);\n }\n };\n\n const status = guardians ? describeGuardianStatus(guardians) : null;\n const recoveryAction = escape ? describeRecoveryAction(escape) : \"none\";\n const inProgress = escape?.escapeType === \"Owner\" && recoveryAction !== \"none\" ? escape : null;\n\n const sealed = loadSealed();\n\n return (\n <div className=\"rounded-2xl border border-border/60 bg-card p-5 sm:p-6 space-y-5\">\n <div className=\"flex items-start gap-3\">\n <div className=\"h-10 w-10 shrink-0 rounded-full bg-emerald-500/10 flex items-center justify-center\">\n <Shield className=\"h-5 w-5 text-emerald-600 dark:text-emerald-400\" />\n </div>\n <div>\n <h3 className=\"text-base font-bold text-foreground\">Security &amp; Recovery</h3>\n <p className=\"text-sm text-muted-foreground mt-0.5\">\n A guardian can help you get back into this wallet if you ever lose this device.\n </p>\n </div>\n </div>\n\n <div className=\"space-y-3\">\n {inProgress && (\n <Alert variant=\"destructive\">\n <ShieldAlert className=\"h-4 w-4\" />\n <AlertDescription>\n A guardian has started replacing this wallet&apos;s owner key.{\" \"}\n {inProgress.status === \"Ready\"\n ? \"It can complete at any time.\"\n : `It can complete on ${new Date(inProgress.readyAt * 1000).toLocaleString()}.`}{\" \"}\n If this wasn&apos;t you, cancel it now.\n {cancelError && <p className=\"mt-1 text-destructive\">{cancelError}</p>}\n <Button\n onClick={handleCancel}\n disabled={cancelBusy}\n variant=\"destructive\"\n size=\"sm\"\n className=\"mt-2 w-full\"\n >\n {cancelBusy ? <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" /> : null}\n Cancel recovery\n </Button>\n </AlertDescription>\n </Alert>\n )}\n\n <div className=\"flex items-center justify-between gap-3 rounded-xl border border-border/60 p-4 flex-wrap\">\n <div>\n <p className=\"text-sm font-medium text-foreground\">Guardian recovery</p>\n {status === null ? (\n <p className=\"text-xs text-muted-foreground mt-0.5\">Checking…</p>\n ) : status.kind === \"none\" ? (\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {guardianRecoveryAvailable ? \"Not set up — add one from another device you trust.\" : \"Not available yet.\"}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n Active: {status.guardian.type} guardian {short(status.guardian.storedValue)}\n </p>\n )}\n </div>\n {status?.kind === \"none\" && sealed && (\n <Button onClick={() => setAddOpen(true)} variant=\"outline\" size=\"sm\" disabled={!guardianRecoveryAvailable}>\n Add guardian\n </Button>\n )}\n {status?.kind === \"active\" && (\n <Badge variant=\"outline\" className=\"border-emerald-500/40 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 text-[10px]\">\n Configured\n </Badge>\n )}\n </div>\n\n <Link\n href={recoverHref}\n className=\"flex items-center justify-between gap-3 rounded-xl border border-border/60 p-4 transition-colors hover:bg-foreground/[0.03]\"\n >\n <div>\n <p className=\"text-sm font-medium text-foreground\">Recover a wallet</p>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n Lost this device, or acting as someone&apos;s guardian?\n </p>\n </div>\n <ChevronRight className=\"h-4 w-4 text-muted-foreground shrink-0\" />\n </Link>\n </div>\n\n {sealed && guardianRecoveryAvailable && (\n <AddGuardianDialog\n open={addOpen}\n onOpenChange={setAddOpen}\n sealed={sealed}\n onAdded={refresh}\n wallet={wallet}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["sealed","Link"]}
@@ -0,0 +1,14 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { GuardianWallet, LoadSealedOwner } from './wallet-types.cjs';
3
+ import '@medialane/sdk/starknet';
4
+
5
+ interface GuardianRecoverySectionProps {
6
+ walletAddress: string;
7
+ wallet: GuardianWallet;
8
+ loadSealed: LoadSealedOwner;
9
+ guardianRecoveryAvailable: boolean;
10
+ recoverHref?: string;
11
+ }
12
+ declare function GuardianRecoverySection({ walletAddress, wallet, loadSealed, guardianRecoveryAvailable, recoverHref, }: GuardianRecoverySectionProps): react_jsx_runtime.JSX.Element;
13
+
14
+ export { GuardianRecoverySection, type GuardianRecoverySectionProps };
@@ -0,0 +1,14 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { GuardianWallet, LoadSealedOwner } from './wallet-types.js';
3
+ import '@medialane/sdk/starknet';
4
+
5
+ interface GuardianRecoverySectionProps {
6
+ walletAddress: string;
7
+ wallet: GuardianWallet;
8
+ loadSealed: LoadSealedOwner;
9
+ guardianRecoveryAvailable: boolean;
10
+ recoverHref?: string;
11
+ }
12
+ declare function GuardianRecoverySection({ walletAddress, wallet, loadSealed, guardianRecoveryAvailable, recoverHref, }: GuardianRecoverySectionProps): react_jsx_runtime.JSX.Element;
13
+
14
+ export { GuardianRecoverySection, type GuardianRecoverySectionProps };
@@ -0,0 +1,130 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useState } from "react";
4
+ import { Shield, ShieldAlert, ChevronRight, Loader2 } from "lucide-react";
5
+ import {
6
+ describeGuardianStatus,
7
+ describeRecoveryAction
8
+ } from "@medialane/sdk/starknet";
9
+ import Link from "../link.js";
10
+ import { Button } from "../button.js";
11
+ import { Badge } from "../badge.js";
12
+ import { Alert, AlertDescription } from "../alert.js";
13
+ import { describeError } from "../../utils/describe-error.js";
14
+ import { AddGuardianDialog } from "./add-guardian-dialog.js";
15
+ const short = (a) => `${a.slice(0, 6)}\u2026${a.slice(-4)}`;
16
+ function GuardianRecoverySection({
17
+ walletAddress,
18
+ wallet,
19
+ loadSealed,
20
+ guardianRecoveryAvailable,
21
+ recoverHref = "/recover"
22
+ }) {
23
+ const [guardians, setGuardians] = useState(null);
24
+ const [escape, setEscape] = useState(null);
25
+ const [addOpen, setAddOpen] = useState(false);
26
+ const [cancelBusy, setCancelBusy] = useState(false);
27
+ const [cancelError, setCancelError] = useState(null);
28
+ const refresh = useCallback(() => {
29
+ wallet.getGuardians(walletAddress).then(setGuardians).catch(() => setGuardians([]));
30
+ wallet.getEscape(walletAddress).then(setEscape).catch(() => setEscape(null));
31
+ }, [walletAddress, wallet]);
32
+ useEffect(() => {
33
+ refresh();
34
+ }, [refresh]);
35
+ const handleCancel = async () => {
36
+ const sealed2 = loadSealed();
37
+ if (!sealed2) return;
38
+ setCancelBusy(true);
39
+ setCancelError(null);
40
+ try {
41
+ await wallet.cancelEscape(sealed2);
42
+ refresh();
43
+ } catch (e) {
44
+ setCancelError(describeError(e, "We couldn't cancel recovery. Please try again.").message);
45
+ } finally {
46
+ setCancelBusy(false);
47
+ }
48
+ };
49
+ const status = guardians ? describeGuardianStatus(guardians) : null;
50
+ const recoveryAction = escape ? describeRecoveryAction(escape) : "none";
51
+ const inProgress = escape?.escapeType === "Owner" && recoveryAction !== "none" ? escape : null;
52
+ const sealed = loadSealed();
53
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border/60 bg-card p-5 sm:p-6 space-y-5", children: [
54
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
55
+ /* @__PURE__ */ jsx("div", { className: "h-10 w-10 shrink-0 rounded-full bg-emerald-500/10 flex items-center justify-center", children: /* @__PURE__ */ jsx(Shield, { className: "h-5 w-5 text-emerald-600 dark:text-emerald-400" }) }),
56
+ /* @__PURE__ */ jsxs("div", { children: [
57
+ /* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground", children: "Security & Recovery" }),
58
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-0.5", children: "A guardian can help you get back into this wallet if you ever lose this device." })
59
+ ] })
60
+ ] }),
61
+ /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
62
+ inProgress && /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
63
+ /* @__PURE__ */ jsx(ShieldAlert, { className: "h-4 w-4" }),
64
+ /* @__PURE__ */ jsxs(AlertDescription, { children: [
65
+ "A guardian has started replacing this wallet's owner key.",
66
+ " ",
67
+ inProgress.status === "Ready" ? "It can complete at any time." : `It can complete on ${new Date(inProgress.readyAt * 1e3).toLocaleString()}.`,
68
+ " ",
69
+ "If this wasn't you, cancel it now.",
70
+ cancelError && /* @__PURE__ */ jsx("p", { className: "mt-1 text-destructive", children: cancelError }),
71
+ /* @__PURE__ */ jsxs(
72
+ Button,
73
+ {
74
+ onClick: handleCancel,
75
+ disabled: cancelBusy,
76
+ variant: "destructive",
77
+ size: "sm",
78
+ className: "mt-2 w-full",
79
+ children: [
80
+ cancelBusy ? /* @__PURE__ */ jsx(Loader2, { className: "mr-1.5 h-3.5 w-3.5 animate-spin" }) : null,
81
+ "Cancel recovery"
82
+ ]
83
+ }
84
+ )
85
+ ] })
86
+ ] }),
87
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 rounded-xl border border-border/60 p-4 flex-wrap", children: [
88
+ /* @__PURE__ */ jsxs("div", { children: [
89
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Guardian recovery" }),
90
+ status === null ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Checking\u2026" }) : status.kind === "none" ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: guardianRecoveryAvailable ? "Not set up \u2014 add one from another device you trust." : "Not available yet." }) : /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mt-0.5", children: [
91
+ "Active: ",
92
+ status.guardian.type,
93
+ " guardian ",
94
+ short(status.guardian.storedValue)
95
+ ] })
96
+ ] }),
97
+ status?.kind === "none" && sealed && /* @__PURE__ */ jsx(Button, { onClick: () => setAddOpen(true), variant: "outline", size: "sm", disabled: !guardianRecoveryAvailable, children: "Add guardian" }),
98
+ status?.kind === "active" && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "border-emerald-500/40 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 text-[10px]", children: "Configured" })
99
+ ] }),
100
+ /* @__PURE__ */ jsxs(
101
+ Link,
102
+ {
103
+ href: recoverHref,
104
+ className: "flex items-center justify-between gap-3 rounded-xl border border-border/60 p-4 transition-colors hover:bg-foreground/[0.03]",
105
+ children: [
106
+ /* @__PURE__ */ jsxs("div", { children: [
107
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Recover a wallet" }),
108
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Lost this device, or acting as someone's guardian?" })
109
+ ] }),
110
+ /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground shrink-0" })
111
+ ]
112
+ }
113
+ )
114
+ ] }),
115
+ sealed && guardianRecoveryAvailable && /* @__PURE__ */ jsx(
116
+ AddGuardianDialog,
117
+ {
118
+ open: addOpen,
119
+ onOpenChange: setAddOpen,
120
+ sealed,
121
+ onAdded: refresh,
122
+ wallet
123
+ }
124
+ )
125
+ ] });
126
+ }
127
+ export {
128
+ GuardianRecoverySection
129
+ };
130
+ //# sourceMappingURL=guardian-recovery-section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/account/guardian-recovery-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Shield, ShieldAlert, ChevronRight, Loader2 } from \"lucide-react\";\nimport {\n describeGuardianStatus,\n describeRecoveryAction,\n type EscapeInfo,\n type GuardianInfo,\n} from \"@medialane/sdk/starknet\";\nimport Link from \"../link.js\";\nimport { Button } from \"../button.js\";\nimport { Badge } from \"../badge.js\";\nimport { Alert, AlertDescription } from \"../alert.js\";\nimport { describeError } from \"../../utils/describe-error.js\";\nimport { AddGuardianDialog } from \"./add-guardian-dialog.js\";\nimport type { GuardianWallet, LoadSealedOwner } from \"./wallet-types.js\";\n\nconst short = (a: string) => `${a.slice(0, 6)}…${a.slice(-4)}`;\n\nexport interface GuardianRecoverySectionProps {\n walletAddress: string;\n wallet: GuardianWallet;\n loadSealed: LoadSealedOwner;\n guardianRecoveryAvailable: boolean;\n recoverHref?: string;\n}\n\nexport function GuardianRecoverySection({\n walletAddress,\n wallet,\n loadSealed,\n guardianRecoveryAvailable,\n recoverHref = \"/recover\",\n}: GuardianRecoverySectionProps) {\n const [guardians, setGuardians] = useState<GuardianInfo[] | null>(null);\n const [escape, setEscape] = useState<EscapeInfo | null>(null);\n const [addOpen, setAddOpen] = useState(false);\n const [cancelBusy, setCancelBusy] = useState(false);\n const [cancelError, setCancelError] = useState<string | null>(null);\n\n const refresh = useCallback(() => {\n wallet.getGuardians(walletAddress).then(setGuardians).catch(() => setGuardians([]));\n wallet.getEscape(walletAddress).then(setEscape).catch(() => setEscape(null));\n }, [walletAddress, wallet]);\n\n useEffect(() => { refresh(); }, [refresh]);\n\n const handleCancel = async () => {\n const sealed = loadSealed();\n if (!sealed) return;\n setCancelBusy(true);\n setCancelError(null);\n try {\n await wallet.cancelEscape(sealed);\n refresh();\n } catch (e) {\n setCancelError(describeError(e, \"We couldn't cancel recovery. Please try again.\").message);\n } finally {\n setCancelBusy(false);\n }\n };\n\n const status = guardians ? describeGuardianStatus(guardians) : null;\n const recoveryAction = escape ? describeRecoveryAction(escape) : \"none\";\n const inProgress = escape?.escapeType === \"Owner\" && recoveryAction !== \"none\" ? escape : null;\n\n const sealed = loadSealed();\n\n return (\n <div className=\"rounded-2xl border border-border/60 bg-card p-5 sm:p-6 space-y-5\">\n <div className=\"flex items-start gap-3\">\n <div className=\"h-10 w-10 shrink-0 rounded-full bg-emerald-500/10 flex items-center justify-center\">\n <Shield className=\"h-5 w-5 text-emerald-600 dark:text-emerald-400\" />\n </div>\n <div>\n <h3 className=\"text-base font-bold text-foreground\">Security &amp; Recovery</h3>\n <p className=\"text-sm text-muted-foreground mt-0.5\">\n A guardian can help you get back into this wallet if you ever lose this device.\n </p>\n </div>\n </div>\n\n <div className=\"space-y-3\">\n {inProgress && (\n <Alert variant=\"destructive\">\n <ShieldAlert className=\"h-4 w-4\" />\n <AlertDescription>\n A guardian has started replacing this wallet&apos;s owner key.{\" \"}\n {inProgress.status === \"Ready\"\n ? \"It can complete at any time.\"\n : `It can complete on ${new Date(inProgress.readyAt * 1000).toLocaleString()}.`}{\" \"}\n If this wasn&apos;t you, cancel it now.\n {cancelError && <p className=\"mt-1 text-destructive\">{cancelError}</p>}\n <Button\n onClick={handleCancel}\n disabled={cancelBusy}\n variant=\"destructive\"\n size=\"sm\"\n className=\"mt-2 w-full\"\n >\n {cancelBusy ? <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" /> : null}\n Cancel recovery\n </Button>\n </AlertDescription>\n </Alert>\n )}\n\n <div className=\"flex items-center justify-between gap-3 rounded-xl border border-border/60 p-4 flex-wrap\">\n <div>\n <p className=\"text-sm font-medium text-foreground\">Guardian recovery</p>\n {status === null ? (\n <p className=\"text-xs text-muted-foreground mt-0.5\">Checking…</p>\n ) : status.kind === \"none\" ? (\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {guardianRecoveryAvailable ? \"Not set up — add one from another device you trust.\" : \"Not available yet.\"}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n Active: {status.guardian.type} guardian {short(status.guardian.storedValue)}\n </p>\n )}\n </div>\n {status?.kind === \"none\" && sealed && (\n <Button onClick={() => setAddOpen(true)} variant=\"outline\" size=\"sm\" disabled={!guardianRecoveryAvailable}>\n Add guardian\n </Button>\n )}\n {status?.kind === \"active\" && (\n <Badge variant=\"outline\" className=\"border-emerald-500/40 text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 text-[10px]\">\n Configured\n </Badge>\n )}\n </div>\n\n <Link\n href={recoverHref}\n className=\"flex items-center justify-between gap-3 rounded-xl border border-border/60 p-4 transition-colors hover:bg-foreground/[0.03]\"\n >\n <div>\n <p className=\"text-sm font-medium text-foreground\">Recover a wallet</p>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n Lost this device, or acting as someone&apos;s guardian?\n </p>\n </div>\n <ChevronRight className=\"h-4 w-4 text-muted-foreground shrink-0\" />\n </Link>\n </div>\n\n {sealed && guardianRecoveryAvailable && (\n <AddGuardianDialog\n open={addOpen}\n onOpenChange={setAddOpen}\n sealed={sealed}\n onAdded={refresh}\n wallet={wallet}\n />\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["sealed"]}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var input_otp_exports = {};
31
+ __export(input_otp_exports, {
32
+ InputOTP: () => InputOTP,
33
+ InputOTPGroup: () => InputOTPGroup,
34
+ InputOTPSeparator: () => InputOTPSeparator,
35
+ InputOTPSlot: () => InputOTPSlot
36
+ });
37
+ module.exports = __toCommonJS(input_otp_exports);
38
+ var import_jsx_runtime = require("react/jsx-runtime");
39
+ var React = __toESM(require("react"), 1);
40
+ var import_input_otp = require("input-otp");
41
+ var import_lucide_react = require("lucide-react");
42
+ var import_cn = require("../../utils/cn.js");
43
+ const InputOTP = React.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
44
+ import_input_otp.OTPInput,
45
+ {
46
+ ref,
47
+ containerClassName: (0, import_cn.cn)("flex items-center gap-2 has-[:disabled]:opacity-50", containerClassName),
48
+ className: (0, import_cn.cn)("disabled:cursor-not-allowed", className),
49
+ ...props
50
+ }
51
+ ));
52
+ InputOTP.displayName = "InputOTP";
53
+ const InputOTPGroup = React.forwardRef(
54
+ ({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref, className: (0, import_cn.cn)("flex items-center", className), ...props })
55
+ );
56
+ InputOTPGroup.displayName = "InputOTPGroup";
57
+ const InputOTPSlot = React.forwardRef(({ index, className, ...props }, ref) => {
58
+ const inputOTPContext = React.useContext(import_input_otp.OTPInputContext);
59
+ const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index];
60
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
61
+ "div",
62
+ {
63
+ ref,
64
+ className: (0, import_cn.cn)(
65
+ "relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md",
66
+ isActive && "z-10 ring-2 ring-ring ring-offset-background",
67
+ className
68
+ ),
69
+ ...props,
70
+ children: [
71
+ char,
72
+ hasFakeCaret && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-4 w-px animate-caret-blink bg-foreground duration-1000" }) })
73
+ ]
74
+ }
75
+ );
76
+ });
77
+ InputOTPSlot.displayName = "InputOTPSlot";
78
+ const InputOTPSeparator = React.forwardRef(
79
+ ({ ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ref, role: "separator", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Dot, {}) })
80
+ );
81
+ InputOTPSeparator.displayName = "InputOTPSeparator";
82
+ // Annotate the CommonJS export names for ESM import in node:
83
+ 0 && (module.exports = {
84
+ InputOTP,
85
+ InputOTPGroup,
86
+ InputOTPSeparator,
87
+ InputOTPSlot
88
+ });
89
+ //# sourceMappingURL=input-otp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/account/input-otp.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { OTPInput, OTPInputContext } from \"input-otp\";\nimport { Dot } from \"lucide-react\";\nimport { cn } from \"../../utils/cn.js\";\n\nconst InputOTP = React.forwardRef<\n React.ElementRef<typeof OTPInput>,\n React.ComponentPropsWithoutRef<typeof OTPInput>\n>(({ className, containerClassName, ...props }, ref) => (\n <OTPInput\n ref={ref}\n containerClassName={cn(\"flex items-center gap-2 has-[:disabled]:opacity-50\", containerClassName)}\n className={cn(\"disabled:cursor-not-allowed\", className)}\n {...props}\n />\n));\nInputOTP.displayName = \"InputOTP\";\n\nconst InputOTPGroup = React.forwardRef<React.ElementRef<\"div\">, React.ComponentPropsWithoutRef<\"div\">>(\n ({ className, ...props }, ref) => <div ref={ref} className={cn(\"flex items-center\", className)} {...props} />,\n);\nInputOTPGroup.displayName = \"InputOTPGroup\";\n\nconst InputOTPSlot = React.forwardRef<\n React.ElementRef<\"div\">,\n React.ComponentPropsWithoutRef<\"div\"> & { index: number }\n>(({ index, className, ...props }, ref) => {\n const inputOTPContext = React.useContext(OTPInputContext);\n const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index]!;\n\n return (\n <div\n ref={ref}\n className={cn(\n \"relative flex h-10 w-10 items-center justify-center border-y border-r border-input text-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md\",\n isActive && \"z-10 ring-2 ring-ring ring-offset-background\",\n className,\n )}\n {...props}\n >\n {char}\n {hasFakeCaret && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n <div className=\"h-4 w-px animate-caret-blink bg-foreground duration-1000\" />\n </div>\n )}\n </div>\n );\n});\nInputOTPSlot.displayName = \"InputOTPSlot\";\n\nconst InputOTPSeparator = React.forwardRef<React.ElementRef<\"div\">, React.ComponentPropsWithoutRef<\"div\">>(\n ({ ...props }, ref) => (\n <div ref={ref} role=\"separator\" {...props}>\n <Dot />\n </div>\n ),\n);\nInputOTPSeparator.displayName = \"InputOTPSeparator\";\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWE;AATF,YAAuB;AACvB,uBAA0C;AAC1C,0BAAoB;AACpB,gBAAmB;AAEnB,MAAM,WAAW,MAAM,WAGrB,CAAC,EAAE,WAAW,oBAAoB,GAAG,MAAM,GAAG,QAC9C;AAAA,EAAC;AAAA;AAAA,IACC;AAAA,IACA,wBAAoB,cAAG,sDAAsD,kBAAkB;AAAA,IAC/F,eAAW,cAAG,+BAA+B,SAAS;AAAA,IACrD,GAAG;AAAA;AACN,CACD;AACD,SAAS,cAAc;AAEvB,MAAM,gBAAgB,MAAM;AAAA,EAC1B,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,QAAQ,4CAAC,SAAI,KAAU,eAAW,cAAG,qBAAqB,SAAS,GAAI,GAAG,OAAO;AAC7G;AACA,cAAc,cAAc;AAE5B,MAAM,eAAe,MAAM,WAGzB,CAAC,EAAE,OAAO,WAAW,GAAG,MAAM,GAAG,QAAQ;AACzC,QAAM,kBAAkB,MAAM,WAAW,gCAAe;AACxD,QAAM,EAAE,MAAM,cAAc,SAAS,IAAI,gBAAgB,MAAM,KAAK;AAEpE,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,eAAW;AAAA,QACT;AAAA,QACA,YAAY;AAAA,QACZ;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QACA,gBACC,4CAAC,SAAI,WAAU,yEACb,sDAAC,SAAI,WAAU,4DAA2D,GAC5E;AAAA;AAAA;AAAA,EAEJ;AAEJ,CAAC;AACD,aAAa,cAAc;AAE3B,MAAM,oBAAoB,MAAM;AAAA,EAC9B,CAAC,EAAE,GAAG,MAAM,GAAG,QACb,4CAAC,SAAI,KAAU,MAAK,aAAa,GAAG,OAClC,sDAAC,2BAAI,GACP;AAEJ;AACA,kBAAkB,cAAc;","names":[]}
@@ -0,0 +1,37 @@
1
+ import * as input_otp from 'input-otp';
2
+ import * as React from 'react';
3
+
4
+ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
5
+ value?: string;
6
+ onChange?: (newValue: string) => unknown;
7
+ maxLength: number;
8
+ textAlign?: "left" | "center" | "right";
9
+ onComplete?: (...args: any[]) => unknown;
10
+ pushPasswordManagerStrategy?: "increase-width" | "none";
11
+ pasteTransformer?: (pasted: string) => string;
12
+ containerClassName?: string;
13
+ noScriptCSSFallback?: string | null;
14
+ } & {
15
+ render: (props: input_otp.RenderProps) => React.ReactNode;
16
+ children?: never;
17
+ } & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
18
+ value?: string;
19
+ onChange?: (newValue: string) => unknown;
20
+ maxLength: number;
21
+ textAlign?: "left" | "center" | "right";
22
+ onComplete?: (...args: any[]) => unknown;
23
+ pushPasswordManagerStrategy?: "increase-width" | "none";
24
+ pasteTransformer?: (pasted: string) => string;
25
+ containerClassName?: string;
26
+ noScriptCSSFallback?: string | null;
27
+ } & {
28
+ render?: never;
29
+ children: React.ReactNode;
30
+ } & React.RefAttributes<HTMLInputElement>, "ref">) & React.RefAttributes<HTMLInputElement>>;
31
+ declare const InputOTPGroup: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
32
+ declare const InputOTPSlot: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
33
+ index: number;
34
+ } & React.RefAttributes<HTMLDivElement>>;
35
+ declare const InputOTPSeparator: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
36
+
37
+ export { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot };