@pollar/react 0.9.0-rc.2 → 0.9.0-rc.3

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.mjs CHANGED
@@ -1033,7 +1033,7 @@ var PollarModalFooter = () => {
1033
1033
  /* @__PURE__ */ jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
1034
1034
  /* @__PURE__ */ jsxs("span", { className: "pollar-footer-version", children: [
1035
1035
  "v",
1036
- "0.9.0-rc.2"
1036
+ "0.9.0-rc.3"
1037
1037
  ] })
1038
1038
  ] })
1039
1039
  ] });
@@ -1268,26 +1268,9 @@ function cropAddress(address) {
1268
1268
  if (address.length <= 16) return address;
1269
1269
  return `${address.slice(0, 8)}...${address.slice(-8)}`;
1270
1270
  }
1271
- function AssetItem({ record }) {
1272
- const established = record.trustlineEstablished;
1273
- return /* @__PURE__ */ jsxs("div", { className: "pollar-asset-item", children: [
1274
- /* @__PURE__ */ jsxs("div", { className: "pollar-asset-info", children: [
1275
- /* @__PURE__ */ jsx("span", { className: "pollar-asset-code", children: record.code }),
1276
- record.name && /* @__PURE__ */ jsx("span", { className: "pollar-asset-name", children: record.name })
1277
- ] }),
1278
- /* @__PURE__ */ jsx("span", { className: `pollar-asset-trustline${established ? " established" : ""}`, children: established ? "Trustline active" : "Needs trustline" })
1279
- ] });
1280
- }
1281
- function EnabledAssetsModalTemplate({
1282
- theme,
1283
- accentColor,
1284
- enabledAssets,
1285
- walletAddress,
1286
- onRefresh,
1287
- onClose
1288
- }) {
1271
+ function cssVarsFor(theme, accentColor) {
1289
1272
  const isDark = theme === "dark";
1290
- const cssVars = {
1273
+ return {
1291
1274
  "--pollar-accent": accentColor,
1292
1275
  "--pollar-bg": isDark ? "#1a1a1a" : "#ffffff",
1293
1276
  "--pollar-border": isDark ? "#374151" : "#e5e7eb",
@@ -1304,13 +1287,62 @@ function EnabledAssetsModalTemplate({
1304
1287
  "--pollar-input-border-radius": "0.5rem",
1305
1288
  "--pollar-card-border-radius": "10px"
1306
1289
  };
1290
+ }
1291
+ function assetKey(record) {
1292
+ return record.code + (record.issuer ?? "");
1293
+ }
1294
+ function AssetItem({
1295
+ record,
1296
+ busy,
1297
+ disabled,
1298
+ onToggle
1299
+ }) {
1300
+ const established = record.trustlineEstablished;
1301
+ const isNative = record.type === "native";
1302
+ return /* @__PURE__ */ jsxs("div", { className: "pollar-asset-item", children: [
1303
+ /* @__PURE__ */ jsxs("div", { className: "pollar-asset-info", children: [
1304
+ /* @__PURE__ */ jsxs("div", { className: "pollar-asset-code-row", children: [
1305
+ /* @__PURE__ */ jsx("span", { className: "pollar-asset-code", children: record.code }),
1306
+ record.enabledInApp && /* @__PURE__ */ jsx("span", { className: "pollar-asset-tag", children: "App" })
1307
+ ] }),
1308
+ record.name && /* @__PURE__ */ jsx("span", { className: "pollar-asset-name", children: record.name }),
1309
+ !isNative && record.enabledInApp && /* @__PURE__ */ jsx("span", { className: "pollar-asset-sponsor", children: record.sponsored ? "Reserve sponsored by the app" : "You pay the reserve (~0.5 XLM)" })
1310
+ ] }),
1311
+ /* @__PURE__ */ jsxs("div", { className: "pollar-asset-actions", children: [
1312
+ /* @__PURE__ */ jsx("span", { className: `pollar-asset-trustline${established ? " established" : ""}`, children: established ? "Trustline active" : "Needs trustline" }),
1313
+ !isNative && /* @__PURE__ */ jsx(
1314
+ "button",
1315
+ {
1316
+ className: `pollar-asset-btn${established ? " danger" : ""}`,
1317
+ onClick: () => onToggle(record),
1318
+ disabled: busy || disabled,
1319
+ children: busy ? "\u2026" : established ? "Disable" : "Enable"
1320
+ }
1321
+ )
1322
+ ] })
1323
+ ] });
1324
+ }
1325
+ function EnabledAssetsModalTemplate({
1326
+ theme,
1327
+ accentColor,
1328
+ enabledAssets,
1329
+ walletAddress,
1330
+ busyKey,
1331
+ actionError,
1332
+ onRefresh,
1333
+ onClose,
1334
+ onToggleTrustline,
1335
+ onAddCustom
1336
+ }) {
1337
+ const cssVars = cssVarsFor(theme, accentColor);
1307
1338
  const isLoading = enabledAssets.step === "loading";
1308
1339
  const data = enabledAssets.step === "loaded" ? enabledAssets.data : null;
1340
+ const busy = busyKey !== null;
1309
1341
  return /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-asset-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
1310
1342
  /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
1311
- /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: "Enabled Assets" }),
1343
+ /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: "Trustlines" }),
1312
1344
  /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
1313
- /* @__PURE__ */ jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading, children: [
1345
+ /* @__PURE__ */ jsxs("button", { className: "pollar-modal-refresh-btn", onClick: onRefresh, disabled: isLoading || busy, children: [
1314
1346
  /* @__PURE__ */ jsxs(
1315
1347
  "svg",
1316
1348
  {
@@ -1334,31 +1366,199 @@ function EnabledAssetsModalTemplate({
1334
1366
  walletAddress && /* @__PURE__ */ jsx("div", { className: "pollar-asset-address", children: cropAddress(walletAddress) }),
1335
1367
  isLoading && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "Loading\u2026" }),
1336
1368
  enabledAssets.step === "error" && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: enabledAssets.message }),
1369
+ actionError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-action-error", children: actionError }),
1337
1370
  data && !data.exists && /* @__PURE__ */ jsxs("div", { className: "pollar-modal-empty", children: [
1338
1371
  "Account not found on ",
1339
1372
  data.network,
1340
1373
  "."
1341
1374
  ] }),
1342
- data && data.assets.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "No assets enabled for this application." }),
1343
- data && data.assets.length > 0 && /* @__PURE__ */ jsx("div", { className: "pollar-asset-list", children: data.assets.map((a) => /* @__PURE__ */ jsx(AssetItem, { record: a }, a.code + (a.issuer ?? ""))) }),
1375
+ data && data.assets.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-empty", children: "No trustlines found." }),
1376
+ data && data.assets.length > 0 && /* @__PURE__ */ jsx("div", { className: "pollar-asset-list", children: data.assets.map((a) => /* @__PURE__ */ jsx(
1377
+ AssetItem,
1378
+ {
1379
+ record: a,
1380
+ busy: busyKey === assetKey(a),
1381
+ disabled: busy && busyKey !== assetKey(a),
1382
+ onToggle: onToggleTrustline
1383
+ },
1384
+ assetKey(a)
1385
+ )) }),
1386
+ /* @__PURE__ */ jsx("button", { className: "pollar-asset-add-custom", onClick: onAddCustom, disabled: busy, children: "+ Add custom trustline" }),
1387
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
1388
+ ] });
1389
+ }
1390
+ function isValidIssuer(issuer) {
1391
+ return issuer.length === 56 && issuer.startsWith("G");
1392
+ }
1393
+ function CustomTrustlineModalTemplate({
1394
+ theme,
1395
+ accentColor,
1396
+ busy,
1397
+ actionError,
1398
+ onBack,
1399
+ onClose,
1400
+ onSubmit
1401
+ }) {
1402
+ const cssVars = cssVarsFor(theme, accentColor);
1403
+ const [code, setCode] = useState("");
1404
+ const [issuer, setIssuer] = useState("");
1405
+ const [limit, setLimit] = useState("");
1406
+ const codeOk = code.trim().length >= 1 && code.trim().length <= 12;
1407
+ const issuerOk = isValidIssuer(issuer.trim());
1408
+ const canSubmit = codeOk && issuerOk && !busy;
1409
+ const submit = () => {
1410
+ if (!canSubmit) return;
1411
+ const trimmedLimit = limit.trim();
1412
+ onSubmit({ code: code.trim(), issuer: issuer.trim(), ...trimmedLimit ? { limit: trimmedLimit } : {} });
1413
+ };
1414
+ return /* @__PURE__ */ jsxs("div", { className: "pollar-modal-card pollar-asset-modal", "data-theme": theme, style: cssVars, onClick: (e) => e.stopPropagation(), children: [
1415
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
1416
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
1417
+ /* @__PURE__ */ jsx("button", { className: "pollar-modal-back", onClick: onBack, disabled: busy, "aria-label": "Back", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
1418
+ /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: "Add custom trustline" })
1419
+ ] }),
1420
+ /* @__PURE__ */ jsx("button", { className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
1421
+ ] }),
1422
+ /* @__PURE__ */ jsx("p", { className: "pollar-asset-custom-hint", children: "Custom trustlines aren't sponsored \u2014 your wallet pays the 0.5 XLM reserve and the transaction fee." }),
1423
+ /* @__PURE__ */ jsxs("div", { className: "pollar-field", children: [
1424
+ /* @__PURE__ */ jsx("label", { className: "pollar-label", htmlFor: "pollar-trustline-code", children: "Asset code" }),
1425
+ /* @__PURE__ */ jsx(
1426
+ "input",
1427
+ {
1428
+ id: "pollar-trustline-code",
1429
+ className: "pollar-input",
1430
+ value: code,
1431
+ onChange: (e) => setCode(e.target.value),
1432
+ placeholder: "USDC",
1433
+ maxLength: 12,
1434
+ autoComplete: "off",
1435
+ spellCheck: false,
1436
+ disabled: busy
1437
+ }
1438
+ )
1439
+ ] }),
1440
+ /* @__PURE__ */ jsxs("div", { className: "pollar-field", children: [
1441
+ /* @__PURE__ */ jsx("label", { className: "pollar-label", htmlFor: "pollar-trustline-issuer", children: "Issuer" }),
1442
+ /* @__PURE__ */ jsx(
1443
+ "input",
1444
+ {
1445
+ id: "pollar-trustline-issuer",
1446
+ className: "pollar-input",
1447
+ value: issuer,
1448
+ onChange: (e) => setIssuer(e.target.value),
1449
+ placeholder: "G\u2026",
1450
+ autoComplete: "off",
1451
+ spellCheck: false,
1452
+ disabled: busy
1453
+ }
1454
+ ),
1455
+ issuer.trim().length > 0 && !issuerOk && /* @__PURE__ */ jsx("span", { className: "pollar-field-error", children: "Issuer must be a 56-character Stellar address starting with G." })
1456
+ ] }),
1457
+ /* @__PURE__ */ jsxs("div", { className: "pollar-field", children: [
1458
+ /* @__PURE__ */ jsxs("label", { className: "pollar-label", htmlFor: "pollar-trustline-limit", children: [
1459
+ "Limit ",
1460
+ /* @__PURE__ */ jsx("span", { className: "pollar-label-optional", children: "(optional)" })
1461
+ ] }),
1462
+ /* @__PURE__ */ jsx(
1463
+ "input",
1464
+ {
1465
+ id: "pollar-trustline-limit",
1466
+ className: "pollar-input",
1467
+ value: limit,
1468
+ onChange: (e) => setLimit(e.target.value),
1469
+ placeholder: "Maximum",
1470
+ inputMode: "decimal",
1471
+ autoComplete: "off",
1472
+ spellCheck: false,
1473
+ disabled: busy
1474
+ }
1475
+ )
1476
+ ] }),
1477
+ actionError && /* @__PURE__ */ jsx("div", { className: "pollar-modal-action-error", children: actionError }),
1478
+ /* @__PURE__ */ jsx("button", { className: "pollar-asset-submit", onClick: submit, disabled: !canSubmit, children: busy ? "Enabling\u2026" : "Enable trustline" }),
1344
1479
  /* @__PURE__ */ jsx(PollarModalFooter, {})
1345
1480
  ] });
1346
1481
  }
1482
+ function assetKey2(record) {
1483
+ return record.code + (record.issuer ?? "");
1484
+ }
1347
1485
  function EnabledAssetsModal({ onClose }) {
1348
- const { enabledAssets, refreshAssets, walletAddress, styles } = usePollar();
1486
+ const { enabledAssets, refreshAssets, setTrustline, walletAddress, styles } = usePollar();
1349
1487
  const { theme = "light", accentColor = "#005DB4" } = styles;
1488
+ const [view, setView] = useState("list");
1489
+ const [busyKey, setBusyKey] = useState(null);
1490
+ const [actionError, setActionError] = useState(null);
1350
1491
  useEffect(() => {
1351
1492
  void refreshAssets();
1352
1493
  }, [refreshAssets]);
1353
- return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", onClick: onClose, children: /* @__PURE__ */ jsx(
1494
+ const runAction = useCallback(
1495
+ async (key, asset, opts) => {
1496
+ setBusyKey(key);
1497
+ setActionError(null);
1498
+ const res = await setTrustline(asset, opts);
1499
+ if (res.status === "error") {
1500
+ setActionError(res.details || "Trustline update failed. Please try again.");
1501
+ setBusyKey(null);
1502
+ return false;
1503
+ }
1504
+ await refreshAssets();
1505
+ setBusyKey(null);
1506
+ return true;
1507
+ },
1508
+ [setTrustline, refreshAssets]
1509
+ );
1510
+ const handleToggle = useCallback(
1511
+ (record) => {
1512
+ const removing = record.trustlineEstablished;
1513
+ void runAction(
1514
+ assetKey2(record),
1515
+ { code: record.code, issuer: record.issuer ?? "" },
1516
+ { ...removing ? { limit: "0" } : {}, sponsored: record.sponsored ?? false }
1517
+ );
1518
+ },
1519
+ [runAction]
1520
+ );
1521
+ const handleCustomSubmit = useCallback(
1522
+ async (input) => {
1523
+ const ok = await runAction(
1524
+ "custom",
1525
+ { code: input.code, issuer: input.issuer },
1526
+ { ...input.limit ? { limit: input.limit } : {}, sponsored: false }
1527
+ );
1528
+ if (ok) setView("list");
1529
+ },
1530
+ [runAction]
1531
+ );
1532
+ return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", onClick: onClose, children: view === "list" ? /* @__PURE__ */ jsx(
1354
1533
  EnabledAssetsModalTemplate,
1355
1534
  {
1356
1535
  theme,
1357
1536
  accentColor,
1358
1537
  enabledAssets,
1359
1538
  walletAddress,
1539
+ busyKey,
1540
+ actionError,
1360
1541
  onRefresh: () => refreshAssets(),
1361
- onClose
1542
+ onClose,
1543
+ onToggleTrustline: handleToggle,
1544
+ onAddCustom: () => {
1545
+ setActionError(null);
1546
+ setView("custom");
1547
+ }
1548
+ }
1549
+ ) : /* @__PURE__ */ jsx(
1550
+ CustomTrustlineModalTemplate,
1551
+ {
1552
+ theme,
1553
+ accentColor,
1554
+ busy: busyKey === "custom",
1555
+ actionError,
1556
+ onBack: () => {
1557
+ setActionError(null);
1558
+ setView("list");
1559
+ },
1560
+ onClose,
1561
+ onSubmit: handleCustomSubmit
1362
1562
  }
1363
1563
  ) });
1364
1564
  }
@@ -1711,7 +1911,8 @@ function LoginModalTemplate({
1711
1911
  onEmailSubmit,
1712
1912
  onSocialLogin,
1713
1913
  onWalletConnect,
1714
- onSmartWallet,
1914
+ onLoginSmartWallet,
1915
+ onCreateSmartWallet,
1715
1916
  renderWallets,
1716
1917
  authState,
1717
1918
  codeInputKey,
@@ -1721,6 +1922,7 @@ function LoginModalTemplate({
1721
1922
  onRetry
1722
1923
  }) {
1723
1924
  const [showWalletPicker, setShowWalletPicker] = useState(false);
1925
+ const [showPasskeyChooser, setShowPasskeyChooser] = useState(false);
1724
1926
  const isDark = theme === "dark";
1725
1927
  const enabledSocial = Object.entries(providers).filter(([, enabled]) => enabled);
1726
1928
  const cssVars = {
@@ -1791,6 +1993,31 @@ function LoginModalTemplate({
1791
1993
  renderWallets ? renderWallets({ onConnect: onWalletConnect ?? (() => {
1792
1994
  }), authState }) : /* @__PURE__ */ jsx(DefaultFreighterAlbedoButtons, { onConnect: onWalletConnect ?? (() => {
1793
1995
  }), isLoading })
1996
+ ] }) : showPasskeyChooser ? /* @__PURE__ */ jsxs(Fragment, { children: [
1997
+ /* @__PURE__ */ jsx(BackButton, { onClick: () => setShowPasskeyChooser(false) }),
1998
+ /* @__PURE__ */ jsxs("div", { className: "pollar-wallet-section", children: [
1999
+ /* @__PURE__ */ jsx(
2000
+ "button",
2001
+ {
2002
+ type: "button",
2003
+ disabled: isLoading,
2004
+ className: "pollar-btn-primary",
2005
+ style: { width: "100%" },
2006
+ onClick: onCreateSmartWallet,
2007
+ children: "Create a new wallet"
2008
+ }
2009
+ ),
2010
+ /* @__PURE__ */ jsx(
2011
+ "button",
2012
+ {
2013
+ type: "button",
2014
+ disabled: isLoading,
2015
+ className: "pollar-wallet-entry-btn",
2016
+ onClick: onLoginSmartWallet,
2017
+ children: "Log in with an existing wallet"
2018
+ }
2019
+ )
2020
+ ] })
1794
2021
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1795
2022
  emailEnabled && /* @__PURE__ */ jsxs("div", { className: "pollar-email-section", children: [
1796
2023
  /* @__PURE__ */ jsx(
@@ -1858,7 +2085,7 @@ function LoginModalTemplate({
1858
2085
  type: "button",
1859
2086
  disabled: isLoading,
1860
2087
  className: "pollar-wallet-entry-btn",
1861
- onClick: onSmartWallet,
2088
+ onClick: () => setShowPasskeyChooser(true),
1862
2089
  children: [
1863
2090
  /* @__PURE__ */ jsx(
1864
2091
  "svg",
@@ -1929,8 +2156,8 @@ function LoginModal({ onClose }) {
1929
2156
  }
1930
2157
  };
1931
2158
  }, [getClient]);
1932
- const { theme = "light", accentColor = "#005DB4", logoUrl, emailEnabled, embeddedWallets, providers } = styles;
1933
- const smartWallet = styles.smartWallet ?? true;
2159
+ const { theme = "light", accentColor = "#005DB4", logoUrl, emailEnabled, embeddedWallets, smartWallet, providers } = styles;
2160
+ const smartWalletEnabled = smartWallet ?? false;
1934
2161
  function handleClose() {
1935
2162
  setEmail("");
1936
2163
  getClient().cancelLogin();
@@ -1947,9 +2174,12 @@ function LoginModal({ onClose }) {
1947
2174
  function handleWalletConnect(type) {
1948
2175
  getClient().loginWallet(type);
1949
2176
  }
1950
- function handleSmartWallet() {
2177
+ function handleLoginSmartWallet() {
1951
2178
  getClient().loginSmartWallet();
1952
2179
  }
2180
+ function handleCreateSmartWallet() {
2181
+ getClient().createSmartWallet();
2182
+ }
1953
2183
  function handleVerifyCode(code) {
1954
2184
  getClient().verifyEmailCode(code);
1955
2185
  }
@@ -1971,7 +2201,7 @@ function LoginModal({ onClose }) {
1971
2201
  logoUrl: logoUrl ?? null,
1972
2202
  emailEnabled: !!emailEnabled,
1973
2203
  embeddedWallets: !!embeddedWallets,
1974
- smartWallet,
2204
+ smartWallet: smartWalletEnabled,
1975
2205
  providers: {
1976
2206
  google: !!providers?.google,
1977
2207
  discord: !!providers?.discord,
@@ -1985,7 +2215,8 @@ function LoginModal({ onClose }) {
1985
2215
  onEmailSubmit: handleEmailSubmit,
1986
2216
  onSocialLogin: handleSocialLogin,
1987
2217
  onWalletConnect: handleWalletConnect,
1988
- onSmartWallet: handleSmartWallet,
2218
+ onLoginSmartWallet: handleLoginSmartWallet,
2219
+ onCreateSmartWallet: handleCreateSmartWallet,
1989
2220
  ...renderWallets !== void 0 && { renderWallets },
1990
2221
  authState,
1991
2222
  codeInputKey,
@@ -2748,7 +2979,7 @@ function formatBalance(balance) {
2748
2979
  const n = parseFloat(balance);
2749
2980
  return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
2750
2981
  }
2751
- function assetKey(record) {
2982
+ function assetKey3(record) {
2752
2983
  return `${record.code}:${record.issuer ?? "native"}`;
2753
2984
  }
2754
2985
  function SendModalTemplate({
@@ -2801,7 +3032,7 @@ function SendModalTemplate({
2801
3032
  };
2802
3033
  const enabledAssets = assets.filter((a) => a.enabledInApp);
2803
3034
  const otherAssets = assets.filter((a) => !a.enabledInApp);
2804
- const selectedKey = selectedAsset ? assetKey(selectedAsset) : "";
3035
+ const selectedKey = selectedAsset ? assetKey3(selectedAsset) : "";
2805
3036
  const canSubmit = !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
2806
3037
  const title = step === "form" ? "Send" : txTitle;
2807
3038
  return /* @__PURE__ */ jsxs(
@@ -2829,23 +3060,23 @@ function SendModalTemplate({
2829
3060
  value: selectedKey,
2830
3061
  onChange: (e) => {
2831
3062
  const all = [...enabledAssets, ...otherAssets];
2832
- const found = all.find((a) => assetKey(a) === e.target.value);
3063
+ const found = all.find((a) => assetKey3(a) === e.target.value);
2833
3064
  if (found) onSelectAsset(found);
2834
3065
  },
2835
3066
  children: [
2836
3067
  /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select asset" }),
2837
- enabledAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: "App assets", children: enabledAssets.map((a) => /* @__PURE__ */ jsxs("option", { value: assetKey(a), children: [
3068
+ enabledAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: "App assets", children: enabledAssets.map((a) => /* @__PURE__ */ jsxs("option", { value: assetKey3(a), children: [
2838
3069
  a.code,
2839
3070
  " \u2014 ",
2840
3071
  formatBalance(a.available),
2841
3072
  " available"
2842
- ] }, assetKey(a))) }),
2843
- otherAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: "Other assets", children: otherAssets.map((a) => /* @__PURE__ */ jsxs("option", { value: assetKey(a), children: [
3073
+ ] }, assetKey3(a))) }),
3074
+ otherAssets.length > 0 && /* @__PURE__ */ jsx("optgroup", { label: "Other assets", children: otherAssets.map((a) => /* @__PURE__ */ jsxs("option", { value: assetKey3(a), children: [
2844
3075
  a.code,
2845
3076
  " \u2014 ",
2846
3077
  formatBalance(a.available),
2847
3078
  " available"
2848
- ] }, assetKey(a))) })
3079
+ ] }, assetKey3(a))) })
2849
3080
  ]
2850
3081
  }
2851
3082
  )
@@ -3687,14 +3918,13 @@ function randomUserId() {
3687
3918
  for (const b of bytes) bin += String.fromCharCode(b);
3688
3919
  return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
3689
3920
  }
3690
- var browserPasskeyCeremony = async ({ challenge }) => {
3921
+ var browserPasskeyCeremony = async ({ challenge, mode }) => {
3691
3922
  const rpId = window.location.hostname;
3692
- try {
3923
+ if (mode === "login") {
3693
3924
  const response2 = await startAuthentication({
3694
3925
  optionsJSON: { challenge, rpId, userVerification: "required" }
3695
3926
  });
3696
3927
  return { kind: "login", response: response2 };
3697
- } catch {
3698
3928
  }
3699
3929
  const userId = randomUserId();
3700
3930
  const response = await startRegistration({
@@ -3858,6 +4088,7 @@ function PollarProvider({
3858
4088
  // enabled assets
3859
4089
  enabledAssets,
3860
4090
  refreshAssets,
4091
+ setTrustline: (asset, opts) => pollarClient.setTrustline(asset, opts),
3861
4092
  openEnabledAssetsModal: () => setEnabledAssetsModalOpen(true),
3862
4093
  // send / receive
3863
4094
  openSendModal: () => setSendModalOpen(true),