@pollar/react 0.7.0 → 0.7.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.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { PollarApplicationConfigContent, PollarLoginOptions, PollarClientConfig, pollarPaths, PollarAdapters, PollarClient, TransactionState, TxBuildBody, WalletId, StellarNetwork, WalletBalanceState, TxHistoryState, PollarAdapter, KycStatus as KycStatus$1, RampQuote, AuthState, KycProvider, KycStartResponse, RampDirection, PaymentInstructions, WalletBalanceRecord, SessionInfo } from '@pollar/core';
2
+ import { PollarApplicationConfigContent, PollarLoginOptions, PollarClientConfig, pollarPaths, PollarAdapters, PollarClient, TransactionState, TxBuildBody, WalletId, StellarNetwork, WalletBalanceState, TxHistoryState, PollarAdapter, KycStatus as KycStatus$1, RampQuote, AuthState, KycProvider, KycStartResponse, RampDirection, PaymentInstructions, WalletBalanceRecord, SessionInfo, DistributionRulesState, DistributionRule } from '@pollar/core';
3
3
  import { ReactNode } from 'react';
4
4
 
5
5
  type ConfigResponse = pollarPaths['/applications/config']['get']['responses'][200]['content']['application/json'];
@@ -59,6 +59,7 @@ interface PollarContextValue {
59
59
  openWalletBalanceModal: () => void;
60
60
  openSendModal: () => void;
61
61
  openReceiveModal: () => void;
62
+ openDistributionRulesModal: () => void;
62
63
  adapters?: PollarAdapters;
63
64
  }
64
65
  interface PollarProviderProps {
@@ -125,6 +126,11 @@ interface SessionsModalProps {
125
126
  }
126
127
  declare function SessionsModal({ onClose }: SessionsModalProps): react_jsx_runtime.JSX.Element;
127
128
 
129
+ interface DistributionRulesModalProps {
130
+ onClose: () => void;
131
+ }
132
+ declare function DistributionRulesModal({ onClose }: DistributionRulesModalProps): react_jsx_runtime.JSX.Element;
133
+
128
134
  interface LoginModalTemplateProps {
129
135
  theme: string;
130
136
  accentColor: string;
@@ -311,4 +317,17 @@ interface SessionsModalTemplateProps {
311
317
  }
312
318
  declare function SessionsModalTemplate({ theme, accentColor, state, revokingFamilyId, signingOutEverywhere, onRefresh, onRevoke, onLogoutEverywhere, onClose, }: SessionsModalTemplateProps): react_jsx_runtime.JSX.Element;
313
319
 
314
- export { type AuthContextValue, type AuthModalProps, type AuthProviderProps, KycModal, KycModalTemplate, KycStatus, type KycStep, type LoginButtonProps, LoginModalTemplate, type PollarConfig, PollarProvider, type PollarStyles, type RampStep, RampWidget, RampWidgetTemplate, ReceiveModal, ReceiveModalTemplate, type ReceiveModalTemplateProps, RouteDisplay, SendModal, SendModalTemplate, type SendModalTemplateProps, SessionsModal, SessionsModalTemplate, type SessionsModalTemplateProps, type SessionsState, TransactionModalTemplate, type TransactionModalTemplateProps, TxHistoryModalTemplate, TxStatusView, type TxStatusViewProps, WalletBalanceModal, WalletBalanceModalTemplate, type WalletBalanceModalTemplateProps, WalletButton, createPollarAdapterHook, usePollar };
320
+ interface DistributionRulesModalTemplateProps {
321
+ theme: string;
322
+ accentColor: string;
323
+ state: DistributionRulesState;
324
+ claimingId: string | null;
325
+ claimErrors: Record<string, string>;
326
+ claimedIds: Set<string>;
327
+ onRefresh: () => void;
328
+ onClaim: (rule: DistributionRule) => void;
329
+ onClose: () => void;
330
+ }
331
+ declare function DistributionRulesModalTemplate({ theme, accentColor, state, claimingId, claimErrors, claimedIds, onRefresh, onClaim, onClose, }: DistributionRulesModalTemplateProps): react_jsx_runtime.JSX.Element;
332
+
333
+ export { type AuthContextValue, type AuthModalProps, type AuthProviderProps, DistributionRulesModal, DistributionRulesModalTemplate, KycModal, KycModalTemplate, KycStatus, type KycStep, type LoginButtonProps, LoginModalTemplate, type PollarConfig, PollarProvider, type PollarStyles, type RampStep, RampWidget, RampWidgetTemplate, ReceiveModal, ReceiveModalTemplate, type ReceiveModalTemplateProps, RouteDisplay, SendModal, SendModalTemplate, type SendModalTemplateProps, SessionsModal, SessionsModalTemplate, type SessionsModalTemplateProps, type SessionsState, TransactionModalTemplate, type TransactionModalTemplateProps, TxHistoryModalTemplate, TxStatusView, type TxStatusViewProps, WalletBalanceModal, WalletBalanceModalTemplate, type WalletBalanceModalTemplateProps, WalletButton, createPollarAdapterHook, usePollar };
package/dist/index.js CHANGED
@@ -1030,7 +1030,7 @@ var PollarModalFooter = () => {
1030
1030
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
1031
1031
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-footer-version", children: [
1032
1032
  "v",
1033
- "0.7.0"
1033
+ "0.7.1"
1034
1034
  ] })
1035
1035
  ] })
1036
1036
  ] });
@@ -1054,6 +1054,221 @@ function ModalStatusBanner({ message, status, onCancel, onRetry }) {
1054
1054
  status === "ERROR" && onRetry && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-status-cancel", onClick: onRetry, children: "Retry" })
1055
1055
  ] });
1056
1056
  }
1057
+ var PERIOD_LABEL = {
1058
+ DAY: "every 24h",
1059
+ DAY_CALENDAR: "daily",
1060
+ WEEK: "every 7 days",
1061
+ MONTH: "every 30 days",
1062
+ MONTH_CALENDAR: "monthly",
1063
+ LIFETIME: "one-time"
1064
+ };
1065
+ var REASON_LABEL = {
1066
+ DISTRIBUTION_RULE_DISABLED: "Disabled",
1067
+ DISTRIBUTION_RULE_NOT_STARTED: "Not started yet",
1068
+ DISTRIBUTION_RULE_EXPIRED: "Expired",
1069
+ DISTRIBUTION_RULE_EXHAUSTED: "Fully claimed",
1070
+ DISTRIBUTION_RATE_LIMIT_EXCEEDED: "Already claimed"
1071
+ };
1072
+ function reasonLabel(reason) {
1073
+ if (!reason) return "Not available";
1074
+ return REASON_LABEL[reason] ?? "Not available";
1075
+ }
1076
+ function formatAmount(amount) {
1077
+ const n = parseFloat(amount);
1078
+ return isNaN(n) ? amount : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
1079
+ }
1080
+ function formatValidity(rule) {
1081
+ const from = rule.validFrom ? new Date(rule.validFrom) : null;
1082
+ const until = rule.validUntil ? new Date(rule.validUntil) : null;
1083
+ if (!from && !until) return null;
1084
+ const fmt = (d) => d.toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" });
1085
+ if (from && until) return `${fmt(from)} \u2192 ${fmt(until)}`;
1086
+ if (until) return `Until ${fmt(until)}`;
1087
+ if (from) return `From ${fmt(from)}`;
1088
+ return null;
1089
+ }
1090
+ function RuleCard({
1091
+ rule,
1092
+ isClaiming,
1093
+ isClaimed,
1094
+ errorMessage,
1095
+ onClaim
1096
+ }) {
1097
+ const validity = formatValidity(rule);
1098
+ const effectivelyClaimable = rule.claimable && !isClaimed;
1099
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-item", "data-claimable": effectivelyClaimable ? "true" : "false", children: [
1100
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-item-row", children: [
1101
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-name", children: rule.name }),
1102
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "pollar-dist-item-amount", children: [
1103
+ formatAmount(rule.amount),
1104
+ " ",
1105
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-asset", children: rule.assetCode })
1106
+ ] })
1107
+ ] }),
1108
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-item-meta", children: [
1109
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: PERIOD_LABEL[rule.period] }),
1110
+ validity && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1111
+ "\xB7 ",
1112
+ validity
1113
+ ] })
1114
+ ] }),
1115
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-action", children: isClaimed ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "claimed", children: "Claimed" }) : effectivelyClaimable ? /* @__PURE__ */ jsxRuntime.jsx(
1116
+ "button",
1117
+ {
1118
+ type: "button",
1119
+ className: "pollar-btn-primary pollar-dist-claim-btn",
1120
+ onClick: onClaim,
1121
+ disabled: isClaiming,
1122
+ children: isClaiming ? "Claiming\u2026" : "Claim"
1123
+ }
1124
+ ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-dist-item-status", "data-kind": "unavailable", children: reasonLabel(rule.reason) }) }),
1125
+ errorMessage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-dist-item-error", children: errorMessage })
1126
+ ] });
1127
+ }
1128
+ function DistributionRulesModalTemplate({
1129
+ theme,
1130
+ accentColor,
1131
+ state,
1132
+ claimingId,
1133
+ claimErrors,
1134
+ claimedIds,
1135
+ onRefresh,
1136
+ onClaim,
1137
+ onClose
1138
+ }) {
1139
+ const isDark = theme === "dark";
1140
+ const cssVars = {
1141
+ "--pollar-accent": accentColor,
1142
+ "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
1143
+ "--pollar-border": isDark ? "#374151" : "#e5e7eb",
1144
+ "--pollar-text": isDark ? "#ffffff" : "#111827",
1145
+ "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
1146
+ "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
1147
+ "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
1148
+ "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
1149
+ "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
1150
+ "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
1151
+ "--pollar-buttons-border-radius": "6px",
1152
+ "--pollar-buttons-height": "44px",
1153
+ "--pollar-input-height": "44px",
1154
+ "--pollar-input-border-radius": "0.5rem",
1155
+ "--pollar-card-border-radius": "10px"
1156
+ };
1157
+ const isLoading = state.step === "loading";
1158
+ const rules = state.step === "loaded" ? state.rules : [];
1159
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1160
+ "div",
1161
+ {
1162
+ className: "pollar-modal-card pollar-dist-modal",
1163
+ "data-theme": theme,
1164
+ style: cssVars,
1165
+ onClick: (e) => e.stopPropagation(),
1166
+ children: [
1167
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
1168
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Distribution Rules" }),
1169
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header-actions", children: [
1170
+ /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
1171
+ /* @__PURE__ */ jsxRuntime.jsxs(
1172
+ "svg",
1173
+ {
1174
+ className: `pollar-modal-refresh-icon${isLoading ? " spinning" : ""}`,
1175
+ width: "13",
1176
+ height: "13",
1177
+ viewBox: "0 0 13 13",
1178
+ fill: "none",
1179
+ "aria-hidden": true,
1180
+ children: [
1181
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M11.5 6.5a5 5 0 11-1.5-3.536", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }),
1182
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10 1v3h-3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
1183
+ ]
1184
+ }
1185
+ ),
1186
+ "Refresh"
1187
+ ] }),
1188
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
1189
+ ] })
1190
+ ] }),
1191
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-dist-list", children: [
1192
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
1193
+ state.step === "error" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-error", children: state.message }),
1194
+ state.step === "loaded" && rules.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No distribution rules available." }),
1195
+ rules.map((rule) => /* @__PURE__ */ jsxRuntime.jsx(
1196
+ RuleCard,
1197
+ {
1198
+ rule,
1199
+ isClaiming: claimingId === rule.id,
1200
+ isClaimed: claimedIds.has(rule.id),
1201
+ ...claimErrors[rule.id] && { errorMessage: claimErrors[rule.id] },
1202
+ onClaim: () => onClaim(rule)
1203
+ },
1204
+ rule.id
1205
+ ))
1206
+ ] }),
1207
+ /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
1208
+ ]
1209
+ }
1210
+ );
1211
+ }
1212
+ function DistributionRulesModal({ onClose }) {
1213
+ const { getClient, styles } = usePollar();
1214
+ const { theme = "light", accentColor = "#005DB4" } = styles;
1215
+ const [state, setState] = react.useState({ step: "idle" });
1216
+ const [claimingId, setClaimingId] = react.useState(null);
1217
+ const [claimErrors, setClaimErrors] = react.useState({});
1218
+ const [claimedIds, setClaimedIds] = react.useState(() => /* @__PURE__ */ new Set());
1219
+ const load = react.useCallback(async () => {
1220
+ setState({ step: "loading" });
1221
+ try {
1222
+ const rules = await getClient().listDistributionRules();
1223
+ setState({ step: "loaded", rules });
1224
+ } catch (err) {
1225
+ const message = err instanceof Error ? err.message : "Failed to load distribution rules";
1226
+ setState({ step: "error", message });
1227
+ }
1228
+ }, [getClient]);
1229
+ react.useEffect(() => {
1230
+ void load();
1231
+ }, [load]);
1232
+ const handleClaim = react.useCallback(
1233
+ async (rule) => {
1234
+ setClaimingId(rule.id);
1235
+ setClaimErrors((prev) => {
1236
+ if (!prev[rule.id]) return prev;
1237
+ const next = { ...prev };
1238
+ delete next[rule.id];
1239
+ return next;
1240
+ });
1241
+ try {
1242
+ await getClient().claimDistributionRule({ ruleId: rule.id });
1243
+ setClaimedIds((prev) => {
1244
+ const next = new Set(prev);
1245
+ next.add(rule.id);
1246
+ return next;
1247
+ });
1248
+ } catch (err) {
1249
+ const message = err instanceof Error ? err.message : "Claim failed";
1250
+ setClaimErrors((prev) => ({ ...prev, [rule.id]: message }));
1251
+ } finally {
1252
+ setClaimingId(null);
1253
+ }
1254
+ },
1255
+ [getClient]
1256
+ );
1257
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
1258
+ DistributionRulesModalTemplate,
1259
+ {
1260
+ theme,
1261
+ accentColor,
1262
+ state,
1263
+ claimingId,
1264
+ claimErrors,
1265
+ claimedIds,
1266
+ onRefresh: () => void load(),
1267
+ onClaim: handleClaim,
1268
+ onClose
1269
+ }
1270
+ ) });
1271
+ }
1057
1272
  var STATUS_CONFIG = {
1058
1273
  none: { label: "Not started", color: "#6b7280", dot: false },
1059
1274
  pending: { label: "Pending review", color: "#f59e0b", dot: true },
@@ -1577,166 +1792,6 @@ function LoginModal({ onClose }) {
1577
1792
  }
1578
1793
  ) });
1579
1794
  }
1580
-
1581
- // src/lib/qr-code/index.tsx
1582
- var import_ErrorCorrectLevel = __toESM(require_ErrorCorrectLevel());
1583
- var import_QRCode = __toESM(require_QRCode());
1584
- var QRCodeSvg = react.forwardRef(function QRCodeSvg2({
1585
- bgColor,
1586
- bgD,
1587
- fgD,
1588
- fgColor,
1589
- size,
1590
- title,
1591
- viewBoxSize,
1592
- xmlns = "http://www.w3.org/2000/svg",
1593
- ...props
1594
- }, ref) {
1595
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, height: size, ref, viewBox: `0 0 ${viewBoxSize} ${viewBoxSize}`, width: size, xmlns, children: [
1596
- title ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: title }) : null,
1597
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: bgD, fill: bgColor }),
1598
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: fgD, fill: fgColor })
1599
- ] });
1600
- });
1601
- QRCodeSvg.displayName = "QRCodeSvg";
1602
- function bytesToBinaryString(bytes) {
1603
- return bytes.map((b) => String.fromCharCode(b & 255)).join("");
1604
- }
1605
- function encodeStringToUtf8Bytes(input) {
1606
- return Array.from(new TextEncoder().encode(input));
1607
- }
1608
- var QRCode = react.forwardRef(function QRCode2({ bgColor = "#FFFFFF", fgColor = "#000000", level = "L", size = 256, value, ...props }, ref) {
1609
- const qrcode = new import_QRCode.default(-1, import_ErrorCorrectLevel.default[level]);
1610
- const utf8Bytes = encodeStringToUtf8Bytes(value);
1611
- const binaryString = bytesToBinaryString(utf8Bytes);
1612
- qrcode.addData(binaryString, "Byte");
1613
- qrcode.make();
1614
- const cells = qrcode.modules;
1615
- return /* @__PURE__ */ jsxRuntime.jsx(
1616
- QRCodeSvg,
1617
- {
1618
- ...props,
1619
- bgColor,
1620
- bgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => !cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
1621
- fgColor,
1622
- fgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
1623
- ref,
1624
- size,
1625
- viewBoxSize: cells.length
1626
- }
1627
- );
1628
- });
1629
- function ReceiveModalTemplate({
1630
- theme,
1631
- accentColor,
1632
- walletAddress,
1633
- copied,
1634
- onCopy,
1635
- onClose
1636
- }) {
1637
- const isDark = theme === "dark";
1638
- const cssVars = {
1639
- "--pollar-accent": accentColor,
1640
- "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
1641
- "--pollar-border": isDark ? "#374151" : "#e5e7eb",
1642
- "--pollar-text": isDark ? "#ffffff" : "#111827",
1643
- "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
1644
- "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
1645
- "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
1646
- "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
1647
- "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
1648
- "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
1649
- "--pollar-buttons-border-radius": "6px",
1650
- "--pollar-buttons-height": "44px",
1651
- "--pollar-input-height": "44px",
1652
- "--pollar-input-border-radius": "0.5rem",
1653
- "--pollar-card-border-radius": "10px"
1654
- };
1655
- return /* @__PURE__ */ jsxRuntime.jsxs(
1656
- "div",
1657
- {
1658
- className: "pollar-modal-card pollar-receive-modal",
1659
- "data-theme": theme,
1660
- style: cssVars,
1661
- onClick: (e) => e.stopPropagation(),
1662
- children: [
1663
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
1664
- /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Receive" }),
1665
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) }) })
1666
- ] }),
1667
- walletAddress ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1668
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsxRuntime.jsx(
1669
- QRCode,
1670
- {
1671
- value: walletAddress,
1672
- size: 180,
1673
- fgColor: isDark ? "#ffffff" : "#111827",
1674
- bgColor: "transparent"
1675
- }
1676
- ) }),
1677
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-receive-instructions", children: "Share your Stellar address to receive any asset. Only send Stellar assets to this address." }),
1678
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-receive-address-row", children: [
1679
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-receive-address", children: walletAddress }),
1680
- /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-receive-copy-btn", onClick: onCopy, "aria-label": "Copy address", children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1681
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
1682
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
1683
- /* @__PURE__ */ jsxRuntime.jsx(
1684
- "path",
1685
- {
1686
- d: "M3.5 7l2.5 2.5 4.5-5",
1687
- stroke: "white",
1688
- strokeWidth: "1.5",
1689
- strokeLinecap: "round",
1690
- strokeLinejoin: "round"
1691
- }
1692
- )
1693
- ] }),
1694
- "Copied!"
1695
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1696
- /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
1697
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
1698
- /* @__PURE__ */ jsxRuntime.jsx(
1699
- "path",
1700
- {
1701
- d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
1702
- stroke: "currentColor",
1703
- strokeWidth: "1.5",
1704
- strokeLinecap: "round"
1705
- }
1706
- )
1707
- ] }),
1708
- "Copy address"
1709
- ] }) })
1710
- ] })
1711
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No wallet connected." }),
1712
- /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
1713
- ]
1714
- }
1715
- );
1716
- }
1717
- function ReceiveModal({ onClose }) {
1718
- const { walletAddress, styles } = usePollar();
1719
- const { theme = "light", accentColor = "#005DB4" } = styles;
1720
- const [copied, setCopied] = react.useState(false);
1721
- function handleCopy() {
1722
- if (!walletAddress) return;
1723
- navigator.clipboard.writeText(walletAddress).then(() => {
1724
- setCopied(true);
1725
- setTimeout(() => setCopied(false), 2e3);
1726
- });
1727
- }
1728
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
1729
- ReceiveModalTemplate,
1730
- {
1731
- theme,
1732
- accentColor,
1733
- walletAddress,
1734
- copied,
1735
- onCopy: handleCopy,
1736
- onClose
1737
- }
1738
- ) });
1739
- }
1740
1795
  var RAIL_LABELS = {
1741
1796
  SPEI: "SPEI (Mexico)",
1742
1797
  PIX: "PIX (Brazil)",
@@ -2051,6 +2106,166 @@ function RampWidget({ onClose }) {
2051
2106
  }
2052
2107
  ) });
2053
2108
  }
2109
+
2110
+ // src/lib/qr-code/index.tsx
2111
+ var import_ErrorCorrectLevel = __toESM(require_ErrorCorrectLevel());
2112
+ var import_QRCode = __toESM(require_QRCode());
2113
+ var QRCodeSvg = react.forwardRef(function QRCodeSvg2({
2114
+ bgColor,
2115
+ bgD,
2116
+ fgD,
2117
+ fgColor,
2118
+ size,
2119
+ title,
2120
+ viewBoxSize,
2121
+ xmlns = "http://www.w3.org/2000/svg",
2122
+ ...props
2123
+ }, ref) {
2124
+ return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, height: size, ref, viewBox: `0 0 ${viewBoxSize} ${viewBoxSize}`, width: size, xmlns, children: [
2125
+ title ? /* @__PURE__ */ jsxRuntime.jsx("title", { children: title }) : null,
2126
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: bgD, fill: bgColor }),
2127
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: fgD, fill: fgColor })
2128
+ ] });
2129
+ });
2130
+ QRCodeSvg.displayName = "QRCodeSvg";
2131
+ function bytesToBinaryString(bytes) {
2132
+ return bytes.map((b) => String.fromCharCode(b & 255)).join("");
2133
+ }
2134
+ function encodeStringToUtf8Bytes(input) {
2135
+ return Array.from(new TextEncoder().encode(input));
2136
+ }
2137
+ var QRCode = react.forwardRef(function QRCode2({ bgColor = "#FFFFFF", fgColor = "#000000", level = "L", size = 256, value, ...props }, ref) {
2138
+ const qrcode = new import_QRCode.default(-1, import_ErrorCorrectLevel.default[level]);
2139
+ const utf8Bytes = encodeStringToUtf8Bytes(value);
2140
+ const binaryString = bytesToBinaryString(utf8Bytes);
2141
+ qrcode.addData(binaryString, "Byte");
2142
+ qrcode.make();
2143
+ const cells = qrcode.modules;
2144
+ return /* @__PURE__ */ jsxRuntime.jsx(
2145
+ QRCodeSvg,
2146
+ {
2147
+ ...props,
2148
+ bgColor,
2149
+ bgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => !cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
2150
+ fgColor,
2151
+ fgD: cells.map((row, rowIndex) => row.map((cell, cellIndex) => cell ? `M ${cellIndex} ${rowIndex} l 1 0 0 1 -1 0 Z` : "").join(" ")).join(" "),
2152
+ ref,
2153
+ size,
2154
+ viewBoxSize: cells.length
2155
+ }
2156
+ );
2157
+ });
2158
+ function ReceiveModalTemplate({
2159
+ theme,
2160
+ accentColor,
2161
+ walletAddress,
2162
+ copied,
2163
+ onCopy,
2164
+ onClose
2165
+ }) {
2166
+ const isDark = theme === "dark";
2167
+ const cssVars = {
2168
+ "--pollar-accent": accentColor,
2169
+ "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
2170
+ "--pollar-border": isDark ? "#374151" : "#e5e7eb",
2171
+ "--pollar-text": isDark ? "#ffffff" : "#111827",
2172
+ "--pollar-muted": isDark ? "#9ca3af" : "#6b7280",
2173
+ "--pollar-input-bg": isDark ? "#374151" : "#f9fafb",
2174
+ "--pollar-error-bg": isDark ? "#2a1515" : "#fef2f2",
2175
+ "--pollar-error-border": isDark ? "#7f1d1d" : "#fecaca",
2176
+ "--pollar-error-text": isDark ? "#f87171" : "#dc2626",
2177
+ "--pollar-success-text": isDark ? "#4ade80" : "#16a34a",
2178
+ "--pollar-buttons-border-radius": "6px",
2179
+ "--pollar-buttons-height": "44px",
2180
+ "--pollar-input-height": "44px",
2181
+ "--pollar-input-border-radius": "0.5rem",
2182
+ "--pollar-card-border-radius": "10px"
2183
+ };
2184
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2185
+ "div",
2186
+ {
2187
+ className: "pollar-modal-card pollar-receive-modal",
2188
+ "data-theme": theme,
2189
+ style: cssVars,
2190
+ onClick: (e) => e.stopPropagation(),
2191
+ children: [
2192
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-modal-header", children: [
2193
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "pollar-modal-title", children: "Receive" }),
2194
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-header-actions", children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) }) })
2195
+ ] }),
2196
+ walletAddress ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2197
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-receive-qr", children: /* @__PURE__ */ jsxRuntime.jsx(
2198
+ QRCode,
2199
+ {
2200
+ value: walletAddress,
2201
+ size: 180,
2202
+ fgColor: isDark ? "#ffffff" : "#111827",
2203
+ bgColor: "transparent"
2204
+ }
2205
+ ) }),
2206
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "pollar-receive-instructions", children: "Share your Stellar address to receive any asset. Only send Stellar assets to this address." }),
2207
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pollar-receive-address-row", children: [
2208
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pollar-receive-address", children: walletAddress }),
2209
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "pollar-receive-copy-btn", onClick: onCopy, "aria-label": "Copy address", children: copied ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2210
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 14 14", fill: "none", "aria-hidden": true, children: [
2211
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "7", cy: "7", r: "7", fill: "currentColor" }),
2212
+ /* @__PURE__ */ jsxRuntime.jsx(
2213
+ "path",
2214
+ {
2215
+ d: "M3.5 7l2.5 2.5 4.5-5",
2216
+ stroke: "white",
2217
+ strokeWidth: "1.5",
2218
+ strokeLinecap: "round",
2219
+ strokeLinejoin: "round"
2220
+ }
2221
+ )
2222
+ ] }),
2223
+ "Copied!"
2224
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2225
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 13 13", fill: "none", "aria-hidden": true, children: [
2226
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: "currentColor", strokeWidth: "1.5" }),
2227
+ /* @__PURE__ */ jsxRuntime.jsx(
2228
+ "path",
2229
+ {
2230
+ d: "M3 9H2a1 1 0 01-1-1V2a1 1 0 011-1h6a1 1 0 011 1v1",
2231
+ stroke: "currentColor",
2232
+ strokeWidth: "1.5",
2233
+ strokeLinecap: "round"
2234
+ }
2235
+ )
2236
+ ] }),
2237
+ "Copy address"
2238
+ ] }) })
2239
+ ] })
2240
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-modal-empty", children: "No wallet connected." }),
2241
+ /* @__PURE__ */ jsxRuntime.jsx(PollarModalFooter, {})
2242
+ ]
2243
+ }
2244
+ );
2245
+ }
2246
+ function ReceiveModal({ onClose }) {
2247
+ const { walletAddress, styles } = usePollar();
2248
+ const { theme = "light", accentColor = "#005DB4" } = styles;
2249
+ const [copied, setCopied] = react.useState(false);
2250
+ function handleCopy() {
2251
+ if (!walletAddress) return;
2252
+ navigator.clipboard.writeText(walletAddress).then(() => {
2253
+ setCopied(true);
2254
+ setTimeout(() => setCopied(false), 2e3);
2255
+ });
2256
+ }
2257
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsx(
2258
+ ReceiveModalTemplate,
2259
+ {
2260
+ theme,
2261
+ accentColor,
2262
+ walletAddress,
2263
+ copied,
2264
+ onCopy: handleCopy,
2265
+ onClose
2266
+ }
2267
+ ) });
2268
+ }
2054
2269
  var STATUS_MESSAGES = {
2055
2270
  idle: "",
2056
2271
  building: "Building transaction\u2026",
@@ -3191,6 +3406,7 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3191
3406
  const [sendModalOpen, setSendModalOpen] = react.useState(false);
3192
3407
  const [receiveModalOpen, setReceiveModalOpen] = react.useState(false);
3193
3408
  const [sessionsModalOpen, setSessionsModalOpen] = react.useState(false);
3409
+ const [distributionRulesModalOpen, setDistributionRulesModalOpen] = react.useState(false);
3194
3410
  const adaptersRef = react.useRef(adapters);
3195
3411
  adaptersRef.current = adapters;
3196
3412
  const walletAddress = sessionState?.wallet?.publicKey || "";
@@ -3225,6 +3441,8 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3225
3441
  openReceiveModal: () => setReceiveModalOpen(true),
3226
3442
  // sessions
3227
3443
  openSessionsModal: () => setSessionsModalOpen(true),
3444
+ // distribution
3445
+ openDistributionRulesModal: () => setDistributionRulesModalOpen(true),
3228
3446
  // network
3229
3447
  network: networkState.step === "connected" ? networkState.network : "testnet",
3230
3448
  setNetwork: (network) => pollarClient.setNetwork(network),
@@ -3240,7 +3458,18 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3240
3458
  styles,
3241
3459
  adapters: adaptersRef.current
3242
3460
  }),
3243
- [walletAddress, pollarClient, getClient, transaction, txHistory, walletBalance, refreshWalletBalance, networkState, remoteConfig, styles]
3461
+ [
3462
+ walletAddress,
3463
+ pollarClient,
3464
+ getClient,
3465
+ transaction,
3466
+ txHistory,
3467
+ walletBalance,
3468
+ refreshWalletBalance,
3469
+ networkState,
3470
+ remoteConfig,
3471
+ styles
3472
+ ]
3244
3473
  );
3245
3474
  return /* @__PURE__ */ jsxRuntime.jsxs(PollarContext.Provider, { value: contextValue, children: [
3246
3475
  children,
@@ -3260,7 +3489,8 @@ function PollarProvider({ config, styles: propStyles, adapters, children }) {
3260
3489
  walletBalanceModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setWalletBalanceModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(WalletBalanceModal, { onClose: () => setWalletBalanceModalOpen(false) }) }),
3261
3490
  sendModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSendModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SendModal, { onClose: () => setSendModalOpen(false) }) }),
3262
3491
  receiveModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) }),
3263
- sessionsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) })
3492
+ sessionsModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) }),
3493
+ distributionRulesModalOpen && /* @__PURE__ */ jsxRuntime.jsx(ModalErrorBoundary, { onClose: () => setDistributionRulesModalOpen(false), children: /* @__PURE__ */ jsxRuntime.jsx(DistributionRulesModal, { onClose: () => setDistributionRulesModalOpen(false) }) })
3264
3494
  ] });
3265
3495
  }
3266
3496
  function usePollar() {
@@ -3511,6 +3741,8 @@ function WalletButton() {
3511
3741
  );
3512
3742
  }
3513
3743
 
3744
+ exports.DistributionRulesModal = DistributionRulesModal;
3745
+ exports.DistributionRulesModalTemplate = DistributionRulesModalTemplate;
3514
3746
  exports.KycModal = KycModal;
3515
3747
  exports.KycModalTemplate = KycModalTemplate;
3516
3748
  exports.KycStatus = KycStatus;