@pollar/core 0.9.0-rc.0 → 0.9.0-rc.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/README.md +35 -0
- package/dist/index.d.mts +55 -2
- package/dist/index.d.ts +55 -2
- package/dist/index.js +89 -67
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +89 -68
- package/dist/index.mjs.map +1 -1
- package/dist/index.rn.d.mts +1 -1
- package/dist/index.rn.d.ts +1 -1
- package/dist/index.rn.js +89 -68
- package/dist/index.rn.js.map +1 -1
- package/dist/index.rn.mjs +89 -69
- package/dist/index.rn.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -341,7 +341,6 @@ var WebCryptoKeyManager = class {
|
|
|
341
341
|
if (this.keyPair) return;
|
|
342
342
|
if (!this._initPromise) {
|
|
343
343
|
this._initPromise = this._doInit().catch((err) => {
|
|
344
|
-
console.error("[PollarClient:keys] WebCryptoKeyManager init failed", err);
|
|
345
344
|
this._initPromise = null;
|
|
346
345
|
throw err;
|
|
347
346
|
});
|
|
@@ -1076,6 +1075,16 @@ function normalizeHtu(rawUrl) {
|
|
|
1076
1075
|
return `${scheme}//${host}${portPart}${url.pathname}`;
|
|
1077
1076
|
}
|
|
1078
1077
|
|
|
1078
|
+
// src/lib/logger.ts
|
|
1079
|
+
var RANK = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 };
|
|
1080
|
+
function createLogger(level = "info", sink = console) {
|
|
1081
|
+
const threshold = RANK[level];
|
|
1082
|
+
const gate = (lvl) => (...args) => {
|
|
1083
|
+
if (threshold >= RANK[lvl]) sink[lvl](...args);
|
|
1084
|
+
};
|
|
1085
|
+
return { error: gate("error"), warn: gate("warn"), info: gate("info"), debug: gate("debug") };
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1079
1088
|
// src/storage/web.ts
|
|
1080
1089
|
var LOG_PREFIX = "[PollarClient:storage]";
|
|
1081
1090
|
function createMemoryAdapter() {
|
|
@@ -1099,7 +1108,7 @@ function createLocalStorageAdapter(options = {}) {
|
|
|
1099
1108
|
function degrade(reason, error) {
|
|
1100
1109
|
if (degraded) return;
|
|
1101
1110
|
degraded = true;
|
|
1102
|
-
console.warn(`${LOG_PREFIX} localStorage unavailable (${reason}); degrading to in-memory storage`);
|
|
1111
|
+
(options.logger ?? console).warn(`${LOG_PREFIX} localStorage unavailable (${reason}); degrading to in-memory storage`);
|
|
1103
1112
|
options.onDegrade?.(reason, error);
|
|
1104
1113
|
}
|
|
1105
1114
|
return {
|
|
@@ -1164,7 +1173,7 @@ function defaultStorage(options = {}) {
|
|
|
1164
1173
|
}
|
|
1165
1174
|
|
|
1166
1175
|
// src/version.ts
|
|
1167
|
-
var POLLAR_CORE_VERSION = "0.9.0-rc.
|
|
1176
|
+
var POLLAR_CORE_VERSION = "0.9.0-rc.1" ;
|
|
1168
1177
|
|
|
1169
1178
|
// src/visibility/noop.ts
|
|
1170
1179
|
function createNoopVisibilityProvider() {
|
|
@@ -1448,85 +1457,85 @@ function isBoundedString(v, max, allowEmpty = false) {
|
|
|
1448
1457
|
if (!allowEmpty && v.length === 0) return false;
|
|
1449
1458
|
return v.length <= max;
|
|
1450
1459
|
}
|
|
1451
|
-
function isValidSession(value) {
|
|
1460
|
+
function isValidSession(value, logger = console) {
|
|
1452
1461
|
if (typeof value !== "object" || value === null) {
|
|
1453
|
-
|
|
1462
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 value is not an object");
|
|
1454
1463
|
return false;
|
|
1455
1464
|
}
|
|
1456
1465
|
const s = value;
|
|
1457
1466
|
if (!isBoundedString(s["clientSessionId"], MAX_CLIENT_SESSION_ID)) {
|
|
1458
|
-
|
|
1467
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 clientSessionId missing/empty/too long");
|
|
1459
1468
|
return false;
|
|
1460
1469
|
}
|
|
1461
1470
|
if (s["userId"] !== null && !isBoundedString(s["userId"], MAX_USER_ID)) {
|
|
1462
|
-
|
|
1471
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 userId must be string|null");
|
|
1463
1472
|
return false;
|
|
1464
1473
|
}
|
|
1465
1474
|
if (!isBoundedString(s["status"], MAX_STATUS)) {
|
|
1466
|
-
|
|
1475
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 status must be string");
|
|
1467
1476
|
return false;
|
|
1468
1477
|
}
|
|
1469
1478
|
const token = s["token"];
|
|
1470
1479
|
if (typeof token !== "object" || token === null) {
|
|
1471
|
-
|
|
1480
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 token missing or not an object");
|
|
1472
1481
|
return false;
|
|
1473
1482
|
}
|
|
1474
1483
|
const t = token;
|
|
1475
1484
|
if (!isBoundedString(t["accessToken"], MAX_ACCESS_TOKEN)) {
|
|
1476
|
-
|
|
1485
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 token.accessToken missing/empty/too long");
|
|
1477
1486
|
return false;
|
|
1478
1487
|
}
|
|
1479
1488
|
if (!isBoundedString(t["refreshToken"], MAX_REFRESH_TOKEN)) {
|
|
1480
|
-
|
|
1489
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 token.refreshToken missing/empty/too long");
|
|
1481
1490
|
return false;
|
|
1482
1491
|
}
|
|
1483
1492
|
if (typeof t["expiresAt"] !== "number" || !Number.isFinite(t["expiresAt"])) {
|
|
1484
|
-
|
|
1493
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 token.expiresAt must be a finite number");
|
|
1485
1494
|
return false;
|
|
1486
1495
|
}
|
|
1487
1496
|
const user = s["user"];
|
|
1488
1497
|
if (typeof user !== "object" || user === null) {
|
|
1489
|
-
|
|
1498
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 user missing or not an object");
|
|
1490
1499
|
return false;
|
|
1491
1500
|
}
|
|
1492
1501
|
const u = user;
|
|
1493
1502
|
if (u["id"] !== void 0 && !isBoundedString(u["id"], MAX_USER_ID)) {
|
|
1494
|
-
|
|
1503
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 user.id must be string if present");
|
|
1495
1504
|
return false;
|
|
1496
1505
|
}
|
|
1497
1506
|
if (typeof u["ready"] !== "boolean") {
|
|
1498
|
-
|
|
1507
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 user.ready must be boolean");
|
|
1499
1508
|
return false;
|
|
1500
1509
|
}
|
|
1501
1510
|
const wallet = s["wallet"];
|
|
1502
1511
|
if (typeof wallet !== "object" || wallet === null) {
|
|
1503
|
-
|
|
1512
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 wallet missing or not an object");
|
|
1504
1513
|
return false;
|
|
1505
1514
|
}
|
|
1506
1515
|
const w = wallet;
|
|
1507
1516
|
if (w["type"] !== "custodial" && w["type"] !== "smart" && w["type"] !== "external") {
|
|
1508
|
-
|
|
1517
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 wallet.type must be custodial|smart|external");
|
|
1509
1518
|
return false;
|
|
1510
1519
|
}
|
|
1511
1520
|
if (w["address"] !== null && !isBoundedString(w["address"], MAX_WALLET_PUBLIC_KEY)) {
|
|
1512
|
-
|
|
1521
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 wallet.address must be string|null");
|
|
1513
1522
|
return false;
|
|
1514
1523
|
}
|
|
1515
1524
|
if (w["existsOnStellar"] !== void 0 && typeof w["existsOnStellar"] !== "boolean") {
|
|
1516
|
-
|
|
1525
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 wallet.existsOnStellar must be boolean if present");
|
|
1517
1526
|
return false;
|
|
1518
1527
|
}
|
|
1519
1528
|
if (w["createdAt"] !== void 0 && (typeof w["createdAt"] !== "number" || !Number.isFinite(w["createdAt"]))) {
|
|
1520
|
-
|
|
1529
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 wallet.createdAt must be a finite number if present");
|
|
1521
1530
|
return false;
|
|
1522
1531
|
}
|
|
1523
1532
|
if (w["linkedAt"] !== void 0 && (typeof w["linkedAt"] !== "number" || !Number.isFinite(w["linkedAt"]))) {
|
|
1524
|
-
|
|
1533
|
+
logger.debug("[PollarClient:session] Invalid session \u2014 wallet.linkedAt must be a finite number if present");
|
|
1525
1534
|
return false;
|
|
1526
1535
|
}
|
|
1527
1536
|
return true;
|
|
1528
1537
|
}
|
|
1529
|
-
async function readStorage(storage, apiKeyHash) {
|
|
1538
|
+
async function readStorage(storage, apiKeyHash, logger = console) {
|
|
1530
1539
|
const raw = await storage.get(sessionStorageKey(apiKeyHash));
|
|
1531
1540
|
if (!raw) return null;
|
|
1532
1541
|
try {
|
|
@@ -1537,9 +1546,9 @@ async function readStorage(storage, apiKeyHash) {
|
|
|
1537
1546
|
w["address"] = w["publicKey"];
|
|
1538
1547
|
}
|
|
1539
1548
|
}
|
|
1540
|
-
if (!isValidSession(session)) {
|
|
1549
|
+
if (!isValidSession(session, logger)) {
|
|
1541
1550
|
await storage.remove(sessionStorageKey(apiKeyHash));
|
|
1542
|
-
|
|
1551
|
+
logger.warn("[PollarClient:session] Stored session is invalid \u2014 clearing storage");
|
|
1543
1552
|
return null;
|
|
1544
1553
|
}
|
|
1545
1554
|
if (session.token.expiresAt * 1e3 < Date.now()) {
|
|
@@ -1547,7 +1556,7 @@ async function readStorage(storage, apiKeyHash) {
|
|
|
1547
1556
|
}
|
|
1548
1557
|
return session;
|
|
1549
1558
|
} catch (error) {
|
|
1550
|
-
|
|
1559
|
+
logger.error("[PollarClient:session] Failed to parse session from storage", error);
|
|
1551
1560
|
await storage.remove(sessionStorageKey(apiKeyHash));
|
|
1552
1561
|
return null;
|
|
1553
1562
|
}
|
|
@@ -1609,7 +1618,7 @@ function abortableDelay(ms, signal) {
|
|
|
1609
1618
|
});
|
|
1610
1619
|
}
|
|
1611
1620
|
var MAX_BACKOFF_MS = 5e3;
|
|
1612
|
-
async function streamUntilFound(api, clientSessionId, check, retryDelayMs = 200, signal) {
|
|
1621
|
+
async function streamUntilFound(api, clientSessionId, check, retryDelayMs = 200, signal, logger = console) {
|
|
1613
1622
|
let backoff = retryDelayMs;
|
|
1614
1623
|
const sleep = async (ms) => {
|
|
1615
1624
|
if (ms <= 0) return;
|
|
@@ -1627,7 +1636,7 @@ async function streamUntilFound(api, clientSessionId, check, retryDelayMs = 200,
|
|
|
1627
1636
|
}));
|
|
1628
1637
|
} catch (e) {
|
|
1629
1638
|
if (e instanceof Error && e.name === "AbortError") throw e;
|
|
1630
|
-
|
|
1639
|
+
logger.debug("[PollarClient:stream] session-status request failed; will retry", e);
|
|
1631
1640
|
}
|
|
1632
1641
|
if (error || !data) {
|
|
1633
1642
|
await sleep(backoff);
|
|
@@ -1667,7 +1676,7 @@ async function streamUntilFound(api, clientSessionId, check, retryDelayMs = 200,
|
|
|
1667
1676
|
} catch (e) {
|
|
1668
1677
|
if (e instanceof Error && e.name === "AbortError") throw e;
|
|
1669
1678
|
if (e instanceof SessionStatusError) throw e;
|
|
1670
|
-
|
|
1679
|
+
logger.debug("[PollarClient:stream] session-status stream read failed; will retry", e);
|
|
1671
1680
|
} finally {
|
|
1672
1681
|
reader.releaseLock();
|
|
1673
1682
|
}
|
|
@@ -1677,7 +1686,7 @@ async function streamUntilFound(api, clientSessionId, check, retryDelayMs = 200,
|
|
|
1677
1686
|
if (delay) await sleep(delay);
|
|
1678
1687
|
}
|
|
1679
1688
|
}
|
|
1680
|
-
async function pollUntilFound(baseUrl, clientSessionId, check, intervalMs = 500, signal) {
|
|
1689
|
+
async function pollUntilFound(baseUrl, clientSessionId, check, intervalMs = 500, signal, logger = console) {
|
|
1681
1690
|
const url = `${baseUrl}/auth/session/status/${encodeURIComponent(clientSessionId)}/poll`;
|
|
1682
1691
|
let backoff = intervalMs;
|
|
1683
1692
|
const sleep = async (ms) => {
|
|
@@ -1695,7 +1704,7 @@ async function pollUntilFound(baseUrl, clientSessionId, check, intervalMs = 500,
|
|
|
1695
1704
|
envelope = await response.json().catch(() => null);
|
|
1696
1705
|
} catch (e) {
|
|
1697
1706
|
if (e instanceof Error && e.name === "AbortError") throw e;
|
|
1698
|
-
|
|
1707
|
+
logger.debug("[PollarClient:stream] session-status poll failed; will retry", e);
|
|
1699
1708
|
}
|
|
1700
1709
|
if (httpStatus === 404 || envelope?.code === "INVALID_CLIENT_SESSION_ID") {
|
|
1701
1710
|
throw new SessionStatusError("INVALID_CLIENT_SESSION_ID");
|
|
@@ -1712,13 +1721,13 @@ async function pollUntilFound(baseUrl, clientSessionId, check, intervalMs = 500,
|
|
|
1712
1721
|
}
|
|
1713
1722
|
}
|
|
1714
1723
|
function waitForSessionReady(args) {
|
|
1715
|
-
const { api, baseUrl, clientSessionId, check, useStreaming, retryDelayMs, signal } = args;
|
|
1716
|
-
return useStreaming ? streamUntilFound(api, clientSessionId, check, retryDelayMs ?? 200, signal) : pollUntilFound(baseUrl, clientSessionId, check, retryDelayMs ?? 500, signal);
|
|
1724
|
+
const { api, baseUrl, clientSessionId, check, useStreaming, retryDelayMs, signal, logger = console } = args;
|
|
1725
|
+
return useStreaming ? streamUntilFound(api, clientSessionId, check, retryDelayMs ?? 200, signal, logger) : pollUntilFound(baseUrl, clientSessionId, check, retryDelayMs ?? 500, signal, logger);
|
|
1717
1726
|
}
|
|
1718
1727
|
|
|
1719
1728
|
// src/client/auth/authenticate.ts
|
|
1720
1729
|
async function authenticate(clientSessionId, deps, expectedWallet) {
|
|
1721
|
-
const { api, basePath, useStreaming, signal, setAuthState, storeSession, clearSession } = deps;
|
|
1730
|
+
const { api, logger, basePath, useStreaming, signal, setAuthState, storeSession, clearSession } = deps;
|
|
1722
1731
|
setAuthState({ step: "authenticating" });
|
|
1723
1732
|
try {
|
|
1724
1733
|
await waitForSessionReady({
|
|
@@ -1727,7 +1736,8 @@ async function authenticate(clientSessionId, deps, expectedWallet) {
|
|
|
1727
1736
|
clientSessionId,
|
|
1728
1737
|
check: (data2) => data2?.status === "READY",
|
|
1729
1738
|
useStreaming,
|
|
1730
|
-
signal
|
|
1739
|
+
signal,
|
|
1740
|
+
logger
|
|
1731
1741
|
});
|
|
1732
1742
|
} catch (err) {
|
|
1733
1743
|
if (err instanceof SessionStatusError) {
|
|
@@ -1752,7 +1762,7 @@ async function authenticate(clientSessionId, deps, expectedWallet) {
|
|
|
1752
1762
|
},
|
|
1753
1763
|
signal
|
|
1754
1764
|
});
|
|
1755
|
-
if (data?.code === "SDK_LOGIN_SUCCESS" && isValidSession(data?.content)) {
|
|
1765
|
+
if (data?.code === "SDK_LOGIN_SUCCESS" && isValidSession(data?.content, logger)) {
|
|
1756
1766
|
if (expectedWallet && data.content.data.providers.wallet?.address !== expectedWallet) {
|
|
1757
1767
|
setAuthState({
|
|
1758
1768
|
step: "error",
|
|
@@ -2070,7 +2080,9 @@ var PollarClient = class {
|
|
|
2070
2080
|
this.apiKey = config.apiKey;
|
|
2071
2081
|
this.id = randomUUID();
|
|
2072
2082
|
this.basePath = `${config.baseUrl || "https://sdk.api.pollar.xyz"}/v1`;
|
|
2083
|
+
this._log = createLogger(config.logLevel ?? "info", config.logger);
|
|
2073
2084
|
this._storage = config.storage ?? defaultStorage({
|
|
2085
|
+
logger: this._log,
|
|
2074
2086
|
onDegrade: (reason, error) => {
|
|
2075
2087
|
config.onStorageDegrade?.(reason, error);
|
|
2076
2088
|
this._dispatchStorageDegrade(reason, error);
|
|
@@ -2094,7 +2106,7 @@ var PollarClient = class {
|
|
|
2094
2106
|
this._initialized = Promise.resolve();
|
|
2095
2107
|
return;
|
|
2096
2108
|
}
|
|
2097
|
-
|
|
2109
|
+
this._log.info(
|
|
2098
2110
|
`[PollarClient] Initialized v${POLLAR_CORE_VERSION} \u2014 endpoint: ${this.basePath}, network: ${this._networkState.network}`
|
|
2099
2111
|
);
|
|
2100
2112
|
this._initialized = this._initialize();
|
|
@@ -2121,7 +2133,7 @@ var PollarClient = class {
|
|
|
2121
2133
|
const sessionKey = sessionStorageKey(this._apiKeyHash);
|
|
2122
2134
|
const handler = (e) => {
|
|
2123
2135
|
if (e.key === sessionKey) {
|
|
2124
|
-
this._restoreSession().catch((err) =>
|
|
2136
|
+
this._restoreSession().catch((err) => this._log.error("[PollarClient] Cross-tab restore failed", err));
|
|
2125
2137
|
}
|
|
2126
2138
|
};
|
|
2127
2139
|
window.addEventListener("storage", handler);
|
|
@@ -2130,7 +2142,7 @@ var PollarClient = class {
|
|
|
2130
2142
|
try {
|
|
2131
2143
|
await this._keyManager.init();
|
|
2132
2144
|
} catch (err) {
|
|
2133
|
-
|
|
2145
|
+
this._log.warn("[PollarClient] KeyManager init failed; DPoP unavailable for this session", err);
|
|
2134
2146
|
}
|
|
2135
2147
|
await this._restoreSession();
|
|
2136
2148
|
this._visibilityUnsubscribe = this._visibilityProvider.onChange((visible) => {
|
|
@@ -2171,7 +2183,7 @@ var PollarClient = class {
|
|
|
2171
2183
|
try {
|
|
2172
2184
|
self._requestBodyCache.set(request, await request.clone().arrayBuffer());
|
|
2173
2185
|
} catch (err) {
|
|
2174
|
-
|
|
2186
|
+
this._log.warn("[PollarClient] Could not snapshot request body for retry", err);
|
|
2175
2187
|
}
|
|
2176
2188
|
}
|
|
2177
2189
|
const isRefresh = request.url.includes("/auth/refresh");
|
|
@@ -2230,7 +2242,7 @@ var PollarClient = class {
|
|
|
2230
2242
|
this._keyManager
|
|
2231
2243
|
);
|
|
2232
2244
|
} catch (err) {
|
|
2233
|
-
|
|
2245
|
+
this._log.warn("[PollarClient] DPoP proof build failed", err);
|
|
2234
2246
|
return null;
|
|
2235
2247
|
}
|
|
2236
2248
|
}
|
|
@@ -2284,7 +2296,7 @@ var PollarClient = class {
|
|
|
2284
2296
|
async _doRefresh() {
|
|
2285
2297
|
const refreshToken = this._session?.token?.refreshToken;
|
|
2286
2298
|
if (!refreshToken) {
|
|
2287
|
-
|
|
2299
|
+
this._log.warn("[PollarClient] Refresh skipped: no refresh token in session");
|
|
2288
2300
|
await this._clearSession();
|
|
2289
2301
|
throw new Error("No refresh token available");
|
|
2290
2302
|
}
|
|
@@ -2295,18 +2307,18 @@ var PollarClient = class {
|
|
|
2295
2307
|
data = response.data;
|
|
2296
2308
|
error = response.error;
|
|
2297
2309
|
} catch (err) {
|
|
2298
|
-
|
|
2310
|
+
this._log.error("[PollarClient] /auth/refresh request threw", err);
|
|
2299
2311
|
await this._clearSession();
|
|
2300
2312
|
throw err;
|
|
2301
2313
|
}
|
|
2302
2314
|
if (error || !data) {
|
|
2303
|
-
|
|
2315
|
+
this._log.error("[PollarClient] /auth/refresh returned error", { error });
|
|
2304
2316
|
await this._clearSession();
|
|
2305
2317
|
throw new Error("Refresh failed");
|
|
2306
2318
|
}
|
|
2307
2319
|
const successData = data;
|
|
2308
2320
|
if (!successData.success || !successData.content?.token) {
|
|
2309
|
-
|
|
2321
|
+
this._log.error("[PollarClient] /auth/refresh response malformed", {
|
|
2310
2322
|
success: successData.success,
|
|
2311
2323
|
hasToken: !!successData.content?.token
|
|
2312
2324
|
});
|
|
@@ -2315,7 +2327,7 @@ var PollarClient = class {
|
|
|
2315
2327
|
}
|
|
2316
2328
|
const newToken = successData.content.token;
|
|
2317
2329
|
if (typeof newToken.accessToken !== "string" || typeof newToken.refreshToken !== "string" || typeof newToken.expiresAt !== "number") {
|
|
2318
|
-
|
|
2330
|
+
this._log.error("[PollarClient] /auth/refresh token shape invalid", {
|
|
2319
2331
|
accessToken: typeof newToken.accessToken,
|
|
2320
2332
|
refreshToken: typeof newToken.refreshToken,
|
|
2321
2333
|
expiresAt: typeof newToken.expiresAt
|
|
@@ -2327,9 +2339,9 @@ var PollarClient = class {
|
|
|
2327
2339
|
try {
|
|
2328
2340
|
this._session = { ...this._session, token: newToken };
|
|
2329
2341
|
await writeStorage(this._storage, this.apiKeyHash, this._session);
|
|
2330
|
-
|
|
2342
|
+
this._log.info("[PollarClient] Tokens refreshed");
|
|
2331
2343
|
} catch (err) {
|
|
2332
|
-
|
|
2344
|
+
this._log.error("[PollarClient] Failed to persist refreshed session", err);
|
|
2333
2345
|
}
|
|
2334
2346
|
this._scheduleNextRefresh();
|
|
2335
2347
|
}
|
|
@@ -2383,7 +2395,7 @@ var PollarClient = class {
|
|
|
2383
2395
|
try {
|
|
2384
2396
|
await this.refresh();
|
|
2385
2397
|
} catch (err) {
|
|
2386
|
-
|
|
2398
|
+
this._log.warn("[PollarClient] Proactive refresh failed; session cleared", err);
|
|
2387
2399
|
}
|
|
2388
2400
|
}
|
|
2389
2401
|
_clearRefreshTimer() {
|
|
@@ -2429,7 +2441,7 @@ var PollarClient = class {
|
|
|
2429
2441
|
try {
|
|
2430
2442
|
cb(reason, error);
|
|
2431
2443
|
} catch (err) {
|
|
2432
|
-
|
|
2444
|
+
this._log.error("[PollarClient] onStorageDegrade listener threw", err);
|
|
2433
2445
|
}
|
|
2434
2446
|
}
|
|
2435
2447
|
}
|
|
@@ -2549,20 +2561,20 @@ var PollarClient = class {
|
|
|
2549
2561
|
warnServerSide("logout");
|
|
2550
2562
|
return;
|
|
2551
2563
|
}
|
|
2552
|
-
|
|
2564
|
+
this._log.info("[PollarClient] Logout requested", { everywhere: !!options.everywhere });
|
|
2553
2565
|
if (this._session?.token?.accessToken) {
|
|
2554
2566
|
try {
|
|
2555
2567
|
await this._api.POST("/auth/logout", {
|
|
2556
2568
|
body: options.everywhere ? { everywhere: true } : {}
|
|
2557
2569
|
});
|
|
2558
2570
|
} catch (err) {
|
|
2559
|
-
|
|
2571
|
+
this._log.warn("[PollarClient] Server logout failed (continuing with local clear)", err);
|
|
2560
2572
|
}
|
|
2561
2573
|
}
|
|
2562
2574
|
try {
|
|
2563
2575
|
await this._clearSession();
|
|
2564
2576
|
} catch (err) {
|
|
2565
|
-
|
|
2577
|
+
this._log.warn("[PollarClient] Local logout cleanup failed", err);
|
|
2566
2578
|
}
|
|
2567
2579
|
}
|
|
2568
2580
|
/** Convenience: revoke every active session for this user (all devices). */
|
|
@@ -2638,6 +2650,14 @@ var PollarClient = class {
|
|
|
2638
2650
|
getNetworkState() {
|
|
2639
2651
|
return this._networkState;
|
|
2640
2652
|
}
|
|
2653
|
+
/**
|
|
2654
|
+
* The client's level-gated logger (built from `logLevel` / `logger`). Exposed
|
|
2655
|
+
* so the runtime layer (`@pollar/react`) can route its own logs through the
|
|
2656
|
+
* same level and sink instead of calling `console` directly.
|
|
2657
|
+
*/
|
|
2658
|
+
getLogger() {
|
|
2659
|
+
return this._log;
|
|
2660
|
+
}
|
|
2641
2661
|
setNetwork(network) {
|
|
2642
2662
|
this._setNetworkState({ step: "connected", network });
|
|
2643
2663
|
}
|
|
@@ -2786,7 +2806,7 @@ var PollarClient = class {
|
|
|
2786
2806
|
this._setTransactionState({ step: "error", phase: "building", ...details && { details } });
|
|
2787
2807
|
return { status: "error", ...details && { details } };
|
|
2788
2808
|
} catch (err) {
|
|
2789
|
-
|
|
2809
|
+
this._log.error("[PollarClient] buildTx failed", err);
|
|
2790
2810
|
this._setTransactionState({ step: "error", phase: "building" });
|
|
2791
2811
|
return { status: "error" };
|
|
2792
2812
|
}
|
|
@@ -3299,6 +3319,7 @@ var PollarClient = class {
|
|
|
3299
3319
|
_flowDeps(signal) {
|
|
3300
3320
|
return {
|
|
3301
3321
|
api: this._api,
|
|
3322
|
+
logger: this._log,
|
|
3302
3323
|
basePath: this.basePath,
|
|
3303
3324
|
// SSE status streaming works on web; React Native's `fetch` has no
|
|
3304
3325
|
// readable `response.body`, so those clients poll the non-streaming
|
|
@@ -3351,12 +3372,12 @@ var PollarClient = class {
|
|
|
3351
3372
|
}
|
|
3352
3373
|
_handleFlowError(error) {
|
|
3353
3374
|
if (error instanceof Error && error.name === "AbortError") {
|
|
3354
|
-
|
|
3375
|
+
this._log.debug("[PollarClient] Login cancelled");
|
|
3355
3376
|
this._setAuthState({ step: "idle" });
|
|
3356
3377
|
return;
|
|
3357
3378
|
}
|
|
3358
3379
|
if (error instanceof Error && error.code === AUTH_ERROR_CODES.WALLET_RESOLVER_TIMEOUT) {
|
|
3359
|
-
|
|
3380
|
+
this._log.error("[PollarClient]", error.message);
|
|
3360
3381
|
this._setAuthState({
|
|
3361
3382
|
step: "error",
|
|
3362
3383
|
previousStep: this._authState.step,
|
|
@@ -3365,7 +3386,7 @@ var PollarClient = class {
|
|
|
3365
3386
|
});
|
|
3366
3387
|
return;
|
|
3367
3388
|
}
|
|
3368
|
-
|
|
3389
|
+
this._log.error("[PollarClient] Unexpected error in auth flow", error);
|
|
3369
3390
|
this._setAuthState({
|
|
3370
3391
|
step: "error",
|
|
3371
3392
|
previousStep: this._authState.step,
|
|
@@ -3374,22 +3395,22 @@ var PollarClient = class {
|
|
|
3374
3395
|
});
|
|
3375
3396
|
}
|
|
3376
3397
|
async _restoreSession() {
|
|
3377
|
-
this._session = await readStorage(this._storage, this.apiKeyHash);
|
|
3398
|
+
this._session = await readStorage(this._storage, this.apiKeyHash, this._log);
|
|
3378
3399
|
if (this._session) {
|
|
3379
3400
|
const storedType = await readWalletType(this._storage, this.apiKeyHash);
|
|
3380
3401
|
if (storedType) {
|
|
3381
3402
|
try {
|
|
3382
3403
|
this._walletAdapter = await this._resolveWalletAdapter(storedType);
|
|
3383
3404
|
} catch (err) {
|
|
3384
|
-
|
|
3405
|
+
this._log.warn("[PollarClient] Could not restore wallet adapter for stored id", { id: storedType, err });
|
|
3385
3406
|
}
|
|
3386
3407
|
}
|
|
3387
|
-
|
|
3408
|
+
this._log.info("[PollarClient] Session restored from storage");
|
|
3388
3409
|
this._setAuthState({ step: "authenticated", session: this._session, verified: false });
|
|
3389
3410
|
this._scheduleNextRefresh();
|
|
3390
3411
|
void this._resume();
|
|
3391
3412
|
} else {
|
|
3392
|
-
|
|
3413
|
+
this._log.info("[PollarClient] No session in storage");
|
|
3393
3414
|
}
|
|
3394
3415
|
}
|
|
3395
3416
|
/**
|
|
@@ -3420,13 +3441,13 @@ var PollarClient = class {
|
|
|
3420
3441
|
this._setAuthState({ step: "authenticated", session: this._session, verified: true });
|
|
3421
3442
|
} catch (err) {
|
|
3422
3443
|
if (err?.name === "AbortError") return;
|
|
3423
|
-
|
|
3444
|
+
this._log.warn("[PollarClient] resume failed (network); will retry", err);
|
|
3424
3445
|
} finally {
|
|
3425
3446
|
if (this._resumeController === controller) this._resumeController = null;
|
|
3426
3447
|
}
|
|
3427
3448
|
}
|
|
3428
3449
|
async _storeSession(session) {
|
|
3429
|
-
|
|
3450
|
+
this._log.info("[PollarClient] Session stored");
|
|
3430
3451
|
const w = session.wallet;
|
|
3431
3452
|
const persisted = {
|
|
3432
3453
|
clientSessionId: session.clientSessionId,
|
|
@@ -3461,7 +3482,7 @@ var PollarClient = class {
|
|
|
3461
3482
|
this._scheduleNextRefresh();
|
|
3462
3483
|
}
|
|
3463
3484
|
async _clearSession() {
|
|
3464
|
-
|
|
3485
|
+
this._log.info("[PollarClient] Session cleared");
|
|
3465
3486
|
this._clearRefreshTimer();
|
|
3466
3487
|
this._session = null;
|
|
3467
3488
|
this._profile = null;
|
|
@@ -3470,7 +3491,7 @@ var PollarClient = class {
|
|
|
3470
3491
|
try {
|
|
3471
3492
|
await this._keyManager.reset();
|
|
3472
3493
|
} catch (err) {
|
|
3473
|
-
|
|
3494
|
+
this._log.warn("[PollarClient] KeyManager reset failed during clearSession", err);
|
|
3474
3495
|
}
|
|
3475
3496
|
await removeStorage(this._storage, this.apiKeyHash);
|
|
3476
3497
|
this._transactionState = null;
|
|
@@ -3482,17 +3503,17 @@ var PollarClient = class {
|
|
|
3482
3503
|
_setNetworkState(next) {
|
|
3483
3504
|
this._networkState = next;
|
|
3484
3505
|
const label = next.step === "connected" ? next.network : next.step;
|
|
3485
|
-
|
|
3506
|
+
this._log.debug(`[PollarClient] network:${label}`);
|
|
3486
3507
|
for (const cb of this._networkStateListeners) cb(next);
|
|
3487
3508
|
}
|
|
3488
3509
|
_setAuthState(next) {
|
|
3489
3510
|
this._authState = next;
|
|
3490
|
-
|
|
3511
|
+
this._log.debug(`[PollarClient] auth:${next.step}`);
|
|
3491
3512
|
for (const cb of this._authStateListeners) cb(next);
|
|
3492
3513
|
}
|
|
3493
3514
|
_setTransactionState(next) {
|
|
3494
3515
|
this._transactionState = next;
|
|
3495
|
-
|
|
3516
|
+
this._log.debug(`[PollarClient] transaction:${next.step}`);
|
|
3496
3517
|
for (const cb of this._transactionStateListeners) cb(next);
|
|
3497
3518
|
}
|
|
3498
3519
|
/**
|
|
@@ -3553,6 +3574,7 @@ exports.canonicalEcJwk = canonicalEcJwk;
|
|
|
3553
3574
|
exports.claimDistributionRule = claimDistributionRule;
|
|
3554
3575
|
exports.computeJwkThumbprint = computeJwkThumbprint;
|
|
3555
3576
|
exports.createLocalStorageAdapter = createLocalStorageAdapter;
|
|
3577
|
+
exports.createLogger = createLogger;
|
|
3556
3578
|
exports.createMemoryAdapter = createMemoryAdapter;
|
|
3557
3579
|
exports.createOffRamp = createOffRamp;
|
|
3558
3580
|
exports.createOnRamp = createOnRamp;
|