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