@pollar/core 0.4.5 → 0.5.2

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
@@ -650,31 +650,98 @@ function createApiClient(baseUrl) {
650
650
  return createClient({ baseUrl });
651
651
  }
652
652
 
653
- // src/constants.ts
654
- var StateStatus = {
655
- NONE: "NONE",
656
- LOADING: "LOADING",
657
- SUCCESS: "SUCCESS",
658
- ERROR: "ERROR"
659
- };
660
- var PollarStateVar = {
661
- NETWORK: "network",
662
- TRANSACTION: "transaction"
653
+ // src/api/endpoints/kyc.ts
654
+ async function getKycStatus(api, providerId) {
655
+ const { data, error } = await api.GET("/kyc/status", {
656
+ params: { query: providerId ? { providerId } : {} }
657
+ });
658
+ if (!data?.content || error) {
659
+ throw new Error(error?.error ?? "Failed to get KYC status");
660
+ }
661
+ return data.content;
662
+ }
663
+ async function getKycProviders(api, country) {
664
+ const { data, error } = await api.GET("/kyc/providers", { params: { query: { country } } });
665
+ if (!data?.content || error) throw new Error(error?.error ?? "Failed to get KYC providers");
666
+ return data.content;
667
+ }
668
+ async function startKyc(api, body) {
669
+ const { data, error } = await api.POST("/kyc/start", { body });
670
+ if (!data?.content || error) throw new Error(error?.error ?? "Failed to start KYC");
671
+ return data.content;
672
+ }
673
+ async function resolveKyc(api, providerId, level = "basic") {
674
+ const { status } = await getKycStatus(api, providerId);
675
+ if (status === "approved") return { alreadyApproved: true };
676
+ const started = await startKyc(api, { providerId, level });
677
+ return { alreadyApproved: false, ...started };
678
+ }
679
+ async function pollKycStatus(api, providerId, { intervalMs = 3e3, timeoutMs = 3e5 } = {}) {
680
+ const deadline = Date.now() + timeoutMs;
681
+ while (Date.now() < deadline) {
682
+ const { status } = await getKycStatus(api, providerId);
683
+ if (status === "approved" || status === "rejected") return status;
684
+ await new Promise((r) => setTimeout(r, intervalMs));
685
+ }
686
+ throw new Error("KYC polling timed out");
687
+ }
688
+
689
+ // src/api/endpoints/ramps.ts
690
+ async function getRampsQuote(api, query) {
691
+ const { data, error } = await api.GET("/ramps/quote", { params: { query } });
692
+ if (!data?.content || error) throw new Error(error?.error ?? "Failed to get ramp quotes");
693
+ return data.content;
694
+ }
695
+ async function createOnRamp(api, body) {
696
+ const { data, error } = await api.POST("/ramps/onramp", { body });
697
+ if (!data?.content || error) throw new Error(error?.error ?? "Failed to create onramp");
698
+ return data.content;
699
+ }
700
+ async function createOffRamp(api, body) {
701
+ const { data, error } = await api.POST("/ramps/offramp", { body });
702
+ if (!data?.content || error) throw new Error(error?.error ?? "Failed to create offramp");
703
+ return data.content;
704
+ }
705
+ async function getRampTransaction(api, txId) {
706
+ const { data, error } = await api.GET("/ramps/transaction/{txId}", { params: { path: { txId } } });
707
+ if (!data?.content || error) throw new Error(error?.error ?? "Failed to get transaction");
708
+ return data.content;
709
+ }
710
+ async function pollRampTransaction(api, txId, { intervalMs = 5e3, timeoutMs = 6e5 } = {}) {
711
+ const deadline = Date.now() + timeoutMs;
712
+ while (Date.now() < deadline) {
713
+ const { status } = await getRampTransaction(api, txId);
714
+ if (status === "completed" || status === "failed") return status;
715
+ await new Promise((r) => setTimeout(r, intervalMs));
716
+ }
717
+ throw new Error("Ramp transaction polling timed out");
718
+ }
719
+
720
+ // src/stellar/StellarClient.ts
721
+ var HORIZON_URLS = {
722
+ mainnet: "https://horizon.stellar.org",
723
+ testnet: "https://horizon-testnet.stellar.org"
663
724
  };
664
- var STATE_VAR_CODES = {
665
- transaction: {
666
- NONE: "NONE",
667
- BUILD_TRANSACTION_ERROR_NO_WALLET: "BUILD_TRANSACTION_ERROR_NO_WALLET",
668
- BUILD_TRANSACTION_START: "BUILD_TRANSACTION_START",
669
- BUILD_TRANSACTION_SUCCESS: "BUILD_TRANSACTION_SUCCESS",
670
- BUILD_TRANSACTION_ERROR: "BUILD_TRANSACTION_ERROR",
671
- SIGN_SEND_TRANSACTION_START: "SIGN_SEND_TRANSACTION_START",
672
- SIGN_SEND_TRANSACTION_SUCCESS: "SIGN_SEND_TRANSACTION_SUCCESS",
673
- SIGN_SEND_TRANSACTION_ERROR: "SIGN_SEND_TRANSACTION_ERROR"
674
- },
675
- network: {
676
- NONE: "NONE",
677
- NETWORK_UPDATED: "NETWORK_UPDATED"
725
+ var StellarClient = class {
726
+ constructor(config) {
727
+ this.horizonUrl = typeof config === "string" ? HORIZON_URLS[config] : config.horizonUrl;
728
+ }
729
+ async submitTransaction(signedXdr) {
730
+ try {
731
+ const response = await fetch(`${this.horizonUrl}/transactions`, {
732
+ method: "POST",
733
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
734
+ body: new URLSearchParams({ tx: signedXdr })
735
+ });
736
+ if (!response.ok) {
737
+ const body = await response.json().catch(() => ({}));
738
+ return { success: false, errorCode: body.extras?.result_codes?.transaction ?? "HORIZON_ERROR" };
739
+ }
740
+ const data = await response.json();
741
+ return { success: true, hash: data.hash };
742
+ } catch {
743
+ return { success: false, errorCode: "NETWORK_ERROR" };
744
+ }
678
745
  }
679
746
  };
680
747
 
@@ -698,8 +765,176 @@ var PollarFlowError = class extends Error {
698
765
  }
699
766
  };
700
767
 
768
+ // src/wallets/FreighterAdapter.ts
769
+ var import_freighter_api = __toESM(require_index_min());
770
+
771
+ // src/wallets/types.ts
772
+ var WalletType = /* @__PURE__ */ ((WalletType2) => {
773
+ WalletType2["FREIGHTER"] = "freighter";
774
+ WalletType2["ALBEDO"] = "albedo";
775
+ return WalletType2;
776
+ })(WalletType || {});
777
+
778
+ // src/wallets/FreighterAdapter.ts
779
+ var FreighterAdapter = class {
780
+ constructor() {
781
+ this.type = "freighter" /* FREIGHTER */;
782
+ }
783
+ async isAvailable() {
784
+ try {
785
+ return await (0, import_freighter_api.isConnected)();
786
+ } catch {
787
+ return false;
788
+ }
789
+ }
790
+ async connect() {
791
+ const connected = await (0, import_freighter_api.isConnected)();
792
+ if (!connected) {
793
+ throw new Error("Freighter wallet is not installed");
794
+ }
795
+ const allowed = await (0, import_freighter_api.isAllowed)();
796
+ if (!allowed) {
797
+ await (0, import_freighter_api.setAllowed)();
798
+ }
799
+ const userInfo = await (0, import_freighter_api.getUserInfo)();
800
+ if (!userInfo?.publicKey) {
801
+ throw new Error("Failed to get user information from Freighter");
802
+ }
803
+ return { address: userInfo.publicKey, publicKey: userInfo.publicKey };
804
+ }
805
+ async disconnect() {
806
+ }
807
+ async getPublicKey() {
808
+ try {
809
+ const allowed = await (0, import_freighter_api.isAllowed)();
810
+ if (!allowed) return null;
811
+ const userInfo = await (0, import_freighter_api.getUserInfo)();
812
+ return userInfo?.publicKey ?? null;
813
+ } catch {
814
+ return null;
815
+ }
816
+ }
817
+ async getNetwork() {
818
+ return (0, import_freighter_api.getNetwork)();
819
+ }
820
+ async signTransaction(xdr, options) {
821
+ const result = await (0, import_freighter_api.signTransaction)(xdr, {
822
+ network: options?.network,
823
+ networkPassphrase: options?.networkPassphrase,
824
+ accountToSign: options?.accountToSign
825
+ });
826
+ if (!result || typeof result !== "string") {
827
+ throw new Error("Invalid response from Freighter");
828
+ }
829
+ return { signedTxXdr: result };
830
+ }
831
+ async signAuthEntry(entryXdr, options) {
832
+ const result = await (0, import_freighter_api.signAuthEntry)(entryXdr, { accountToSign: options?.accountToSign });
833
+ if (!result || typeof result !== "string") {
834
+ throw new Error("Invalid response from Freighter");
835
+ }
836
+ return { signedAuthEntry: result };
837
+ }
838
+ };
839
+
840
+ // src/wallets/AlbedoAdapter.ts
841
+ function openAlbedoPopup(url) {
842
+ const popup = window.open(url, "albedo", "width=420,height=720,resizable=yes,scrollbars=yes");
843
+ if (!popup) {
844
+ throw new Error("Failed to open Albedo popup (blocked by browser)");
845
+ }
846
+ return popup;
847
+ }
848
+ function waitForAlbedoPopup() {
849
+ return new Promise((resolve, reject) => {
850
+ const timeout = setTimeout(() => reject(new Error("Albedo response timeout")), 2 * 60 * 1e3);
851
+ function handler(event) {
852
+ if (event.origin !== window.location.origin || event.data?.type !== "ALBEDO_RESULT") return;
853
+ clearTimeout(timeout);
854
+ window.removeEventListener("message", handler);
855
+ resolve(event.data.payload);
856
+ }
857
+ window.addEventListener("message", handler);
858
+ });
859
+ }
860
+ function waitForAlbedoResult() {
861
+ return new Promise((resolve, reject) => {
862
+ const timeout = setTimeout(() => reject(new Error("Albedo response timeout")), 2 * 60 * 1e3);
863
+ const parseResult = () => {
864
+ const params = new URLSearchParams(window.location.search);
865
+ if (!params.has("pubkey") && !params.has("signed_envelope_xdr") && !params.has("signed_xdr")) return;
866
+ clearTimeout(timeout);
867
+ const result = {};
868
+ params.forEach((value, key) => {
869
+ result[key] = value;
870
+ });
871
+ window.history.replaceState({}, document.title, window.location.pathname);
872
+ resolve(result);
873
+ };
874
+ parseResult();
875
+ window.addEventListener("popstate", parseResult);
876
+ });
877
+ }
878
+ var AlbedoAdapter = class {
879
+ constructor() {
880
+ this.type = "albedo" /* ALBEDO */;
881
+ }
882
+ async isAvailable() {
883
+ return typeof window !== "undefined";
884
+ }
885
+ async connect() {
886
+ const url = new URL("https://albedo.link");
887
+ url.searchParams.set("intent", "public-key");
888
+ url.searchParams.set("app_name", "Pollar");
889
+ url.searchParams.set("network", "testnet");
890
+ url.searchParams.set("callback", `${window.location.origin}/albedo-callback`);
891
+ url.searchParams.set("origin", window.location.origin);
892
+ openAlbedoPopup(url.toString());
893
+ const result = await waitForAlbedoPopup();
894
+ if (!result.pubkey) {
895
+ throw new Error("Albedo connection rejected");
896
+ }
897
+ return { address: result.pubkey, publicKey: result.pubkey };
898
+ }
899
+ async disconnect() {
900
+ }
901
+ async getPublicKey() {
902
+ return null;
903
+ }
904
+ async getNetwork() {
905
+ throw new Error("Albedo does not expose network");
906
+ }
907
+ async signTransaction(xdr, _options) {
908
+ const url = new URL("https://albedo.link");
909
+ url.searchParams.set("intent", "tx");
910
+ url.searchParams.set("xdr", xdr);
911
+ url.searchParams.set("app_name", "Pollar");
912
+ url.searchParams.set("network", "testnet");
913
+ url.searchParams.set("callback", window.location.href);
914
+ url.searchParams.set("origin", window.location.origin);
915
+ window.location.href = url.toString();
916
+ const result = await waitForAlbedoResult();
917
+ if (!result.signed_envelope_xdr) throw new Error("Albedo signing rejected");
918
+ return { signedTxXdr: result.signed_envelope_xdr };
919
+ }
920
+ async signAuthEntry(entryXdr, _options) {
921
+ const url = new URL("https://albedo.link");
922
+ url.searchParams.set("intent", "sign-auth-entry");
923
+ url.searchParams.set("xdr", entryXdr);
924
+ url.searchParams.set("app_name", "Pollar");
925
+ url.searchParams.set("network", "testnet");
926
+ url.searchParams.set("callback", window.location.href);
927
+ url.searchParams.set("origin", window.location.origin);
928
+ window.location.href = url.toString();
929
+ const result = await waitForAlbedoResult();
930
+ if (!result.signed_xdr) throw new Error("Albedo auth entry signing rejected");
931
+ return { signedAuthEntry: result.signed_xdr };
932
+ }
933
+ };
934
+
701
935
  // src/client/session.ts
702
936
  var STORAGE_KEY = "pollar:session";
937
+ var WALLET_TYPE_KEY = "pollar:walletType";
703
938
  function isValidSession(value) {
704
939
  if (typeof value !== "object" || value === null) {
705
940
  console.warn("[PollarClient:session] Invalid session \u2014 value is not an object");
@@ -835,8 +1070,15 @@ function writeStorage(session) {
835
1070
  }
836
1071
  function removeStorage() {
837
1072
  localStorage.removeItem(STORAGE_KEY);
1073
+ localStorage.removeItem(WALLET_TYPE_KEY);
838
1074
  console.info("[PollarClient:session] Session removed from storage");
839
1075
  }
1076
+ function writeWalletType(type) {
1077
+ localStorage.setItem(WALLET_TYPE_KEY, type);
1078
+ }
1079
+ function readWalletType() {
1080
+ return localStorage.getItem(WALLET_TYPE_KEY);
1081
+ }
840
1082
 
841
1083
  // src/client/stream.ts
842
1084
  function abortableDelay(ms, signal) {
@@ -910,7 +1152,7 @@ async function streamUntilFound(api, clientSessionId, check, retryDelayMs = 200,
910
1152
  }
911
1153
 
912
1154
  // src/client/auth/authenticate.ts
913
- async function authenticate(clientSessionId, deps) {
1155
+ async function authenticate(clientSessionId, deps, expectedWallet) {
914
1156
  const { api, signal, setAuthState, storeSession, clearSession } = deps;
915
1157
  setAuthState({ step: "authenticating" });
916
1158
  await streamUntilFound(api, clientSessionId, (data2) => data2?.status === "READY", 200, signal);
@@ -919,6 +1161,16 @@ async function authenticate(clientSessionId, deps) {
919
1161
  signal
920
1162
  });
921
1163
  if (data?.code === "SDK_LOGIN_SUCCESS" && isValidSession(data?.content)) {
1164
+ if (expectedWallet && data.content.data.providers.wallet?.address !== expectedWallet) {
1165
+ setAuthState({
1166
+ step: "error",
1167
+ previousStep: "authenticating",
1168
+ message: "Wallet mismatch: session wallet does not match connected wallet",
1169
+ errorCode: AUTH_ERROR_CODES.WALLET_AUTH_FAILED
1170
+ });
1171
+ clearSession();
1172
+ return;
1173
+ }
922
1174
  storeSession(data.content);
923
1175
  } else {
924
1176
  setAuthState({
@@ -931,8 +1183,8 @@ async function authenticate(clientSessionId, deps) {
931
1183
  }
932
1184
  }
933
1185
 
934
- // src/client/auth/emailFlow.ts
935
- async function initEmailSession(deps) {
1186
+ // src/client/auth/deps.ts
1187
+ async function createAuthSession(deps) {
936
1188
  const { api, signal, setAuthState } = deps;
937
1189
  setAuthState({ step: "creating_session" });
938
1190
  const { data, error } = await api.POST("/auth/session", { signal });
@@ -943,9 +1195,16 @@ async function initEmailSession(deps) {
943
1195
  message: "Failed to create session",
944
1196
  errorCode: AUTH_ERROR_CODES.SESSION_CREATE_FAILED
945
1197
  });
946
- return;
1198
+ return null;
947
1199
  }
948
- setAuthState({ step: "entering_email", clientSessionId: data.content.clientSessionId });
1200
+ return data.content.clientSessionId;
1201
+ }
1202
+
1203
+ // src/client/auth/emailFlow.ts
1204
+ async function initEmailSession(deps) {
1205
+ const clientSessionId = await createAuthSession(deps);
1206
+ if (!clientSessionId) return;
1207
+ deps.setAuthState({ step: "entering_email", clientSessionId });
949
1208
  }
950
1209
  async function sendEmailCode(email, clientSessionId, deps) {
951
1210
  const { api, signal, setAuthState } = deps;
@@ -1008,25 +1267,10 @@ async function verifyAndAuthenticate(code, clientSessionId, email, deps) {
1008
1267
  }
1009
1268
 
1010
1269
  // src/client/auth/oauthFlow.ts
1011
- async function initOAuthSession(deps) {
1012
- const { api, signal, setAuthState } = deps;
1013
- setAuthState({ step: "creating_session" });
1014
- const { data, error } = await api.POST("/auth/session", { signal });
1015
- if (error || !data?.success) {
1016
- setAuthState({
1017
- step: "error",
1018
- previousStep: "creating_session",
1019
- message: "Failed to create session",
1020
- errorCode: AUTH_ERROR_CODES.SESSION_CREATE_FAILED
1021
- });
1022
- return null;
1023
- }
1024
- return data.content.clientSessionId;
1025
- }
1026
1270
  async function loginOAuth(provider, deps) {
1027
1271
  const { setAuthState, basePath, apiKey } = deps;
1028
1272
  const popup = window.open("about:blank", "_blank");
1029
- const clientSessionId = await initOAuthSession(deps);
1273
+ const clientSessionId = await createAuthSession(deps);
1030
1274
  if (!clientSessionId) {
1031
1275
  popup?.close();
1032
1276
  return;
@@ -1044,173 +1288,6 @@ async function loginOAuth(provider, deps) {
1044
1288
  await authenticate(clientSessionId, deps);
1045
1289
  }
1046
1290
 
1047
- // src/wallets/FreighterAdapter.ts
1048
- var import_freighter_api = __toESM(require_index_min());
1049
-
1050
- // src/wallets/types.ts
1051
- var WalletType = /* @__PURE__ */ ((WalletType2) => {
1052
- WalletType2["FREIGHTER"] = "freighter";
1053
- WalletType2["ALBEDO"] = "albedo";
1054
- return WalletType2;
1055
- })(WalletType || {});
1056
-
1057
- // src/wallets/FreighterAdapter.ts
1058
- var FreighterAdapter = class {
1059
- constructor() {
1060
- this.type = "freighter" /* FREIGHTER */;
1061
- }
1062
- async isAvailable() {
1063
- try {
1064
- return await (0, import_freighter_api.isConnected)();
1065
- } catch {
1066
- return false;
1067
- }
1068
- }
1069
- async connect() {
1070
- const connected = await (0, import_freighter_api.isConnected)();
1071
- if (!connected) {
1072
- throw new Error("Freighter wallet is not installed");
1073
- }
1074
- const allowed = await (0, import_freighter_api.isAllowed)();
1075
- if (!allowed) {
1076
- await (0, import_freighter_api.setAllowed)();
1077
- }
1078
- const userInfo = await (0, import_freighter_api.getUserInfo)();
1079
- if (!userInfo?.publicKey) {
1080
- throw new Error("Failed to get user information from Freighter");
1081
- }
1082
- return { address: userInfo.publicKey, publicKey: userInfo.publicKey };
1083
- }
1084
- async disconnect() {
1085
- }
1086
- async getPublicKey() {
1087
- try {
1088
- const allowed = await (0, import_freighter_api.isAllowed)();
1089
- if (!allowed) return null;
1090
- const userInfo = await (0, import_freighter_api.getUserInfo)();
1091
- return userInfo?.publicKey ?? null;
1092
- } catch {
1093
- return null;
1094
- }
1095
- }
1096
- async getNetwork() {
1097
- return (0, import_freighter_api.getNetwork)();
1098
- }
1099
- async signTransaction(xdr, options) {
1100
- const result = await (0, import_freighter_api.signTransaction)(xdr, {
1101
- network: options?.network,
1102
- networkPassphrase: options?.networkPassphrase,
1103
- accountToSign: options?.accountToSign
1104
- });
1105
- if (!result || typeof result !== "string") {
1106
- throw new Error("Invalid response from Freighter");
1107
- }
1108
- return { signedTxXdr: result };
1109
- }
1110
- async signAuthEntry(entryXdr, options) {
1111
- const result = await (0, import_freighter_api.signAuthEntry)(entryXdr, { accountToSign: options?.accountToSign });
1112
- if (!result || typeof result !== "string") {
1113
- throw new Error("Invalid response from Freighter");
1114
- }
1115
- return { signedAuthEntry: result };
1116
- }
1117
- };
1118
-
1119
- // src/wallets/AlbedoAdapter.ts
1120
- function openAlbedoPopup(url) {
1121
- const popup = window.open(url, "albedo", "width=420,height=720,resizable=yes,scrollbars=yes");
1122
- if (!popup) {
1123
- throw new Error("Failed to open Albedo popup (blocked by browser)");
1124
- }
1125
- return popup;
1126
- }
1127
- function waitForAlbedoPopup() {
1128
- return new Promise((resolve, reject) => {
1129
- const timeout = setTimeout(() => reject(new Error("Albedo response timeout")), 2 * 60 * 1e3);
1130
- function handler(event) {
1131
- if (event.origin !== window.location.origin || event.data?.type !== "ALBEDO_RESULT") return;
1132
- clearTimeout(timeout);
1133
- window.removeEventListener("message", handler);
1134
- resolve(event.data.payload);
1135
- }
1136
- window.addEventListener("message", handler);
1137
- });
1138
- }
1139
- function waitForAlbedoResult() {
1140
- return new Promise((resolve, reject) => {
1141
- const timeout = setTimeout(() => reject(new Error("Albedo response timeout")), 2 * 60 * 1e3);
1142
- const parseResult = () => {
1143
- const params = new URLSearchParams(window.location.search);
1144
- if (!params.has("pubkey") && !params.has("signed_envelope_xdr") && !params.has("signed_xdr")) return;
1145
- clearTimeout(timeout);
1146
- const result = {};
1147
- params.forEach((value, key) => {
1148
- result[key] = value;
1149
- });
1150
- window.history.replaceState({}, document.title, window.location.pathname);
1151
- resolve(result);
1152
- };
1153
- parseResult();
1154
- window.addEventListener("popstate", parseResult);
1155
- });
1156
- }
1157
- var AlbedoAdapter = class {
1158
- constructor() {
1159
- this.type = "albedo" /* ALBEDO */;
1160
- }
1161
- async isAvailable() {
1162
- return typeof window !== "undefined";
1163
- }
1164
- async connect() {
1165
- const url = new URL("https://albedo.link");
1166
- url.searchParams.set("intent", "public-key");
1167
- url.searchParams.set("app_name", "Pollar");
1168
- url.searchParams.set("network", "testnet");
1169
- url.searchParams.set("callback", `${window.location.origin}/albedo-callback`);
1170
- url.searchParams.set("origin", window.location.origin);
1171
- openAlbedoPopup(url.toString());
1172
- const result = await waitForAlbedoPopup();
1173
- if (!result.pubkey) {
1174
- throw new Error("Albedo connection rejected");
1175
- }
1176
- return { address: result.pubkey, publicKey: result.pubkey };
1177
- }
1178
- async disconnect() {
1179
- }
1180
- async getPublicKey() {
1181
- return null;
1182
- }
1183
- async getNetwork() {
1184
- throw new Error("Albedo does not expose network");
1185
- }
1186
- async signTransaction(xdr, _options) {
1187
- const url = new URL("https://albedo.link");
1188
- url.searchParams.set("intent", "tx");
1189
- url.searchParams.set("xdr", xdr);
1190
- url.searchParams.set("app_name", "Pollar");
1191
- url.searchParams.set("network", "testnet");
1192
- url.searchParams.set("callback", window.location.href);
1193
- url.searchParams.set("origin", window.location.origin);
1194
- window.location.href = url.toString();
1195
- const result = await waitForAlbedoResult();
1196
- if (!result.signed_envelope_xdr) throw new Error("Albedo signing rejected");
1197
- return { signedTxXdr: result.signed_envelope_xdr };
1198
- }
1199
- async signAuthEntry(entryXdr, _options) {
1200
- const url = new URL("https://albedo.link");
1201
- url.searchParams.set("intent", "sign-auth-entry");
1202
- url.searchParams.set("xdr", entryXdr);
1203
- url.searchParams.set("app_name", "Pollar");
1204
- url.searchParams.set("network", "testnet");
1205
- url.searchParams.set("callback", window.location.href);
1206
- url.searchParams.set("origin", window.location.origin);
1207
- window.location.href = url.toString();
1208
- const result = await waitForAlbedoResult();
1209
- if (!result.signed_xdr) throw new Error("Albedo auth entry signing rejected");
1210
- return { signedAuthEntry: result.signed_xdr };
1211
- }
1212
- };
1213
-
1214
1291
  // src/client/auth/walletFlow.ts
1215
1292
  function withSignal(promise, signal) {
1216
1293
  return Promise.race([
@@ -1226,18 +1303,9 @@ function withSignal(promise, signal) {
1226
1303
  }
1227
1304
  async function loginWallet(type, deps) {
1228
1305
  const { api, signal, setAuthState } = deps;
1229
- setAuthState({ step: "creating_session" });
1230
- const { data, error } = await api.POST("/auth/session", { signal });
1231
- if (error || !data?.success) {
1232
- setAuthState({
1233
- step: "error",
1234
- previousStep: "creating_session",
1235
- message: "Failed to create session",
1236
- errorCode: AUTH_ERROR_CODES.SESSION_CREATE_FAILED
1237
- });
1238
- return;
1239
- }
1240
- const clientSessionId = data.content.clientSessionId;
1306
+ const clientSessionId = await createAuthSession(deps);
1307
+ if (!clientSessionId) return;
1308
+ let connectedWallet;
1241
1309
  try {
1242
1310
  setAuthState({ step: "connecting_wallet", walletType: type });
1243
1311
  const adapter = type === "freighter" /* FREIGHTER */ ? new FreighterAdapter() : new AlbedoAdapter();
@@ -1247,6 +1315,8 @@ async function loginWallet(type, deps) {
1247
1315
  return;
1248
1316
  }
1249
1317
  const { publicKey } = await withSignal(adapter.connect(), signal);
1318
+ connectedWallet = publicKey;
1319
+ deps.storeWalletAdapter(adapter, type);
1250
1320
  setAuthState({ step: "authenticating_wallet" });
1251
1321
  const { data: walletData, error: walletError } = await api.POST("/auth/wallet", {
1252
1322
  body: { clientSessionId, walletAddress: publicKey },
@@ -1270,22 +1340,9 @@ async function loginWallet(type, deps) {
1270
1340
  });
1271
1341
  return;
1272
1342
  }
1273
- await authenticate(clientSessionId, deps);
1343
+ await authenticate(clientSessionId, deps, connectedWallet);
1274
1344
  }
1275
1345
 
1276
- // src/client/helpers.ts
1277
- var emitResponse = (state, response, success, errorCode, emitLog) => {
1278
- const isSuccess = !response.error && !!response.data && !!response.data?.success;
1279
- emitLog(
1280
- state,
1281
- isSuccess ? success.code : errorCode,
1282
- isSuccess ? "info" : "error",
1283
- isSuccess ? success.status || StateStatus.LOADING : StateStatus.ERROR,
1284
- isSuccess ? response.data : response.error
1285
- );
1286
- return isSuccess;
1287
- };
1288
-
1289
1346
  // src/client/client.ts
1290
1347
  var isBrowser = typeof window !== "undefined" && typeof localStorage !== "undefined";
1291
1348
  function warnServerSide(method) {
@@ -1296,46 +1353,50 @@ function warnServerSide(method) {
1296
1353
  var PollarClient = class {
1297
1354
  constructor(config) {
1298
1355
  this._session = null;
1299
- this._stateListeners = /* @__PURE__ */ new Set();
1300
- this._state = {
1301
- network: [],
1302
- transaction: []
1303
- };
1356
+ this._transactionState = null;
1357
+ this._transactionStateListeners = /* @__PURE__ */ new Set();
1358
+ this._txHistoryState = { step: "idle" };
1359
+ this._txHistoryStateListeners = /* @__PURE__ */ new Set();
1360
+ this._walletBalanceState = { step: "idle" };
1361
+ this._walletBalanceStateListeners = /* @__PURE__ */ new Set();
1304
1362
  this._authState = { step: "idle" };
1305
1363
  this._authStateListeners = /* @__PURE__ */ new Set();
1364
+ this._networkState = { step: "idle" };
1365
+ this._networkStateListeners = /* @__PURE__ */ new Set();
1366
+ this._walletAdapter = null;
1306
1367
  this._loginController = null;
1307
1368
  this.apiKey = config.apiKey;
1308
1369
  this.id = crypto.randomUUID();
1309
1370
  this.basePath = `${config.baseUrl || "https://sdk.api.pollar.xyz"}/v1`;
1310
1371
  this._api = createApiClient(this.basePath);
1372
+ const self = this;
1311
1373
  this._api.use({
1312
1374
  onRequest({ request }) {
1313
1375
  request.headers.set("x-pollar-api-key", config.apiKey);
1376
+ const accessToken = self._session?.token?.accessToken;
1377
+ if (accessToken) {
1378
+ request.headers.set("Authorization", `Bearer ${accessToken}`);
1379
+ }
1314
1380
  return request;
1315
1381
  }
1316
1382
  });
1383
+ this._networkState = { step: "connected", network: config.stellarNetwork ?? "testnet" };
1317
1384
  if (!isBrowser) {
1318
1385
  warnServerSide("constructor");
1319
1386
  this._session = null;
1320
1387
  return;
1321
1388
  }
1322
- console.info(`[PollarClient] Initialized \u2014 endpoint: ${this.basePath}`);
1323
- this._readStore();
1389
+ console.info(`[PollarClient] Initialized \u2014 endpoint: ${this.basePath}, network: ${this._networkState.network}`);
1390
+ this._restoreSession();
1324
1391
  window.addEventListener("storage", (e) => {
1325
1392
  if (e.key === STORAGE_KEY) {
1326
1393
  const prev = this._session;
1327
1394
  console.info(`[PollarClient] Storage event \u2014 session ${this._session ? "updated" : prev ? "cleared" : "unchanged"}`);
1328
- this._readStore();
1395
+ this._restoreSession();
1329
1396
  }
1330
1397
  });
1331
- this._emitState("network", STATE_VAR_CODES.network.NETWORK_UPDATED, "info", StateStatus.SUCCESS, {
1332
- network: "testnet"
1333
- });
1334
1398
  }
1335
1399
  // ─── Auth state ──────────────────────────────────────────────────────────────
1336
- isAuthenticated() {
1337
- return !!this._session?.wallet?.publicKey;
1338
- }
1339
1400
  getAuthState() {
1340
1401
  return this._authState;
1341
1402
  }
@@ -1350,17 +1411,23 @@ var PollarClient = class {
1350
1411
  warnServerSide("login");
1351
1412
  return;
1352
1413
  }
1353
- if (options.provider === "google" || options.provider === "github") {
1354
- this.loginOAuth(options.provider);
1355
- } else if (options.provider === "email") {
1356
- const { email } = options;
1414
+ if (options.provider === "google" || options.provider === "github" || options.provider === "email") {
1357
1415
  const controller = this._newController();
1358
1416
  const deps = this._flowDeps(controller.signal);
1359
- initEmailSession(deps).then(() => {
1360
- if (this._authState.step === "entering_email") {
1361
- return sendEmailCode(email, this._authState.clientSessionId, deps);
1362
- }
1363
- }).catch((err) => this._handleFlowError(err));
1417
+ if (options.provider === "google" || options.provider === "github") {
1418
+ loginOAuth(options.provider, {
1419
+ ...deps,
1420
+ basePath: this.basePath,
1421
+ apiKey: this.apiKey
1422
+ }).catch((err) => this._handleFlowError(err));
1423
+ } else if (options.provider === "email") {
1424
+ const { email } = options;
1425
+ initEmailSession(deps).then(() => {
1426
+ if (this._authState.step === "entering_email") {
1427
+ return sendEmailCode(email, this._authState.clientSessionId, deps);
1428
+ }
1429
+ }).catch((err) => this._handleFlowError(err));
1430
+ }
1364
1431
  } else if (options.provider === "wallet") {
1365
1432
  this.loginWallet(options.type);
1366
1433
  }
@@ -1403,19 +1470,6 @@ var PollarClient = class {
1403
1470
  (err) => this._handleFlowError(err)
1404
1471
  );
1405
1472
  }
1406
- // ─── OAuth flow (single call) ─────────────────────────────────────────────
1407
- loginOAuth(provider) {
1408
- if (!isBrowser) {
1409
- warnServerSide("loginOAuth");
1410
- return;
1411
- }
1412
- const controller = this._newController();
1413
- loginOAuth(provider, {
1414
- ...this._flowDeps(controller.signal),
1415
- basePath: this.basePath,
1416
- apiKey: this.apiKey
1417
- }).catch((err) => this._handleFlowError(err));
1418
- }
1419
1473
  // ─── Wallet flow (single call) ────────────────────────────────────────────
1420
1474
  loginWallet(type) {
1421
1475
  if (!isBrowser) {
@@ -1440,24 +1494,85 @@ var PollarClient = class {
1440
1494
  console.info("[PollarClient] Logout requested");
1441
1495
  this._clearSession();
1442
1496
  }
1443
- // ─── General state (network / transaction) ────────────────────────────────
1444
- getApi() {
1445
- return this._api;
1446
- }
1497
+ // ─── Network ──────────────────────────────────────────────────────────────
1447
1498
  getNetwork() {
1448
- return this._state.network.at(-1)?.data?.network === "public" ? "public" : "testnet";
1499
+ return this._networkState.step === "connected" ? this._networkState.network : "testnet";
1500
+ }
1501
+ getNetworkState() {
1502
+ return this._networkState;
1503
+ }
1504
+ setNetwork(network) {
1505
+ this._setNetworkState({ step: "connected", network });
1506
+ }
1507
+ onNetworkStateChange(cb) {
1508
+ this._networkStateListeners.add(cb);
1509
+ cb(this._networkState);
1510
+ return () => this._networkStateListeners.delete(cb);
1511
+ }
1512
+ // ─── Transaction state ────────────────────────────────────────────────────
1513
+ getTransactionState() {
1514
+ return this._transactionState;
1515
+ }
1516
+ onTransactionStateChange(cb) {
1517
+ this._transactionStateListeners.add(cb);
1518
+ if (this._transactionState) cb(this._transactionState);
1519
+ return () => this._transactionStateListeners.delete(cb);
1520
+ }
1521
+ // ─── Tx history ──────────────────────────────────────────────────────────
1522
+ getTxHistoryState() {
1523
+ return this._txHistoryState;
1524
+ }
1525
+ onTxHistoryStateChange(cb) {
1526
+ this._txHistoryStateListeners.add(cb);
1527
+ cb(this._txHistoryState);
1528
+ return () => this._txHistoryStateListeners.delete(cb);
1529
+ }
1530
+ async fetchTxHistory(params = {}) {
1531
+ this._setTxHistoryState({ step: "loading", params });
1532
+ try {
1533
+ const { data, error } = await this._api.GET("/tx/history", { params: { query: params } });
1534
+ if (!error && data?.success && data.content) {
1535
+ this._setTxHistoryState({ step: "loaded", params, data: data.content });
1536
+ } else {
1537
+ const message = error?.message ?? "Failed to load history";
1538
+ this._setTxHistoryState({ step: "error", params, message });
1539
+ }
1540
+ } catch {
1541
+ this._setTxHistoryState({ step: "error", params, message: "Failed to load history" });
1542
+ }
1449
1543
  }
1450
- onStateChange(cb) {
1451
- this._stateListeners.add(cb);
1452
- for (const [, stateEntry] of Object.entries(this._state)) {
1453
- if (stateEntry.length >= 1) cb(stateEntry.at(-1));
1544
+ // ─── Wallet balance ───────────────────────────────────────────────────────
1545
+ getWalletBalanceState() {
1546
+ return this._walletBalanceState;
1547
+ }
1548
+ onWalletBalanceStateChange(cb) {
1549
+ this._walletBalanceStateListeners.add(cb);
1550
+ cb(this._walletBalanceState);
1551
+ return () => this._walletBalanceStateListeners.delete(cb);
1552
+ }
1553
+ async refreshBalance(publicKey) {
1554
+ const pk = publicKey ?? this._session?.wallet?.publicKey;
1555
+ if (!pk) {
1556
+ this._setWalletBalanceState({ step: "error", message: "No wallet connected" });
1557
+ return;
1558
+ }
1559
+ this._setWalletBalanceState({ step: "loading" });
1560
+ try {
1561
+ const network = this.getNetwork();
1562
+ const { data, error } = await this._api.GET("/wallet/balance", { params: { query: { publicKey: pk, network } } });
1563
+ if (!error && data?.success && data.content) {
1564
+ this._setWalletBalanceState({ step: "loaded", data: data.content });
1565
+ } else {
1566
+ this._setWalletBalanceState({ step: "error", message: "Failed to load balance" });
1567
+ }
1568
+ } catch {
1569
+ this._setWalletBalanceState({ step: "error", message: "Failed to load balance" });
1454
1570
  }
1455
- return () => this._stateListeners.delete(cb);
1456
1571
  }
1457
1572
  // ─── Transactions ─────────────────────────────────────────────────────────
1458
1573
  async buildTx(operation, params, options) {
1459
1574
  if (!this._session?.wallet?.publicKey) {
1460
- this._emitState("transaction", STATE_VAR_CODES.transaction.BUILD_TRANSACTION_ERROR_NO_WALLET, "error", StateStatus.ERROR);
1575
+ this._setTransactionState({ step: "error", details: "No wallet connected" });
1461
1576
  return;
1462
1577
  }
1463
1578
  const body = {
@@ -1465,42 +1580,114 @@ var PollarClient = class {
1465
1580
  publicKey: this._session.wallet.publicKey,
1466
1581
  operation,
1467
1582
  params,
1468
- options: options || {}
1583
+ options: options ?? {}
1469
1584
  };
1470
1585
  try {
1471
- this._emitState("transaction", STATE_VAR_CODES.transaction.BUILD_TRANSACTION_START, "info", StateStatus.LOADING);
1472
- const response = await this._api.POST("/tx/build", { body });
1473
- emitResponse(
1474
- PollarStateVar.TRANSACTION,
1475
- response,
1476
- { code: STATE_VAR_CODES.transaction.BUILD_TRANSACTION_SUCCESS, status: StateStatus.SUCCESS },
1477
- STATE_VAR_CODES.transaction.BUILD_TRANSACTION_ERROR,
1478
- this._emitState.bind(this)
1479
- );
1480
- } catch (error) {
1481
- this._emitState("transaction", STATE_VAR_CODES.transaction.BUILD_TRANSACTION_ERROR, "error", StateStatus.ERROR, {
1482
- error
1483
- });
1586
+ this._setTransactionState({ step: "building" });
1587
+ const { data, error } = await this._api.POST("/tx/build", { body });
1588
+ if (!error && data?.success && data.content) {
1589
+ this._setTransactionState({ step: "built", buildData: data.content });
1590
+ } else {
1591
+ const details = error?.details;
1592
+ this._setTransactionState({ step: "error", ...details && { details } });
1593
+ }
1594
+ } catch {
1595
+ this._setTransactionState({ step: "error" });
1484
1596
  }
1485
1597
  }
1486
- async submitTx(signedXdr) {
1487
- const body = { network: this.getNetwork(), signedXdr };
1598
+ getWalletType() {
1599
+ return this._walletAdapter?.type ?? null;
1600
+ }
1601
+ async signAndSubmitTx(unsignedXdr) {
1602
+ const state = this._transactionState;
1603
+ const buildData = state?.step === "built" ? state.buildData : state?.step === "error" ? state.buildData : void 0;
1604
+ const isBuiltFlow = !!buildData;
1605
+ const stateExtra = buildData ? { buildData } : { external: true };
1606
+ this._setTransactionState({ step: "signing", ...stateExtra });
1607
+ const accountToSign = isBuiltFlow ? this._session?.wallet?.publicKey : this._session?.data?.providers?.wallet?.address ?? this._session?.wallet?.publicKey;
1608
+ if (this._walletAdapter) {
1609
+ try {
1610
+ const signOpts = accountToSign ? { networkPassphrase: this._networkPassphrase(), accountToSign } : { networkPassphrase: this._networkPassphrase() };
1611
+ const { signedTxXdr } = await this._walletAdapter.signTransaction(unsignedXdr, signOpts);
1612
+ const stellarClient = new StellarClient(this.getNetwork());
1613
+ const result = await stellarClient.submitTransaction(signedTxXdr);
1614
+ if (result.success) {
1615
+ this._setTransactionState({ step: "success", ...stateExtra, hash: result.hash });
1616
+ } else {
1617
+ this._setTransactionState({ step: "error", ...stateExtra, details: result.errorCode });
1618
+ }
1619
+ } catch {
1620
+ this._setTransactionState({ step: "error", ...stateExtra });
1621
+ }
1622
+ return;
1623
+ }
1624
+ const body = {
1625
+ network: this.getNetwork(),
1626
+ publicKey: this._session?.wallet?.publicKey ?? "",
1627
+ unsignedXdr
1628
+ };
1488
1629
  try {
1489
- this._emitState("transaction", STATE_VAR_CODES.transaction.SIGN_SEND_TRANSACTION_START, "info", StateStatus.LOADING);
1490
- const response = await this._api.POST("/tx/sign-and-send", { body });
1491
- emitResponse(
1492
- PollarStateVar.TRANSACTION,
1493
- response,
1494
- { code: STATE_VAR_CODES.transaction.SIGN_SEND_TRANSACTION_SUCCESS, status: StateStatus.SUCCESS },
1495
- STATE_VAR_CODES.transaction.SIGN_SEND_TRANSACTION_ERROR,
1496
- this._emitState.bind(this)
1497
- );
1498
- } catch (error) {
1499
- this._emitState("transaction", STATE_VAR_CODES.transaction.SIGN_SEND_TRANSACTION_ERROR, "error", StateStatus.ERROR, {
1500
- error
1501
- });
1630
+ const { data, error } = await this._api.POST("/tx/sign-and-send", { body });
1631
+ if (!error && data?.success && data.content?.hash) {
1632
+ this._setTransactionState({ step: "success", ...stateExtra, hash: data.content.hash });
1633
+ } else {
1634
+ const details = error?.details;
1635
+ this._setTransactionState({ step: "error", ...stateExtra, ...details && { details } });
1636
+ }
1637
+ } catch {
1638
+ this._setTransactionState({ step: "error", ...stateExtra });
1502
1639
  }
1503
1640
  }
1641
+ // ─── App config ───────────────────────────────────────────────────────────
1642
+ async getAppConfig() {
1643
+ try {
1644
+ const { data, error } = await this._api.GET("/applications/config");
1645
+ if (!data || error) return null;
1646
+ return data.content;
1647
+ } catch {
1648
+ return null;
1649
+ }
1650
+ }
1651
+ // ─── KYC ──────────────────────────────────────────────────────────────────
1652
+ getKycStatus(providerId) {
1653
+ return getKycStatus(this._api, providerId);
1654
+ }
1655
+ getKycProviders(country) {
1656
+ return getKycProviders(this._api, country);
1657
+ }
1658
+ startKyc(body) {
1659
+ return startKyc(this._api, body);
1660
+ }
1661
+ resolveKyc(providerId, level) {
1662
+ return resolveKyc(this._api, providerId, level);
1663
+ }
1664
+ pollKycStatus(providerId, opts) {
1665
+ return pollKycStatus(this._api, providerId, opts);
1666
+ }
1667
+ // ─── Ramps ────────────────────────────────────────────────────────────────
1668
+ getRampsQuote(query) {
1669
+ return getRampsQuote(this._api, query);
1670
+ }
1671
+ createOnRamp(body) {
1672
+ return createOnRamp(this._api, body);
1673
+ }
1674
+ createOffRamp(body) {
1675
+ return createOffRamp(this._api, body);
1676
+ }
1677
+ getRampTransaction(txId) {
1678
+ return getRampTransaction(this._api, txId);
1679
+ }
1680
+ pollRampTransaction(txId, opts) {
1681
+ return pollRampTransaction(this._api, txId, opts);
1682
+ }
1683
+ _setTxHistoryState(next) {
1684
+ this._txHistoryState = next;
1685
+ for (const cb of this._txHistoryStateListeners) cb(next);
1686
+ }
1687
+ _setWalletBalanceState(next) {
1688
+ this._walletBalanceState = next;
1689
+ for (const cb of this._walletBalanceStateListeners) cb(next);
1690
+ }
1504
1691
  // ─── Private ──────────────────────────────────────────────────────────────
1505
1692
  /** Creates a new AbortController, cancelling any existing flow first. */
1506
1693
  _newController() {
@@ -1515,7 +1702,11 @@ var PollarClient = class {
1515
1702
  signal,
1516
1703
  setAuthState: this._setAuthState.bind(this),
1517
1704
  storeSession: this._storeSession.bind(this),
1518
- clearSession: this._clearSession.bind(this)
1705
+ clearSession: this._clearSession.bind(this),
1706
+ storeWalletAdapter: (adapter, type) => {
1707
+ this._walletAdapter = adapter;
1708
+ writeWalletType(type);
1709
+ }
1519
1710
  };
1520
1711
  }
1521
1712
  _handleFlowError(error) {
@@ -1532,10 +1723,18 @@ var PollarClient = class {
1532
1723
  errorCode: AUTH_ERROR_CODES.UNEXPECTED_ERROR
1533
1724
  });
1534
1725
  }
1535
- _readStore() {
1726
+ _restoreSession() {
1536
1727
  this._session = readStorage();
1537
1728
  if (this._session) {
1538
1729
  this._authState = { step: "authenticated", session: this._session };
1730
+ if (this._session.data?.providers?.wallet?.address) {
1731
+ const storedType = readWalletType();
1732
+ if (storedType === "freighter" /* FREIGHTER */) {
1733
+ this._walletAdapter = new FreighterAdapter();
1734
+ } else if (storedType === "albedo" /* ALBEDO */) {
1735
+ this._walletAdapter = new AlbedoAdapter();
1736
+ }
1737
+ }
1539
1738
  console.info("[PollarClient] Session restored from storage");
1540
1739
  } else {
1541
1740
  console.info("[PollarClient] No session in storage");
@@ -1550,59 +1749,32 @@ var PollarClient = class {
1550
1749
  _clearSession() {
1551
1750
  console.info("[PollarClient] Session cleared");
1552
1751
  this._session = null;
1752
+ this._walletAdapter = null;
1553
1753
  removeStorage();
1554
- this._state = { network: [], transaction: [] };
1754
+ this._transactionState = null;
1555
1755
  this._setAuthState({ step: "idle" });
1556
1756
  }
1757
+ _networkPassphrase() {
1758
+ return this.getNetwork() === "mainnet" ? "Public Global Stellar Network ; September 2015" : "Test SDF Network ; September 2015";
1759
+ }
1760
+ _setNetworkState(next) {
1761
+ this._networkState = next;
1762
+ const label = next.step === "connected" ? next.network : next.step;
1763
+ console.info(`[PollarClient] network:${label}`);
1764
+ for (const cb of this._networkStateListeners) cb(next);
1765
+ }
1557
1766
  _setAuthState(next) {
1558
1767
  this._authState = next;
1559
1768
  console.info(`[PollarClient] auth:${next.step}`);
1560
1769
  for (const cb of this._authStateListeners) cb(next);
1561
1770
  }
1562
- _emitState(fn, code, level, status, data) {
1563
- const stateEntry = { var: fn, code, level, data, status, ts: Date.now() };
1564
- this._state[fn].push(stateEntry);
1565
- console[level](`[PollarClient] ${fn}:${code} \u2014 ${status}`);
1566
- for (const cb of this._stateListeners) cb(stateEntry);
1567
- }
1568
- };
1569
-
1570
- // src/stellar/StellarClient.ts
1571
- var HORIZON_URLS = {
1572
- mainnet: "https://horizon.stellar.org",
1573
- testnet: "https://horizon-testnet.stellar.org"
1574
- };
1575
- var StellarClient = class {
1576
- constructor(config) {
1577
- this.horizonUrl = typeof config === "string" ? HORIZON_URLS[config] : config.horizonUrl;
1578
- }
1579
- async getBalances(publicKey) {
1580
- try {
1581
- const response = await fetch(`${this.horizonUrl}/accounts/${publicKey}`);
1582
- if (!response.ok) {
1583
- if (response.status === 404) {
1584
- console.warn(`[StellarClient] Account not found: ${publicKey}`);
1585
- return { success: false, errorCode: "ACCOUNT_NOT_FOUND", balances: [] };
1586
- }
1587
- console.warn(`[StellarClient] Horizon API error: ${response.status}`);
1588
- return { success: false, errorCode: "HORIZON_ERROR", balances: [] };
1589
- }
1590
- const data = await response.json();
1591
- return {
1592
- success: true,
1593
- balances: data.balances.filter((b) => b.asset_type !== "liquidity_pool_shares").map((b) => ({
1594
- asset: b.asset_type === "native" ? "XLM" : b.asset_code ?? "",
1595
- balance: b.balance,
1596
- ...b.asset_type !== "native" && { assetIssuer: b.asset_issuer }
1597
- }))
1598
- };
1599
- } catch (error) {
1600
- console.warn("[StellarClient] Network error fetching balances", error);
1601
- return { success: false, errorCode: "NETWORK_ERROR", balances: [] };
1602
- }
1771
+ _setTransactionState(next) {
1772
+ this._transactionState = next;
1773
+ console.info(`[PollarClient] transaction:${next.step}`);
1774
+ for (const cb of this._transactionStateListeners) cb(next);
1603
1775
  }
1604
1776
  };
1605
1777
 
1606
- export { AUTH_ERROR_CODES, AlbedoAdapter, FreighterAdapter, PollarClient, PollarStateVar, STATE_VAR_CODES, StateStatus, StellarClient, WalletType, isValidSession };
1778
+ export { AUTH_ERROR_CODES, AlbedoAdapter, FreighterAdapter, PollarClient, StellarClient, WalletType, createOffRamp, createOnRamp, getKycProviders, getKycStatus, getRampTransaction, getRampsQuote, isValidSession, pollKycStatus, pollRampTransaction, resolveKyc, startKyc };
1607
1779
  //# sourceMappingURL=index.mjs.map
1608
1780
  //# sourceMappingURL=index.mjs.map