@pollar/react 0.9.0-rc.1 → 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.1"
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" }),
1344
1387
  /* @__PURE__ */ jsx(PollarModalFooter, {})
1345
1388
  ] });
1346
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" }),
1479
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
1480
+ ] });
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",
@@ -1912,6 +2139,9 @@ function LoginModal({ onClose }) {
1912
2139
  setCodeInputKey((k) => k + 1);
1913
2140
  }
1914
2141
  if (next.step === "authenticated") {
2142
+ if (autoCloseTimer.current !== null) {
2143
+ clearTimeout(autoCloseTimer.current);
2144
+ }
1915
2145
  autoCloseTimer.current = setTimeout(() => {
1916
2146
  autoCloseTimer.current = null;
1917
2147
  onCloseRef.current();
@@ -1926,8 +2156,8 @@ function LoginModal({ onClose }) {
1926
2156
  }
1927
2157
  };
1928
2158
  }, [getClient]);
1929
- const { theme = "light", accentColor = "#005DB4", logoUrl, emailEnabled, embeddedWallets, providers } = styles;
1930
- const smartWallet = styles.smartWallet ?? true;
2159
+ const { theme = "light", accentColor = "#005DB4", logoUrl, emailEnabled, embeddedWallets, smartWallet, providers } = styles;
2160
+ const smartWalletEnabled = smartWallet ?? false;
1931
2161
  function handleClose() {
1932
2162
  setEmail("");
1933
2163
  getClient().cancelLogin();
@@ -1944,9 +2174,12 @@ function LoginModal({ onClose }) {
1944
2174
  function handleWalletConnect(type) {
1945
2175
  getClient().loginWallet(type);
1946
2176
  }
1947
- function handleSmartWallet() {
2177
+ function handleLoginSmartWallet() {
1948
2178
  getClient().loginSmartWallet();
1949
2179
  }
2180
+ function handleCreateSmartWallet() {
2181
+ getClient().createSmartWallet();
2182
+ }
1950
2183
  function handleVerifyCode(code) {
1951
2184
  getClient().verifyEmailCode(code);
1952
2185
  }
@@ -1968,7 +2201,7 @@ function LoginModal({ onClose }) {
1968
2201
  logoUrl: logoUrl ?? null,
1969
2202
  emailEnabled: !!emailEnabled,
1970
2203
  embeddedWallets: !!embeddedWallets,
1971
- smartWallet,
2204
+ smartWallet: smartWalletEnabled,
1972
2205
  providers: {
1973
2206
  google: !!providers?.google,
1974
2207
  discord: !!providers?.discord,
@@ -1982,7 +2215,8 @@ function LoginModal({ onClose }) {
1982
2215
  onEmailSubmit: handleEmailSubmit,
1983
2216
  onSocialLogin: handleSocialLogin,
1984
2217
  onWalletConnect: handleWalletConnect,
1985
- onSmartWallet: handleSmartWallet,
2218
+ onLoginSmartWallet: handleLoginSmartWallet,
2219
+ onCreateSmartWallet: handleCreateSmartWallet,
1986
2220
  ...renderWallets !== void 0 && { renderWallets },
1987
2221
  authState,
1988
2222
  codeInputKey,
@@ -2745,7 +2979,7 @@ function formatBalance(balance) {
2745
2979
  const n = parseFloat(balance);
2746
2980
  return isNaN(n) ? balance : n.toLocaleString(void 0, { maximumFractionDigits: 7 });
2747
2981
  }
2748
- function assetKey(record) {
2982
+ function assetKey3(record) {
2749
2983
  return `${record.code}:${record.issuer ?? "native"}`;
2750
2984
  }
2751
2985
  function SendModalTemplate({
@@ -2798,7 +3032,7 @@ function SendModalTemplate({
2798
3032
  };
2799
3033
  const enabledAssets = assets.filter((a) => a.enabledInApp);
2800
3034
  const otherAssets = assets.filter((a) => !a.enabledInApp);
2801
- const selectedKey = selectedAsset ? assetKey(selectedAsset) : "";
3035
+ const selectedKey = selectedAsset ? assetKey3(selectedAsset) : "";
2802
3036
  const canSubmit = !!selectedAsset && !!amount && !!destination.trim() && !isLoadingBalance;
2803
3037
  const title = step === "form" ? "Send" : txTitle;
2804
3038
  return /* @__PURE__ */ jsxs(
@@ -2826,23 +3060,23 @@ function SendModalTemplate({
2826
3060
  value: selectedKey,
2827
3061
  onChange: (e) => {
2828
3062
  const all = [...enabledAssets, ...otherAssets];
2829
- const found = all.find((a) => assetKey(a) === e.target.value);
3063
+ const found = all.find((a) => assetKey3(a) === e.target.value);
2830
3064
  if (found) onSelectAsset(found);
2831
3065
  },
2832
3066
  children: [
2833
3067
  /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select asset" }),
2834
- 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: [
2835
3069
  a.code,
2836
3070
  " \u2014 ",
2837
3071
  formatBalance(a.available),
2838
3072
  " available"
2839
- ] }, assetKey(a))) }),
2840
- 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: [
2841
3075
  a.code,
2842
3076
  " \u2014 ",
2843
3077
  formatBalance(a.available),
2844
3078
  " available"
2845
- ] }, assetKey(a))) })
3079
+ ] }, assetKey3(a))) })
2846
3080
  ]
2847
3081
  }
2848
3082
  )
@@ -3684,14 +3918,13 @@ function randomUserId() {
3684
3918
  for (const b of bytes) bin += String.fromCharCode(b);
3685
3919
  return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
3686
3920
  }
3687
- var browserPasskeyCeremony = async ({ challenge }) => {
3921
+ var browserPasskeyCeremony = async ({ challenge, mode }) => {
3688
3922
  const rpId = window.location.hostname;
3689
- try {
3923
+ if (mode === "login") {
3690
3924
  const response2 = await startAuthentication({
3691
3925
  optionsJSON: { challenge, rpId, userVerification: "required" }
3692
3926
  });
3693
3927
  return { kind: "login", response: response2 };
3694
- } catch {
3695
3928
  }
3696
3929
  const userId = randomUserId();
3697
3930
  const response = await startRegistration({
@@ -3855,6 +4088,7 @@ function PollarProvider({
3855
4088
  // enabled assets
3856
4089
  enabledAssets,
3857
4090
  refreshAssets,
4091
+ setTrustline: (asset, opts) => pollarClient.setTrustline(asset, opts),
3858
4092
  openEnabledAssetsModal: () => setEnabledAssetsModalOpen(true),
3859
4093
  // send / receive
3860
4094
  openSendModal: () => setSendModalOpen(true),