@pollar/core 0.5.0 → 0.5.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.js CHANGED
@@ -767,8 +767,176 @@ var PollarFlowError = class extends Error {
767
767
  }
768
768
  };
769
769
 
770
+ // src/wallets/FreighterAdapter.ts
771
+ var import_freighter_api = __toESM(require_index_min());
772
+
773
+ // src/wallets/types.ts
774
+ var WalletType = /* @__PURE__ */ ((WalletType2) => {
775
+ WalletType2["FREIGHTER"] = "freighter";
776
+ WalletType2["ALBEDO"] = "albedo";
777
+ return WalletType2;
778
+ })(WalletType || {});
779
+
780
+ // src/wallets/FreighterAdapter.ts
781
+ var FreighterAdapter = class {
782
+ constructor() {
783
+ this.type = "freighter" /* FREIGHTER */;
784
+ }
785
+ async isAvailable() {
786
+ try {
787
+ return await (0, import_freighter_api.isConnected)();
788
+ } catch {
789
+ return false;
790
+ }
791
+ }
792
+ async connect() {
793
+ const connected = await (0, import_freighter_api.isConnected)();
794
+ if (!connected) {
795
+ throw new Error("Freighter wallet is not installed");
796
+ }
797
+ const allowed = await (0, import_freighter_api.isAllowed)();
798
+ if (!allowed) {
799
+ await (0, import_freighter_api.setAllowed)();
800
+ }
801
+ const userInfo = await (0, import_freighter_api.getUserInfo)();
802
+ if (!userInfo?.publicKey) {
803
+ throw new Error("Failed to get user information from Freighter");
804
+ }
805
+ return { address: userInfo.publicKey, publicKey: userInfo.publicKey };
806
+ }
807
+ async disconnect() {
808
+ }
809
+ async getPublicKey() {
810
+ try {
811
+ const allowed = await (0, import_freighter_api.isAllowed)();
812
+ if (!allowed) return null;
813
+ const userInfo = await (0, import_freighter_api.getUserInfo)();
814
+ return userInfo?.publicKey ?? null;
815
+ } catch {
816
+ return null;
817
+ }
818
+ }
819
+ async getNetwork() {
820
+ return (0, import_freighter_api.getNetwork)();
821
+ }
822
+ async signTransaction(xdr, options) {
823
+ const result = await (0, import_freighter_api.signTransaction)(xdr, {
824
+ network: options?.network,
825
+ networkPassphrase: options?.networkPassphrase,
826
+ accountToSign: options?.accountToSign
827
+ });
828
+ if (!result || typeof result !== "string") {
829
+ throw new Error("Invalid response from Freighter");
830
+ }
831
+ return { signedTxXdr: result };
832
+ }
833
+ async signAuthEntry(entryXdr, options) {
834
+ const result = await (0, import_freighter_api.signAuthEntry)(entryXdr, { accountToSign: options?.accountToSign });
835
+ if (!result || typeof result !== "string") {
836
+ throw new Error("Invalid response from Freighter");
837
+ }
838
+ return { signedAuthEntry: result };
839
+ }
840
+ };
841
+
842
+ // src/wallets/AlbedoAdapter.ts
843
+ function openAlbedoPopup(url) {
844
+ const popup = window.open(url, "albedo", "width=420,height=720,resizable=yes,scrollbars=yes");
845
+ if (!popup) {
846
+ throw new Error("Failed to open Albedo popup (blocked by browser)");
847
+ }
848
+ return popup;
849
+ }
850
+ function waitForAlbedoPopup() {
851
+ return new Promise((resolve, reject) => {
852
+ const timeout = setTimeout(() => reject(new Error("Albedo response timeout")), 2 * 60 * 1e3);
853
+ function handler(event) {
854
+ if (event.origin !== window.location.origin || event.data?.type !== "ALBEDO_RESULT") return;
855
+ clearTimeout(timeout);
856
+ window.removeEventListener("message", handler);
857
+ resolve(event.data.payload);
858
+ }
859
+ window.addEventListener("message", handler);
860
+ });
861
+ }
862
+ function waitForAlbedoResult() {
863
+ return new Promise((resolve, reject) => {
864
+ const timeout = setTimeout(() => reject(new Error("Albedo response timeout")), 2 * 60 * 1e3);
865
+ const parseResult = () => {
866
+ const params = new URLSearchParams(window.location.search);
867
+ if (!params.has("pubkey") && !params.has("signed_envelope_xdr") && !params.has("signed_xdr")) return;
868
+ clearTimeout(timeout);
869
+ const result = {};
870
+ params.forEach((value, key) => {
871
+ result[key] = value;
872
+ });
873
+ window.history.replaceState({}, document.title, window.location.pathname);
874
+ resolve(result);
875
+ };
876
+ parseResult();
877
+ window.addEventListener("popstate", parseResult);
878
+ });
879
+ }
880
+ var AlbedoAdapter = class {
881
+ constructor() {
882
+ this.type = "albedo" /* ALBEDO */;
883
+ }
884
+ async isAvailable() {
885
+ return typeof window !== "undefined";
886
+ }
887
+ async connect() {
888
+ const url = new URL("https://albedo.link");
889
+ url.searchParams.set("intent", "public-key");
890
+ url.searchParams.set("app_name", "Pollar");
891
+ url.searchParams.set("network", "testnet");
892
+ url.searchParams.set("callback", `${window.location.origin}/albedo-callback`);
893
+ url.searchParams.set("origin", window.location.origin);
894
+ openAlbedoPopup(url.toString());
895
+ const result = await waitForAlbedoPopup();
896
+ if (!result.pubkey) {
897
+ throw new Error("Albedo connection rejected");
898
+ }
899
+ return { address: result.pubkey, publicKey: result.pubkey };
900
+ }
901
+ async disconnect() {
902
+ }
903
+ async getPublicKey() {
904
+ return null;
905
+ }
906
+ async getNetwork() {
907
+ throw new Error("Albedo does not expose network");
908
+ }
909
+ async signTransaction(xdr, _options) {
910
+ const url = new URL("https://albedo.link");
911
+ url.searchParams.set("intent", "tx");
912
+ url.searchParams.set("xdr", xdr);
913
+ url.searchParams.set("app_name", "Pollar");
914
+ url.searchParams.set("network", "testnet");
915
+ url.searchParams.set("callback", window.location.href);
916
+ url.searchParams.set("origin", window.location.origin);
917
+ window.location.href = url.toString();
918
+ const result = await waitForAlbedoResult();
919
+ if (!result.signed_envelope_xdr) throw new Error("Albedo signing rejected");
920
+ return { signedTxXdr: result.signed_envelope_xdr };
921
+ }
922
+ async signAuthEntry(entryXdr, _options) {
923
+ const url = new URL("https://albedo.link");
924
+ url.searchParams.set("intent", "sign-auth-entry");
925
+ url.searchParams.set("xdr", entryXdr);
926
+ url.searchParams.set("app_name", "Pollar");
927
+ url.searchParams.set("network", "testnet");
928
+ url.searchParams.set("callback", window.location.href);
929
+ url.searchParams.set("origin", window.location.origin);
930
+ window.location.href = url.toString();
931
+ const result = await waitForAlbedoResult();
932
+ if (!result.signed_xdr) throw new Error("Albedo auth entry signing rejected");
933
+ return { signedAuthEntry: result.signed_xdr };
934
+ }
935
+ };
936
+
770
937
  // src/client/session.ts
771
938
  var STORAGE_KEY = "pollar:session";
939
+ var WALLET_TYPE_KEY = "pollar:walletType";
772
940
  function isValidSession(value) {
773
941
  if (typeof value !== "object" || value === null) {
774
942
  console.warn("[PollarClient:session] Invalid session \u2014 value is not an object");
@@ -904,8 +1072,15 @@ function writeStorage(session) {
904
1072
  }
905
1073
  function removeStorage() {
906
1074
  localStorage.removeItem(STORAGE_KEY);
1075
+ localStorage.removeItem(WALLET_TYPE_KEY);
907
1076
  console.info("[PollarClient:session] Session removed from storage");
908
1077
  }
1078
+ function writeWalletType(type) {
1079
+ localStorage.setItem(WALLET_TYPE_KEY, type);
1080
+ }
1081
+ function readWalletType() {
1082
+ return localStorage.getItem(WALLET_TYPE_KEY);
1083
+ }
909
1084
 
910
1085
  // src/client/stream.ts
911
1086
  function abortableDelay(ms, signal) {
@@ -979,7 +1154,7 @@ async function streamUntilFound(api, clientSessionId, check, retryDelayMs = 200,
979
1154
  }
980
1155
 
981
1156
  // src/client/auth/authenticate.ts
982
- async function authenticate(clientSessionId, deps) {
1157
+ async function authenticate(clientSessionId, deps, expectedWallet) {
983
1158
  const { api, signal, setAuthState, storeSession, clearSession } = deps;
984
1159
  setAuthState({ step: "authenticating" });
985
1160
  await streamUntilFound(api, clientSessionId, (data2) => data2?.status === "READY", 200, signal);
@@ -988,6 +1163,16 @@ async function authenticate(clientSessionId, deps) {
988
1163
  signal
989
1164
  });
990
1165
  if (data?.code === "SDK_LOGIN_SUCCESS" && isValidSession(data?.content)) {
1166
+ if (expectedWallet && data.content.data.providers.wallet?.address !== expectedWallet) {
1167
+ setAuthState({
1168
+ step: "error",
1169
+ previousStep: "authenticating",
1170
+ message: "Wallet mismatch: session wallet does not match connected wallet",
1171
+ errorCode: AUTH_ERROR_CODES.WALLET_AUTH_FAILED
1172
+ });
1173
+ clearSession();
1174
+ return;
1175
+ }
991
1176
  storeSession(data.content);
992
1177
  } else {
993
1178
  setAuthState({
@@ -1105,173 +1290,6 @@ async function loginOAuth(provider, deps) {
1105
1290
  await authenticate(clientSessionId, deps);
1106
1291
  }
1107
1292
 
1108
- // src/wallets/FreighterAdapter.ts
1109
- var import_freighter_api = __toESM(require_index_min());
1110
-
1111
- // src/wallets/types.ts
1112
- var WalletType = /* @__PURE__ */ ((WalletType2) => {
1113
- WalletType2["FREIGHTER"] = "freighter";
1114
- WalletType2["ALBEDO"] = "albedo";
1115
- return WalletType2;
1116
- })(WalletType || {});
1117
-
1118
- // src/wallets/FreighterAdapter.ts
1119
- var FreighterAdapter = class {
1120
- constructor() {
1121
- this.type = "freighter" /* FREIGHTER */;
1122
- }
1123
- async isAvailable() {
1124
- try {
1125
- return await (0, import_freighter_api.isConnected)();
1126
- } catch {
1127
- return false;
1128
- }
1129
- }
1130
- async connect() {
1131
- const connected = await (0, import_freighter_api.isConnected)();
1132
- if (!connected) {
1133
- throw new Error("Freighter wallet is not installed");
1134
- }
1135
- const allowed = await (0, import_freighter_api.isAllowed)();
1136
- if (!allowed) {
1137
- await (0, import_freighter_api.setAllowed)();
1138
- }
1139
- const userInfo = await (0, import_freighter_api.getUserInfo)();
1140
- if (!userInfo?.publicKey) {
1141
- throw new Error("Failed to get user information from Freighter");
1142
- }
1143
- return { address: userInfo.publicKey, publicKey: userInfo.publicKey };
1144
- }
1145
- async disconnect() {
1146
- }
1147
- async getPublicKey() {
1148
- try {
1149
- const allowed = await (0, import_freighter_api.isAllowed)();
1150
- if (!allowed) return null;
1151
- const userInfo = await (0, import_freighter_api.getUserInfo)();
1152
- return userInfo?.publicKey ?? null;
1153
- } catch {
1154
- return null;
1155
- }
1156
- }
1157
- async getNetwork() {
1158
- return (0, import_freighter_api.getNetwork)();
1159
- }
1160
- async signTransaction(xdr, options) {
1161
- const result = await (0, import_freighter_api.signTransaction)(xdr, {
1162
- network: options?.network,
1163
- networkPassphrase: options?.networkPassphrase,
1164
- accountToSign: options?.accountToSign
1165
- });
1166
- if (!result || typeof result !== "string") {
1167
- throw new Error("Invalid response from Freighter");
1168
- }
1169
- return { signedTxXdr: result };
1170
- }
1171
- async signAuthEntry(entryXdr, options) {
1172
- const result = await (0, import_freighter_api.signAuthEntry)(entryXdr, { accountToSign: options?.accountToSign });
1173
- if (!result || typeof result !== "string") {
1174
- throw new Error("Invalid response from Freighter");
1175
- }
1176
- return { signedAuthEntry: result };
1177
- }
1178
- };
1179
-
1180
- // src/wallets/AlbedoAdapter.ts
1181
- function openAlbedoPopup(url) {
1182
- const popup = window.open(url, "albedo", "width=420,height=720,resizable=yes,scrollbars=yes");
1183
- if (!popup) {
1184
- throw new Error("Failed to open Albedo popup (blocked by browser)");
1185
- }
1186
- return popup;
1187
- }
1188
- function waitForAlbedoPopup() {
1189
- return new Promise((resolve, reject) => {
1190
- const timeout = setTimeout(() => reject(new Error("Albedo response timeout")), 2 * 60 * 1e3);
1191
- function handler(event) {
1192
- if (event.origin !== window.location.origin || event.data?.type !== "ALBEDO_RESULT") return;
1193
- clearTimeout(timeout);
1194
- window.removeEventListener("message", handler);
1195
- resolve(event.data.payload);
1196
- }
1197
- window.addEventListener("message", handler);
1198
- });
1199
- }
1200
- function waitForAlbedoResult() {
1201
- return new Promise((resolve, reject) => {
1202
- const timeout = setTimeout(() => reject(new Error("Albedo response timeout")), 2 * 60 * 1e3);
1203
- const parseResult = () => {
1204
- const params = new URLSearchParams(window.location.search);
1205
- if (!params.has("pubkey") && !params.has("signed_envelope_xdr") && !params.has("signed_xdr")) return;
1206
- clearTimeout(timeout);
1207
- const result = {};
1208
- params.forEach((value, key) => {
1209
- result[key] = value;
1210
- });
1211
- window.history.replaceState({}, document.title, window.location.pathname);
1212
- resolve(result);
1213
- };
1214
- parseResult();
1215
- window.addEventListener("popstate", parseResult);
1216
- });
1217
- }
1218
- var AlbedoAdapter = class {
1219
- constructor() {
1220
- this.type = "albedo" /* ALBEDO */;
1221
- }
1222
- async isAvailable() {
1223
- return typeof window !== "undefined";
1224
- }
1225
- async connect() {
1226
- const url = new URL("https://albedo.link");
1227
- url.searchParams.set("intent", "public-key");
1228
- url.searchParams.set("app_name", "Pollar");
1229
- url.searchParams.set("network", "testnet");
1230
- url.searchParams.set("callback", `${window.location.origin}/albedo-callback`);
1231
- url.searchParams.set("origin", window.location.origin);
1232
- openAlbedoPopup(url.toString());
1233
- const result = await waitForAlbedoPopup();
1234
- if (!result.pubkey) {
1235
- throw new Error("Albedo connection rejected");
1236
- }
1237
- return { address: result.pubkey, publicKey: result.pubkey };
1238
- }
1239
- async disconnect() {
1240
- }
1241
- async getPublicKey() {
1242
- return null;
1243
- }
1244
- async getNetwork() {
1245
- throw new Error("Albedo does not expose network");
1246
- }
1247
- async signTransaction(xdr, _options) {
1248
- const url = new URL("https://albedo.link");
1249
- url.searchParams.set("intent", "tx");
1250
- url.searchParams.set("xdr", xdr);
1251
- url.searchParams.set("app_name", "Pollar");
1252
- url.searchParams.set("network", "testnet");
1253
- url.searchParams.set("callback", window.location.href);
1254
- url.searchParams.set("origin", window.location.origin);
1255
- window.location.href = url.toString();
1256
- const result = await waitForAlbedoResult();
1257
- if (!result.signed_envelope_xdr) throw new Error("Albedo signing rejected");
1258
- return { signedTxXdr: result.signed_envelope_xdr };
1259
- }
1260
- async signAuthEntry(entryXdr, _options) {
1261
- const url = new URL("https://albedo.link");
1262
- url.searchParams.set("intent", "sign-auth-entry");
1263
- url.searchParams.set("xdr", entryXdr);
1264
- url.searchParams.set("app_name", "Pollar");
1265
- url.searchParams.set("network", "testnet");
1266
- url.searchParams.set("callback", window.location.href);
1267
- url.searchParams.set("origin", window.location.origin);
1268
- window.location.href = url.toString();
1269
- const result = await waitForAlbedoResult();
1270
- if (!result.signed_xdr) throw new Error("Albedo auth entry signing rejected");
1271
- return { signedAuthEntry: result.signed_xdr };
1272
- }
1273
- };
1274
-
1275
1293
  // src/client/auth/walletFlow.ts
1276
1294
  function withSignal(promise, signal) {
1277
1295
  return Promise.race([
@@ -1289,6 +1307,7 @@ async function loginWallet(type, deps) {
1289
1307
  const { api, signal, setAuthState } = deps;
1290
1308
  const clientSessionId = await createAuthSession(deps);
1291
1309
  if (!clientSessionId) return;
1310
+ let connectedWallet;
1292
1311
  try {
1293
1312
  setAuthState({ step: "connecting_wallet", walletType: type });
1294
1313
  const adapter = type === "freighter" /* FREIGHTER */ ? new FreighterAdapter() : new AlbedoAdapter();
@@ -1298,7 +1317,8 @@ async function loginWallet(type, deps) {
1298
1317
  return;
1299
1318
  }
1300
1319
  const { publicKey } = await withSignal(adapter.connect(), signal);
1301
- deps.storeWalletAdapter(adapter);
1320
+ connectedWallet = publicKey;
1321
+ deps.storeWalletAdapter(adapter, type);
1302
1322
  setAuthState({ step: "authenticating_wallet" });
1303
1323
  const { data: walletData, error: walletError } = await api.POST("/auth/wallet", {
1304
1324
  body: { clientSessionId, walletAddress: publicKey },
@@ -1322,7 +1342,7 @@ async function loginWallet(type, deps) {
1322
1342
  });
1323
1343
  return;
1324
1344
  }
1325
- await authenticate(clientSessionId, deps);
1345
+ await authenticate(clientSessionId, deps, connectedWallet);
1326
1346
  }
1327
1347
 
1328
1348
  // src/client/client.ts
@@ -1339,6 +1359,8 @@ var PollarClient = class {
1339
1359
  this._transactionStateListeners = /* @__PURE__ */ new Set();
1340
1360
  this._txHistoryState = { step: "idle" };
1341
1361
  this._txHistoryStateListeners = /* @__PURE__ */ new Set();
1362
+ this._walletBalanceState = { step: "idle" };
1363
+ this._walletBalanceStateListeners = /* @__PURE__ */ new Set();
1342
1364
  this._authState = { step: "idle" };
1343
1365
  this._authStateListeners = /* @__PURE__ */ new Set();
1344
1366
  this._networkState = { step: "idle" };
@@ -1499,10 +1521,6 @@ var PollarClient = class {
1499
1521
  return () => this._transactionStateListeners.delete(cb);
1500
1522
  }
1501
1523
  // ─── Tx history ──────────────────────────────────────────────────────────
1502
- _setTxHistoryState(next) {
1503
- this._txHistoryState = next;
1504
- for (const cb of this._txHistoryStateListeners) cb(next);
1505
- }
1506
1524
  getTxHistoryState() {
1507
1525
  return this._txHistoryState;
1508
1526
  }
@@ -1526,13 +1544,32 @@ var PollarClient = class {
1526
1544
  }
1527
1545
  }
1528
1546
  // ─── Wallet balance ───────────────────────────────────────────────────────
1529
- async getWalletBalance(publicKey) {
1547
+ getWalletBalanceState() {
1548
+ return this._walletBalanceState;
1549
+ }
1550
+ onWalletBalanceStateChange(cb) {
1551
+ this._walletBalanceStateListeners.add(cb);
1552
+ cb(this._walletBalanceState);
1553
+ return () => this._walletBalanceStateListeners.delete(cb);
1554
+ }
1555
+ async refreshBalance(publicKey) {
1530
1556
  const pk = publicKey ?? this._session?.wallet?.publicKey;
1531
- if (!pk) return null;
1532
- const network = this.getNetwork();
1533
- const { data, error } = await this._api.GET("/wallet/balance", { params: { query: { publicKey: pk, network } } });
1534
- if (!error && data?.success && data.content) return data.content;
1535
- return null;
1557
+ if (!pk) {
1558
+ this._setWalletBalanceState({ step: "error", message: "No wallet connected" });
1559
+ return;
1560
+ }
1561
+ this._setWalletBalanceState({ step: "loading" });
1562
+ try {
1563
+ const network = this.getNetwork();
1564
+ const { data, error } = await this._api.GET("/wallet/balance", { params: { query: { publicKey: pk, network } } });
1565
+ if (!error && data?.success && data.content) {
1566
+ this._setWalletBalanceState({ step: "loaded", data: data.content });
1567
+ } else {
1568
+ this._setWalletBalanceState({ step: "error", message: "Failed to load balance" });
1569
+ }
1570
+ } catch {
1571
+ this._setWalletBalanceState({ step: "error", message: "Failed to load balance" });
1572
+ }
1536
1573
  }
1537
1574
  // ─── Transactions ─────────────────────────────────────────────────────────
1538
1575
  async buildTx(operation, params, options) {
@@ -1560,27 +1597,29 @@ var PollarClient = class {
1560
1597
  this._setTransactionState({ step: "error" });
1561
1598
  }
1562
1599
  }
1600
+ getWalletType() {
1601
+ return this._walletAdapter?.type ?? null;
1602
+ }
1563
1603
  async signAndSubmitTx(unsignedXdr) {
1564
- if (this._transactionState?.step !== "built") {
1565
- throw new PollarFlowError(
1566
- `signAndSubmitTx() requires step 'built', current step is '${this._transactionState?.step ?? "none"}'`
1567
- );
1568
- }
1569
- const buildData = this._transactionState.buildData;
1570
- this._setTransactionState({ step: "signing", buildData });
1604
+ const state = this._transactionState;
1605
+ const buildData = state?.step === "built" ? state.buildData : state?.step === "error" ? state.buildData : void 0;
1606
+ const isBuiltFlow = !!buildData;
1607
+ const stateExtra = buildData ? { buildData } : { external: true };
1608
+ this._setTransactionState({ step: "signing", ...stateExtra });
1609
+ const accountToSign = isBuiltFlow ? this._session?.wallet?.publicKey : this._session?.data?.providers?.wallet?.address ?? this._session?.wallet?.publicKey;
1571
1610
  if (this._walletAdapter) {
1572
1611
  try {
1573
- const signOpts = this._session?.wallet?.publicKey ? { networkPassphrase: this._networkPassphrase(), accountToSign: this._session.wallet.publicKey } : { networkPassphrase: this._networkPassphrase() };
1612
+ const signOpts = accountToSign ? { networkPassphrase: this._networkPassphrase(), accountToSign } : { networkPassphrase: this._networkPassphrase() };
1574
1613
  const { signedTxXdr } = await this._walletAdapter.signTransaction(unsignedXdr, signOpts);
1575
1614
  const stellarClient = new StellarClient(this.getNetwork());
1576
1615
  const result = await stellarClient.submitTransaction(signedTxXdr);
1577
1616
  if (result.success) {
1578
- this._setTransactionState({ step: "success", buildData, hash: result.hash });
1617
+ this._setTransactionState({ step: "success", ...stateExtra, hash: result.hash });
1579
1618
  } else {
1580
- this._setTransactionState({ step: "error", ...buildData && { buildData }, details: result.errorCode });
1619
+ this._setTransactionState({ step: "error", ...stateExtra, details: result.errorCode });
1581
1620
  }
1582
1621
  } catch {
1583
- this._setTransactionState({ step: "error", ...buildData && { buildData } });
1622
+ this._setTransactionState({ step: "error", ...stateExtra });
1584
1623
  }
1585
1624
  return;
1586
1625
  }
@@ -1592,13 +1631,13 @@ var PollarClient = class {
1592
1631
  try {
1593
1632
  const { data, error } = await this._api.POST("/tx/sign-and-send", { body });
1594
1633
  if (!error && data?.success && data.content?.hash) {
1595
- this._setTransactionState({ step: "success", buildData, hash: data.content.hash });
1634
+ this._setTransactionState({ step: "success", ...stateExtra, hash: data.content.hash });
1596
1635
  } else {
1597
1636
  const details = error?.details;
1598
- this._setTransactionState({ step: "error", ...buildData && { buildData }, ...details && { details } });
1637
+ this._setTransactionState({ step: "error", ...stateExtra, ...details && { details } });
1599
1638
  }
1600
1639
  } catch {
1601
- this._setTransactionState({ step: "error", ...buildData && { buildData } });
1640
+ this._setTransactionState({ step: "error", ...stateExtra });
1602
1641
  }
1603
1642
  }
1604
1643
  // ─── App config ───────────────────────────────────────────────────────────
@@ -1643,6 +1682,14 @@ var PollarClient = class {
1643
1682
  pollRampTransaction(txId, opts) {
1644
1683
  return pollRampTransaction(this._api, txId, opts);
1645
1684
  }
1685
+ _setTxHistoryState(next) {
1686
+ this._txHistoryState = next;
1687
+ for (const cb of this._txHistoryStateListeners) cb(next);
1688
+ }
1689
+ _setWalletBalanceState(next) {
1690
+ this._walletBalanceState = next;
1691
+ for (const cb of this._walletBalanceStateListeners) cb(next);
1692
+ }
1646
1693
  // ─── Private ──────────────────────────────────────────────────────────────
1647
1694
  /** Creates a new AbortController, cancelling any existing flow first. */
1648
1695
  _newController() {
@@ -1658,8 +1705,9 @@ var PollarClient = class {
1658
1705
  setAuthState: this._setAuthState.bind(this),
1659
1706
  storeSession: this._storeSession.bind(this),
1660
1707
  clearSession: this._clearSession.bind(this),
1661
- storeWalletAdapter: (adapter) => {
1708
+ storeWalletAdapter: (adapter, type) => {
1662
1709
  this._walletAdapter = adapter;
1710
+ writeWalletType(type);
1663
1711
  }
1664
1712
  };
1665
1713
  }
@@ -1681,6 +1729,14 @@ var PollarClient = class {
1681
1729
  this._session = readStorage();
1682
1730
  if (this._session) {
1683
1731
  this._authState = { step: "authenticated", session: this._session };
1732
+ if (this._session.data?.providers?.wallet?.address) {
1733
+ const storedType = readWalletType();
1734
+ if (storedType === "freighter" /* FREIGHTER */) {
1735
+ this._walletAdapter = new FreighterAdapter();
1736
+ } else if (storedType === "albedo" /* ALBEDO */) {
1737
+ this._walletAdapter = new AlbedoAdapter();
1738
+ }
1739
+ }
1684
1740
  console.info("[PollarClient] Session restored from storage");
1685
1741
  } else {
1686
1742
  console.info("[PollarClient] No session in storage");