@ab-org/predicate-market-sdk 0.0.1

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 (86) hide show
  1. package/README.md +246 -0
  2. package/dist/auth/autoReconnect.d.ts +11 -0
  3. package/dist/auth/autoReconnect.js +36 -0
  4. package/dist/auth/bundledConfig.d.ts +2 -0
  5. package/dist/auth/bundledConfig.js +19 -0
  6. package/dist/auth/config.d.ts +29 -0
  7. package/dist/auth/config.js +53 -0
  8. package/dist/auth/google.d.ts +43 -0
  9. package/dist/auth/google.js +147 -0
  10. package/dist/auth/twitter.d.ts +7 -0
  11. package/dist/auth/twitter.js +94 -0
  12. package/dist/constants/chains.d.ts +22 -0
  13. package/dist/constants/chains.js +23 -0
  14. package/dist/index.d.ts +19 -0
  15. package/dist/index.js +19 -0
  16. package/dist/modules/api.d.ts +144 -0
  17. package/dist/modules/api.js +93 -0
  18. package/dist/modules/balanceQuery.d.ts +20 -0
  19. package/dist/modules/balanceQuery.js +58 -0
  20. package/dist/modules/deposit.d.ts +31 -0
  21. package/dist/modules/deposit.js +57 -0
  22. package/dist/modules/marketData.d.ts +8 -0
  23. package/dist/modules/marketData.js +113 -0
  24. package/dist/modules/withdraw.d.ts +31 -0
  25. package/dist/modules/withdraw.js +60 -0
  26. package/dist/modules/withdrawExecutor.d.ts +47 -0
  27. package/dist/modules/withdrawExecutor.js +208 -0
  28. package/dist/policyAdapter.d.ts +11 -0
  29. package/dist/policyAdapter.js +38 -0
  30. package/dist/types.d.ts +62 -0
  31. package/dist/types.js +1 -0
  32. package/dist/ui/DepositModal.d.ts +36 -0
  33. package/dist/ui/DepositModal.js +326 -0
  34. package/dist/ui/SignInModal.d.ts +22 -0
  35. package/dist/ui/SignInModal.js +74 -0
  36. package/dist/ui/SignInModal.sections.d.ts +33 -0
  37. package/dist/ui/SignInModal.sections.js +45 -0
  38. package/dist/ui/SignInModal.shared.d.ts +15 -0
  39. package/dist/ui/SignInModal.shared.js +87 -0
  40. package/dist/ui/WalletSelectionModal.d.ts +14 -0
  41. package/dist/ui/WalletSelectionModal.js +54 -0
  42. package/dist/ui/WithdrawModal.d.ts +47 -0
  43. package/dist/ui/WithdrawModal.js +528 -0
  44. package/dist/ui/components/CloseButton.d.ts +4 -0
  45. package/dist/ui/components/CloseButton.js +15 -0
  46. package/dist/ui/components/Countdown.d.ts +16 -0
  47. package/dist/ui/components/Countdown.js +42 -0
  48. package/dist/ui/components/DepositDetailsPanel.d.ts +8 -0
  49. package/dist/ui/components/DepositDetailsPanel.js +117 -0
  50. package/dist/ui/components/DropdownField.d.ts +19 -0
  51. package/dist/ui/components/DropdownField.js +81 -0
  52. package/dist/ui/components/Field.d.ts +10 -0
  53. package/dist/ui/components/Field.js +21 -0
  54. package/dist/ui/components/LoginRequiredOverlay.d.ts +6 -0
  55. package/dist/ui/components/LoginRequiredOverlay.js +31 -0
  56. package/dist/ui/components/ModalCard.d.ts +9 -0
  57. package/dist/ui/components/ModalCard.js +14 -0
  58. package/dist/ui/components/ModalFrame.d.ts +9 -0
  59. package/dist/ui/components/ModalFrame.js +18 -0
  60. package/dist/ui/components/PrimaryButton.d.ts +2 -0
  61. package/dist/ui/components/PrimaryButton.js +14 -0
  62. package/dist/ui/components/QRCodePanel.d.ts +4 -0
  63. package/dist/ui/components/QRCodePanel.js +43 -0
  64. package/dist/ui/components/Select.d.ts +12 -0
  65. package/dist/ui/components/Select.js +29 -0
  66. package/dist/ui/components/StepIndicator.d.ts +7 -0
  67. package/dist/ui/components/StepIndicator.js +35 -0
  68. package/dist/ui/components/Success.d.ts +1 -0
  69. package/dist/ui/components/Success.js +4 -0
  70. package/dist/ui/components/Toast.d.ts +8 -0
  71. package/dist/ui/components/Toast.js +51 -0
  72. package/dist/ui/hooks/useSession.d.ts +2 -0
  73. package/dist/ui/hooks/useSession.js +10 -0
  74. package/dist/ui/signInTypes.d.ts +25 -0
  75. package/dist/ui/signInTypes.js +1 -0
  76. package/dist/ui/theme.d.ts +31 -0
  77. package/dist/ui/theme.js +31 -0
  78. package/dist/ui/useSignInModalController.d.ts +25 -0
  79. package/dist/ui/useSignInModalController.js +173 -0
  80. package/dist/utils/env.d.ts +1 -0
  81. package/dist/utils/env.js +61 -0
  82. package/dist/utils/explorer.d.ts +3 -0
  83. package/dist/utils/explorer.js +47 -0
  84. package/dist/walletUtils.d.ts +3 -0
  85. package/dist/walletUtils.js +3 -0
  86. package/package.json +41 -0
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { colors } from "../theme.js";
3
+ export const CloseButton = ({ onClick }) => (_jsx("button", { type: "button", onClick: onClick, "aria-label": "Close", style: {
4
+ width: 30,
5
+ height: 30,
6
+ borderRadius: "50%",
7
+ background: colors.card,
8
+ border: "none",
9
+ cursor: "pointer",
10
+ display: "flex",
11
+ alignItems: "center",
12
+ justifyContent: "center",
13
+ padding: 0,
14
+ flexShrink: 0,
15
+ }, children: _jsx("svg", { width: "17", height: "17", viewBox: "0 0 17 17", fill: "none", children: _jsx("path", { d: "M4.25 4.25L12.75 12.75M12.75 4.25L4.25 12.75", stroke: colors.textPrimary, strokeWidth: "1.5", strokeLinecap: "round" }) }) }));
@@ -0,0 +1,16 @@
1
+ export interface CountdownProps {
2
+ /** 过期时间:ISO 字符串或时间戳(毫秒) */
3
+ expiresAt: string | number;
4
+ /** 过期时显示文案,默认 "Expired" */
5
+ expiredLabel?: string;
6
+ /** 自定义样式 */
7
+ style?: React.CSSProperties;
8
+ /** 是否已过期(由外部控制,用于与 quoteExpired 等联动时不再倒计时) */
9
+ isExpired?: boolean;
10
+ /** 倒计时归零时调用一次(可用于自动重新询价等) */
11
+ onExpired?: () => void;
12
+ }
13
+ /**
14
+ * 倒计时组件:每秒更新,显示距 expiresAt 的剩余时间(MM:SS)。
15
+ */
16
+ export declare function Countdown({ expiresAt, expiredLabel, style, isExpired, onExpired, }: CountdownProps): import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect, useRef } from "react";
3
+ import { colors, fonts } from "../theme.js";
4
+ function getRemaining(expiresAt) {
5
+ const end = typeof expiresAt === "string" ? new Date(expiresAt).getTime() : expiresAt;
6
+ return Math.max(0, Math.floor((end - Date.now()) / 1000));
7
+ }
8
+ function formatRemaining(seconds) {
9
+ const m = Math.floor(seconds / 60);
10
+ const s = seconds % 60;
11
+ return `${m}:${s.toString().padStart(2, "0")}`;
12
+ }
13
+ /**
14
+ * 倒计时组件:每秒更新,显示距 expiresAt 的剩余时间(MM:SS)。
15
+ */
16
+ export function Countdown({ expiresAt, expiredLabel = "Expired", style, isExpired = false, onExpired, }) {
17
+ const [remaining, setRemaining] = useState(() => getRemaining(expiresAt));
18
+ const hasFiredExpired = useRef(false);
19
+ useEffect(() => {
20
+ hasFiredExpired.current = false;
21
+ }, [expiresAt]);
22
+ useEffect(() => {
23
+ if (isExpired) {
24
+ setRemaining(0);
25
+ return;
26
+ }
27
+ const tick = () => {
28
+ const r = getRemaining(expiresAt);
29
+ setRemaining(r);
30
+ if (r <= 0 && onExpired && !hasFiredExpired.current) {
31
+ hasFiredExpired.current = true;
32
+ onExpired();
33
+ }
34
+ };
35
+ tick();
36
+ const id = setInterval(tick, 1000);
37
+ return () => clearInterval(id);
38
+ }, [expiresAt, isExpired, onExpired]);
39
+ const text = remaining <= 0 ? expiredLabel : formatRemaining(remaining);
40
+ const color = remaining <= 0 ? colors.warning : colors.textSecondary;
41
+ return (_jsxs("span", { style: { fontSize: 12, color, fontFamily: fonts.family, ...style }, children: ["Expires in ", _jsx("span", { style: { fontWeight: 600, color: "#fff" }, children: text })] }));
42
+ }
@@ -0,0 +1,8 @@
1
+ import { type ReactNode } from "react";
2
+ export interface DepositDetailsPanelProps {
3
+ address: string;
4
+ tokenIcon?: ReactNode;
5
+ minimumDeposit?: string;
6
+ onCopyAddress?: () => void;
7
+ }
8
+ export declare const DepositDetailsPanel: ({ address, tokenIcon, minimumDeposit, onCopyAddress, }: DepositDetailsPanelProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,117 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import qrcode from "qrcode-generator";
4
+ import { colors, fonts, radii } from "../theme.js";
5
+ /* ─── QR matrix generation ──────────────────── */
6
+ function generateMatrix(data) {
7
+ const qr = qrcode(0, "H");
8
+ qr.addData(data);
9
+ qr.make();
10
+ const count = qr.getModuleCount();
11
+ const matrix = [];
12
+ for (let r = 0; r < count; r++) {
13
+ const row = [];
14
+ for (let c = 0; c < count; c++) {
15
+ row.push(qr.isDark(r, c));
16
+ }
17
+ matrix.push(row);
18
+ }
19
+ return matrix;
20
+ }
21
+ function isFinderZone(row, col, size) {
22
+ return ((row < 7 && col < 7) ||
23
+ (row < 7 && col >= size - 7) ||
24
+ (row >= size - 7 && col < 7));
25
+ }
26
+ /* ─── Styled finder eye (rounded nested rects) ── */
27
+ const FinderEye = ({ ox, oy, s }) => (_jsxs(_Fragment, { children: [_jsx("rect", { x: ox, y: oy, width: 7 * s, height: 7 * s, rx: s * 1.4, ry: s * 1.4, fill: "#fff" }), _jsx("rect", { x: ox + s, y: oy + s, width: 5 * s, height: 5 * s, rx: s * 0.9, ry: s * 0.9, fill: colors.background }), _jsx("rect", { x: ox + 2 * s, y: oy + 2 * s, width: 3 * s, height: 3 * s, rx: s * 0.7, ry: s * 0.7, fill: "#fff" })] }));
28
+ /* ─── Styled SVG QR ─────────────────────────── */
29
+ const SVG_SIZE = 220;
30
+ const QUIET_ZONE = 2;
31
+ const StyledQR = ({ data }) => {
32
+ const matrix = useMemo(() => generateMatrix(data), [data]);
33
+ const n = matrix.length;
34
+ const total = n + QUIET_ZONE * 2;
35
+ const cell = SVG_SIZE / total;
36
+ const off = QUIET_ZONE * cell;
37
+ const dotR = cell * 0.42;
38
+ const centerClearR = 3;
39
+ const cx = n / 2;
40
+ const cy = n / 2;
41
+ const dots = [];
42
+ for (let r = 0; r < n; r++) {
43
+ for (let c = 0; c < n; c++) {
44
+ if (!matrix[r][c])
45
+ continue;
46
+ if (isFinderZone(r, c, n))
47
+ continue;
48
+ if (Math.abs(c - cx) < centerClearR && Math.abs(r - cy) < centerClearR)
49
+ continue;
50
+ dots.push(_jsx("circle", { cx: off + c * cell + cell / 2, cy: off + r * cell + cell / 2, r: dotR, fill: "#fff" }, `${r}-${c}`));
51
+ }
52
+ }
53
+ return (_jsxs("svg", { width: SVG_SIZE, height: SVG_SIZE, viewBox: `0 0 ${SVG_SIZE} ${SVG_SIZE}`, style: { borderRadius: 12 }, children: [_jsx("rect", { width: SVG_SIZE, height: SVG_SIZE, fill: colors.background }), _jsx(FinderEye, { ox: off, oy: off, s: cell }), _jsx(FinderEye, { ox: off + (n - 7) * cell, oy: off, s: cell }), _jsx(FinderEye, { ox: off, oy: off + (n - 7) * cell, s: cell }), dots] }));
54
+ };
55
+ /* ─── Copy icon ─────────────────────────────── */
56
+ const CopyIcon = () => (_jsxs("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", children: [_jsx("rect", { x: "4.5", y: "4.5", width: "7", height: "7", rx: "1.5", stroke: colors.textPrimary, strokeWidth: "1.2" }), _jsx("path", { d: "M9.5 4.5V3.5C9.5 2.67 8.83 2 8 2H3.5C2.67 2 2 2.67 2 3.5V8C2 8.83 2.67 9.5 3.5 9.5H4.5", stroke: colors.textPrimary, strokeWidth: "1.2" })] }));
57
+ /* ─── Main ──────────────────────────────────── */
58
+ export const DepositDetailsPanel = ({ address, tokenIcon, minimumDeposit, onCopyAddress, }) => {
59
+ const handleCopy = () => {
60
+ navigator.clipboard?.writeText(address);
61
+ onCopyAddress?.();
62
+ };
63
+ return (_jsxs("div", { style: {
64
+ display: "flex",
65
+ flexDirection: "column",
66
+ alignItems: "center",
67
+ gap: 16,
68
+ padding: "20px",
69
+ borderRadius: radii.card,
70
+ border: `1px solid ${colors.border}`,
71
+ fontFamily: fonts.family,
72
+ }, children: [_jsxs("div", { style: { position: "relative", display: "inline-flex" }, children: [_jsx(StyledQR, { data: address }), tokenIcon && (_jsx("div", { style: {
73
+ position: "absolute",
74
+ top: "50%",
75
+ left: "50%",
76
+ transform: "translate(-50%, -50%)",
77
+ width: 36,
78
+ height: 36,
79
+ borderRadius: "50%",
80
+ background: "#3B5998",
81
+ display: "flex",
82
+ alignItems: "center",
83
+ justifyContent: "center",
84
+ boxShadow: `0 0 0 3px ${colors.background}`,
85
+ }, children: tokenIcon }))] }), _jsx("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: 8 }, children: _jsx("div", { style: {
86
+ padding: "10px 14px",
87
+ borderRadius: radii.input,
88
+ background: "rgba(255,255,255,0.05)",
89
+ fontSize: 13,
90
+ color: colors.textPrimary,
91
+ wordBreak: "break-all",
92
+ lineHeight: 1.5,
93
+ }, children: address }) }), minimumDeposit && (_jsxs("div", { style: {
94
+ width: "100%",
95
+ display: "flex",
96
+ justifyContent: "space-between",
97
+ fontSize: 13,
98
+ }, children: [_jsx("span", { style: { color: colors.textSecondary }, children: "Minimum deposit" }), _jsx("span", { style: { color: colors.textPrimary, fontWeight: 500 }, children: minimumDeposit })] })), _jsxs("button", { type: "button", onClick: handleCopy, style: {
99
+ display: "flex",
100
+ alignItems: "center",
101
+ gap: 6,
102
+ padding: "10px 28px",
103
+ borderRadius: radii.pill,
104
+ border: `1px solid ${colors.borderStrong}`,
105
+ background: "transparent",
106
+ color: colors.textPrimary,
107
+ fontSize: 14,
108
+ fontWeight: 500,
109
+ cursor: "pointer",
110
+ fontFamily: fonts.family,
111
+ transition: "background .15s",
112
+ }, onMouseEnter: (e) => {
113
+ e.currentTarget.style.background = "rgba(255,255,255,0.06)";
114
+ }, onMouseLeave: (e) => {
115
+ e.currentTarget.style.background = "transparent";
116
+ }, children: [_jsx(CopyIcon, {}), "Copy address"] })] }));
117
+ };
@@ -0,0 +1,19 @@
1
+ import { type ReactNode } from "react";
2
+ export interface SelectOption {
3
+ id: string;
4
+ label: string;
5
+ subtitle?: string;
6
+ icon?: ReactNode;
7
+ }
8
+ export interface DropdownFieldProps {
9
+ label: string;
10
+ placeholder?: string;
11
+ value?: string;
12
+ icon?: ReactNode;
13
+ focused?: boolean;
14
+ options?: SelectOption[];
15
+ onSelect?: (id: string) => void;
16
+ /** @deprecated Use `options` + `onSelect` instead. */
17
+ onClick?: () => void;
18
+ }
19
+ export declare const DropdownField: ({ label, placeholder, value, icon, focused, options, onSelect, onClick, }: DropdownFieldProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useRef, useEffect } from "react";
3
+ import { colors, fonts, radii } from "../theme.js";
4
+ const Chevron = ({ up }) => (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", style: { transition: "transform .2s", transform: up ? "rotate(180deg)" : "none" }, children: _jsx("path", { d: "M4 6L8 10L12 6", stroke: colors.textSecondary, strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
5
+ export const DropdownField = ({ label, placeholder, value, icon, focused, options, onSelect, onClick, }) => {
6
+ const [open, setOpen] = useState(false);
7
+ const [triggerFocused, setTriggerFocused] = useState(false);
8
+ const ref = useRef(null);
9
+ useEffect(() => {
10
+ if (!open)
11
+ return;
12
+ const handler = (e) => {
13
+ if (ref.current && !ref.current.contains(e.target))
14
+ setOpen(false);
15
+ };
16
+ document.addEventListener("mousedown", handler);
17
+ return () => document.removeEventListener("mousedown", handler);
18
+ }, [open]);
19
+ const hasOptions = options && options.length > 0;
20
+ const handleClick = () => {
21
+ if (hasOptions) {
22
+ setOpen((p) => !p);
23
+ }
24
+ else {
25
+ onClick?.();
26
+ }
27
+ };
28
+ const handleSelect = (id) => {
29
+ onSelect?.(id);
30
+ setOpen(false);
31
+ };
32
+ const selected = hasOptions ? options.find((o) => o.id === value) : undefined;
33
+ return (_jsxs("div", { ref: ref, style: { display: "flex", flexDirection: "column", gap: 8, width: "100%", position: "relative" }, children: [_jsx("span", { style: {
34
+ fontSize: 14,
35
+ fontWeight: 400,
36
+ lineHeight: 1.4,
37
+ color: colors.textPrimary,
38
+ fontFamily: fonts.family,
39
+ }, children: label }), _jsxs("button", { type: "button", onClick: handleClick, onFocus: () => setTriggerFocused(true), onBlur: () => setTriggerFocused(false), style: {
40
+ display: "flex",
41
+ alignItems: "center",
42
+ justifyContent: "space-between",
43
+ height: 44,
44
+ padding: "0 16px",
45
+ borderRadius: radii.input,
46
+ border: `1px solid ${open || triggerFocused ? colors.borderFocused : colors.border}`,
47
+ background: "transparent",
48
+ cursor: "pointer",
49
+ fontFamily: fonts.family,
50
+ width: "100%",
51
+ boxSizing: "border-box",
52
+ }, children: [_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [selected?.icon ?? icon, _jsx("span", { style: {
53
+ fontSize: 14,
54
+ lineHeight: 1.4,
55
+ color: value ? colors.textPrimary : colors.textSecondary,
56
+ fontFamily: fonts.family,
57
+ }, children: selected?.label ?? value ?? placeholder })] }), _jsx(Chevron, { up: open })] }), open && hasOptions && (_jsx("div", { className: "dropdown-list-item", style: {
58
+ position: "absolute",
59
+ top: "calc(100% + 4px)",
60
+ left: 0,
61
+ right: 0,
62
+ zIndex: 10,
63
+ borderRadius: radii.input,
64
+ border: `1px solid ${colors.border}`,
65
+ background: colors.card,
66
+ overflow: "hidden",
67
+ boxShadow: "0 8px 24px rgba(0,0,0,0.4)",
68
+ }, children: options.map((opt) => (_jsxs("button", { type: "button", onClick: () => handleSelect(opt.id), style: {
69
+ display: "flex",
70
+ alignItems: "center",
71
+ gap: 10,
72
+ width: "100%",
73
+ padding: "10px 16px",
74
+ border: "none",
75
+ background: opt.id === value ? "rgba(255,255,255,0.06)" : "transparent",
76
+ cursor: "pointer",
77
+ fontFamily: fonts.family,
78
+ textAlign: "left",
79
+ transition: "background .12s",
80
+ }, onMouseEnter: (e) => { e.currentTarget.style.background = "rgba(255,255,255,0.08)"; }, onMouseLeave: (e) => { e.currentTarget.style.background = opt.id === value ? "rgba(255,255,255,0.06)" : "transparent"; }, children: [opt.icon && (_jsx("div", { style: { width: 28, height: 28, flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: opt.icon })), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 1 }, children: [_jsx("span", { style: { fontSize: 14, fontWeight: 500, color: colors.textPrimary }, children: opt.label }), opt.subtitle && (_jsx("span", { style: { fontSize: 12, color: colors.textSecondary }, children: opt.subtitle }))] })] }, opt.id))) }))] }));
81
+ };
@@ -0,0 +1,10 @@
1
+ import type { ChangeEventHandler } from "react";
2
+ export interface FieldProps {
3
+ label: string;
4
+ placeholder?: string;
5
+ value?: string;
6
+ onChange?: ChangeEventHandler<HTMLInputElement>;
7
+ prefix?: React.ReactNode;
8
+ suffix?: React.ReactNode;
9
+ }
10
+ export declare const Field: ({ label, placeholder, value, onChange, prefix, suffix }: FieldProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { colors, fonts, radii } from "../theme.js";
3
+ export const Field = ({ label, placeholder, value, onChange, prefix, suffix }) => {
4
+ return (_jsxs("label", { style: { display: "flex", flexDirection: "column", gap: 8, fontFamily: fonts.family }, children: [_jsx("span", { style: { fontSize: 14, color: colors.textSecondary }, children: label }), _jsxs("div", { style: {
5
+ display: "flex",
6
+ alignItems: "center",
7
+ background: colors.cardRaised,
8
+ borderRadius: radii.md,
9
+ border: `1px solid ${colors.borderStrong}`,
10
+ padding: "0 14px",
11
+ }, children: [prefix && _jsx("span", { style: { marginRight: 8, color: colors.textSecondary }, children: prefix }), _jsx("input", { value: value, onChange: onChange, placeholder: placeholder, style: {
12
+ flex: 1,
13
+ border: "none",
14
+ outline: "none",
15
+ background: "transparent",
16
+ color: colors.textPrimary,
17
+ fontSize: 16,
18
+ fontFamily: fonts.family,
19
+ padding: "16px 0",
20
+ } }), suffix && _jsx("span", { style: { marginLeft: 8 }, children: suffix })] })] }));
21
+ };
@@ -0,0 +1,6 @@
1
+ export interface LoginRequiredOverlayProps {
2
+ title: string;
3
+ onSignIn?: () => void;
4
+ onClose?: () => void;
5
+ }
6
+ export declare const LoginRequiredOverlay: ({ title, onSignIn, onClose, }: LoginRequiredOverlayProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ModalFrame } from "./ModalFrame.js";
3
+ import { colors, fonts, radii } from "../theme.js";
4
+ const LockIcon = () => (_jsxs("svg", { width: "48", height: "48", viewBox: "0 0 48 48", fill: "none", children: [_jsx("rect", { x: "10", y: "22", width: "28", height: "20", rx: "4", stroke: colors.textSecondary, strokeWidth: "2" }), _jsx("path", { d: "M16 22V16C16 11.5817 19.5817 8 24 8C28.4183 8 32 11.5817 32 16V22", stroke: colors.textSecondary, strokeWidth: "2", strokeLinecap: "round" }), _jsx("circle", { cx: "24", cy: "33", r: "3", fill: colors.textSecondary })] }));
5
+ export const LoginRequiredOverlay = ({ title, onSignIn, onClose, }) => (_jsx(ModalFrame, { onClose: onClose, contentStyle: { padding: "48px 24px" }, children: _jsxs("div", { style: {
6
+ display: "flex",
7
+ flexDirection: "column",
8
+ alignItems: "center",
9
+ gap: 24,
10
+ textAlign: "center",
11
+ }, children: [_jsx(LockIcon, {}), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [_jsx("h2", { style: {
12
+ margin: 0,
13
+ fontSize: 20,
14
+ fontWeight: 600,
15
+ color: colors.textPrimary,
16
+ }, children: title }), _jsx("p", { style: {
17
+ margin: 0,
18
+ fontSize: 14,
19
+ color: colors.textSecondary,
20
+ lineHeight: 1.5,
21
+ }, children: "Please sign in to continue" })] }), onSignIn && (_jsx("button", { type: "button", onClick: onSignIn, style: {
22
+ padding: "12px 48px",
23
+ borderRadius: radii.full,
24
+ border: "none",
25
+ background: colors.textPrimary,
26
+ color: "#15181D",
27
+ fontSize: 16,
28
+ fontWeight: 500,
29
+ fontFamily: fonts.family,
30
+ cursor: "pointer",
31
+ }, children: "Sign In" }))] }) }));
@@ -0,0 +1,9 @@
1
+ import type { PropsWithChildren, ReactNode } from "react";
2
+ export interface ModalCardProps extends PropsWithChildren {
3
+ title: string;
4
+ subtitle?: string;
5
+ icon?: ReactNode;
6
+ width?: number | string;
7
+ footer?: ReactNode;
8
+ }
9
+ export declare const ModalCard: ({ title, subtitle, icon, width, footer, children }: ModalCardProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { colors, fonts, radii } from "../theme.js";
3
+ export const ModalCard = ({ title, subtitle, icon, width = 420, footer, children }) => {
4
+ return (_jsxs("div", { style: {
5
+ width,
6
+ borderRadius: radii.xl,
7
+ background: colors.card,
8
+ border: `1px solid ${colors.border}`,
9
+ padding: "32px",
10
+ color: colors.textPrimary,
11
+ fontFamily: fonts.family,
12
+ boxShadow: "0 30px 90px rgba(0,0,0,0.55)",
13
+ }, children: [_jsxs("header", { style: { display: "flex", alignItems: "center", gap: 16, marginBottom: 24 }, children: [icon && _jsx("div", { children: icon }), _jsxs("div", { children: [_jsx("div", { style: { fontSize: 22, fontWeight: 600 }, children: title }), subtitle && (_jsx("div", { style: { fontSize: 14, color: colors.textSecondary, marginTop: 4 }, children: subtitle }))] })] }), _jsx("div", { style: { display: "flex", flexDirection: "column", gap: 20 }, children: children }), footer && _jsx("div", { style: { marginTop: 32 }, children: footer })] }));
14
+ };
@@ -0,0 +1,9 @@
1
+ import type { CSSProperties, ReactNode } from "react";
2
+ export interface ModalFrameProps {
3
+ onClose?: () => void;
4
+ width?: number;
5
+ cardStyle?: CSSProperties;
6
+ contentStyle?: CSSProperties;
7
+ children: ReactNode;
8
+ }
9
+ export declare const ModalFrame: ({ onClose, width, cardStyle, contentStyle, children, }: ModalFrameProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CloseButton } from "./CloseButton.js";
3
+ import { colors, fonts, radii } from "../theme.js";
4
+ export const ModalFrame = ({ onClose, width = 500, cardStyle, contentStyle, children, }) => (_jsx("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center" }, children: _jsxs("div", { style: { display: "flex", gap: 14, alignItems: "flex-start" }, children: [_jsx("div", { style: {
5
+ width,
6
+ background: colors.card,
7
+ borderRadius: radii.card,
8
+ overflow: "hidden",
9
+ ...cardStyle,
10
+ }, children: _jsx("div", { style: {
11
+ display: "flex",
12
+ flexDirection: "column",
13
+ minHeight: 0,
14
+ fontFamily: fonts.family,
15
+ color: colors.textPrimary,
16
+ boxSizing: "border-box",
17
+ ...contentStyle,
18
+ }, children: children }) }), _jsx(CloseButton, { onClick: onClose })] }) }));
@@ -0,0 +1,2 @@
1
+ import type { ButtonHTMLAttributes } from "react";
2
+ export declare const PrimaryButton: ({ children, ...rest }: ButtonHTMLAttributes<HTMLButtonElement>) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { colors, fonts, radii } from "../theme.js";
3
+ export const PrimaryButton = ({ children, ...rest }) => (_jsx("button", { ...rest, style: {
4
+ width: "100%",
5
+ padding: "16px 20px",
6
+ borderRadius: radii.md,
7
+ border: "none",
8
+ background: `linear-gradient(135deg, ${colors.accent} 0%, ${colors.accentStrong} 100%)`,
9
+ color: colors.background,
10
+ fontSize: 16,
11
+ fontWeight: 600,
12
+ fontFamily: fonts.family,
13
+ cursor: "pointer",
14
+ }, children: children }));
@@ -0,0 +1,4 @@
1
+ export interface QRCodePanelProps {
2
+ address: string;
3
+ }
4
+ export declare const QRCodePanel: ({ address }: QRCodePanelProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,43 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { colors, fonts, radii } from "../theme.js";
3
+ const generateBlocks = (address) => {
4
+ const chars = Array.from(address.replace(/[^0-9a-f]/gi, ""));
5
+ return chars.map((char, index) => {
6
+ const intensity = (parseInt(char, 16) / 15) * 100;
7
+ return (_jsx("div", { style: {
8
+ width: 10,
9
+ height: 10,
10
+ background: `rgba(255,255,255,${intensity / 140})`,
11
+ } }, `${char}-${index}`));
12
+ });
13
+ };
14
+ export const QRCodePanel = ({ address }) => {
15
+ return (_jsxs("div", { style: {
16
+ borderRadius: radii.lg,
17
+ border: `1px solid ${colors.border}`,
18
+ padding: 20,
19
+ width: 200,
20
+ display: "flex",
21
+ flexDirection: "column",
22
+ alignItems: "center",
23
+ gap: 12,
24
+ background: colors.cardRaised,
25
+ }, children: [_jsx("div", { style: {
26
+ width: 160,
27
+ height: 160,
28
+ borderRadius: radii.sm,
29
+ background: colors.background,
30
+ padding: 12,
31
+ display: "grid",
32
+ gridTemplateColumns: "repeat(12, 10px)",
33
+ gap: 2,
34
+ }, children: generateBlocks(address) }), _jsx("button", { type: "button", style: {
35
+ borderRadius: radii.sm,
36
+ border: `1px solid ${colors.borderStrong}`,
37
+ background: "transparent",
38
+ color: colors.textSecondary,
39
+ padding: "6px 12px",
40
+ cursor: "pointer",
41
+ fontFamily: fonts.family,
42
+ }, onClick: () => navigator.clipboard?.writeText(address), children: "Copy address" })] }));
43
+ };
@@ -0,0 +1,12 @@
1
+ export interface SelectOption {
2
+ label: string;
3
+ value: string;
4
+ badge?: string;
5
+ }
6
+ export interface SelectProps {
7
+ label: string;
8
+ value: string;
9
+ options: SelectOption[];
10
+ onChange?: (value: string) => void;
11
+ }
12
+ export declare const Select: ({ label, value, options, onChange }: SelectProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { colors, fonts, radii } from "../theme.js";
3
+ export const Select = ({ label, value, options, onChange }) => {
4
+ const handleChange = (event) => onChange?.(event.target.value);
5
+ return (_jsxs("label", { style: { display: "flex", flexDirection: "column", gap: 8, fontFamily: fonts.family }, children: [_jsx("span", { style: { fontSize: 14, color: colors.textSecondary }, children: label }), _jsxs("div", { style: {
6
+ position: "relative",
7
+ borderRadius: radii.md,
8
+ background: colors.cardRaised,
9
+ border: `1px solid ${colors.borderStrong}`,
10
+ }, children: [_jsx("select", { value: value, onChange: handleChange, style: {
11
+ width: "100%",
12
+ appearance: "none",
13
+ border: "none",
14
+ outline: "none",
15
+ background: "transparent",
16
+ color: colors.textPrimary,
17
+ fontSize: 16,
18
+ padding: "16px 48px 16px 16px",
19
+ fontFamily: fonts.family,
20
+ }, children: options.map((option) => (_jsxs("option", { value: option.value, style: { color: "black" }, children: [option.label, option.badge ? ` (${option.badge})` : ""] }, option.value))) }), _jsx("span", { style: {
21
+ position: "absolute",
22
+ right: 16,
23
+ top: 0,
24
+ bottom: 0,
25
+ display: "flex",
26
+ alignItems: "center",
27
+ color: colors.textSecondary,
28
+ }, children: "\u25BE" })] })] }));
29
+ };
@@ -0,0 +1,7 @@
1
+ export interface StepIndicatorProps {
2
+ steps: number;
3
+ /** When provided, each dot is highlighted when the corresponding value is true; otherwise uses activeStep (i <= activeStep). */
4
+ stepActive?: boolean[];
5
+ activeStep?: number;
6
+ }
7
+ export declare const StepIndicator: ({ steps, stepActive, activeStep }: StepIndicatorProps) => import("react/jsx-runtime.js").JSX.Element;
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { colors } from "../theme.js";
3
+ export const StepIndicator = ({ steps, stepActive, activeStep = 0 }) => {
4
+ return (_jsx("div", { style: {
5
+ display: "flex",
6
+ flexDirection: "column",
7
+ alignItems: "center",
8
+ width: 20,
9
+ paddingTop: 4,
10
+ flexShrink: 0,
11
+ }, children: Array.from({ length: steps }, (_, i) => {
12
+ const isActive = stepActive && stepActive.length > i ? stepActive[i] : i <= activeStep;
13
+ const isLast = i === steps - 1;
14
+ return (_jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center" }, children: [_jsx("div", { style: {
15
+ width: 20,
16
+ height: 20,
17
+ borderRadius: "50%",
18
+ border: `2px solid ${isActive ? colors.stepActive : colors.stepInactive}`,
19
+ display: "flex",
20
+ alignItems: "center",
21
+ justifyContent: "center",
22
+ boxSizing: "border-box",
23
+ }, children: _jsx("div", { style: {
24
+ width: 7.5,
25
+ height: 7.5,
26
+ borderRadius: "50%",
27
+ background: isActive ? colors.stepActive : colors.stepInactive,
28
+ } }) }), !isLast && (_jsx("div", { style: {
29
+ width: 1,
30
+ height: 87,
31
+ background: isActive ? colors.stepActive : colors.stepInactive,
32
+ opacity: 0.3,
33
+ } }))] }, i));
34
+ }) }));
35
+ };
@@ -0,0 +1 @@
1
+ export declare const SuccessIcon: () => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export const SuccessIcon = () => {
3
+ return (_jsxs("svg", { width: "80", height: "81", viewBox: "0 0 80 81", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("path", { d: "M40 80.5C62.0914 80.5 80 62.5914 80 40.5C80 18.4086 62.0914 0.5 40 0.5C17.9086 0.5 0 18.4086 0 40.5C0 62.5914 17.9086 80.5 40 80.5Z", fill: "#627EEA" }), _jsx("path", { d: "M38.999 16.5V34.2437L53.9962 40.9451L38.999 16.5Z", fill: "white", fillOpacity: "0.602" }), _jsx("path", { d: "M38.9991 16.5L24 40.9451L38.9991 34.2437V16.5Z", fill: "white" }), _jsx("path", { d: "M38.999 52.4434V64.4999L54.0061 43.7376L38.999 52.4434Z", fill: "white", fillOpacity: "0.602" }), _jsx("path", { d: "M38.9991 64.4999V52.4414L24 43.7376L38.9991 64.4999Z", fill: "white" }), _jsx("path", { d: "M38.999 49.653L53.9962 40.9451L38.999 34.2477V49.653Z", fill: "white", fillOpacity: "0.2" }), _jsx("path", { d: "M24 40.9451L38.9991 49.653V34.2477L24 40.9451Z", fill: "white", fillOpacity: "0.602" }), _jsx("g", { filter: "url(#filter0_ii_34_1690)", children: _jsx("circle", { cx: "40", cy: "40", r: "40", fill: "url(#paint0_linear_34_1690)" }) }), _jsx("path", { d: "M25.8057 35.9858L38.7921 49.0324L56.7734 30.9678", stroke: "#58AE36", strokeWidth: "5.16129", fill: "none" }), _jsxs("defs", { children: [_jsxs("filter", { id: "filter0_ii_34_1690", x: "0", y: "0", width: "80", height: "80", filterUnits: "userSpaceOnUse", colorInterpolationFilters: "sRGB", children: [_jsx("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }), _jsx("feBlend", { mode: "normal", in: "SourceGraphic", in2: "BackgroundImageFix", result: "shape" }), _jsx("feColorMatrix", { in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), _jsx("feOffset", { dx: "-1.29032", dy: "-1.29032" }), _jsx("feComposite", { in2: "hardAlpha", operator: "arithmetic", k2: "-1", k3: "1" }), _jsx("feColorMatrix", { type: "matrix", values: "0 0 0 0 0.584745 0 0 0 0 1 0 0 0 0 0.420982 0 0 0 1 0" }), _jsx("feBlend", { mode: "multiply", in2: "shape", result: "effect1_innerShadow_34_1690" }), _jsx("feColorMatrix", { in: "SourceAlpha", type: "matrix", values: "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0", result: "hardAlpha" }), _jsx("feOffset", { dx: "1.29032", dy: "1.29032" }), _jsx("feComposite", { in2: "hardAlpha", operator: "arithmetic", k2: "-1", k3: "1" }), _jsx("feColorMatrix", { type: "matrix", values: "0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0" }), _jsx("feBlend", { mode: "normal", in2: "effect1_innerShadow_34_1690", result: "effect2_innerShadow_34_1690" })] }), _jsxs("linearGradient", { id: "paint0_linear_34_1690", x1: "27.4722", y1: "7.62951", x2: "70.4313", y2: "26.563", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#BBFFA1" }), _jsx("stop", { offset: "1", stopColor: "#ACFE8B" })] })] })] }));
4
+ };
@@ -0,0 +1,8 @@
1
+ export type ToastVariant = "success" | "error" | "info";
2
+ export interface ToastProps {
3
+ message: string;
4
+ variant?: ToastVariant;
5
+ duration?: number;
6
+ onClose?: () => void;
7
+ }
8
+ export declare const Toast: ({ message, variant, duration, onClose }: ToastProps) => import("react/jsx-runtime.js").JSX.Element;