@ecency/sdk 1.3.6 → 1.3.8

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.
@@ -80,7 +80,16 @@ var CONFIG = {
80
80
  heliusApiKey: process.env.VITE_HELIUS_API_KEY,
81
81
  queryClient: new reactQuery.QueryClient(),
82
82
  plausibleHost: "https://pl.ecency.com",
83
- spkNode: "https://spk.good-karma.xyz"
83
+ spkNode: "https://spk.good-karma.xyz",
84
+ // DMCA filtering - can be configured by the app
85
+ dmcaAccounts: [],
86
+ dmcaTags: [],
87
+ dmcaPatterns: [],
88
+ // Pre-compiled regex patterns for performance and security
89
+ dmcaTagRegexes: [],
90
+ dmcaPatternRegexes: [],
91
+ // Track if DMCA has been initialized to avoid duplicate logs
92
+ _dmcaInitialized: false
84
93
  };
85
94
  exports.ConfigManager = void 0;
86
95
  ((ConfigManager2) => {
@@ -88,6 +97,111 @@ exports.ConfigManager = void 0;
88
97
  CONFIG.queryClient = client;
89
98
  }
90
99
  ConfigManager2.setQueryClient = setQueryClient;
100
+ function analyzeRedosRisk(pattern) {
101
+ if (/(\([^)]*[*+{][^)]*\))[*+{]/.test(pattern)) {
102
+ return { safe: false, reason: "nested quantifiers detected" };
103
+ }
104
+ if (/\([^|)]*\|[^)]*\)[*+{]/.test(pattern)) {
105
+ return { safe: false, reason: "alternation with quantifier (potential overlap)" };
106
+ }
107
+ if (/\([^)]*[*+][^)]*\)[*+]/.test(pattern)) {
108
+ return { safe: false, reason: "repeated quantifiers (catastrophic backtracking risk)" };
109
+ }
110
+ if (/\.\*\.\*/.test(pattern) || /\.\+\.\+/.test(pattern)) {
111
+ return { safe: false, reason: "multiple greedy quantifiers on wildcards" };
112
+ }
113
+ const unboundedRange = /\.?\{(\d+),(\d+)\}/g;
114
+ let match;
115
+ while ((match = unboundedRange.exec(pattern)) !== null) {
116
+ const [, min, max] = match;
117
+ const range = parseInt(max, 10) - parseInt(min, 10);
118
+ if (range > 1e3) {
119
+ return { safe: false, reason: `excessive range: {${min},${max}}` };
120
+ }
121
+ }
122
+ return { safe: true };
123
+ }
124
+ function testRegexPerformance(regex) {
125
+ const adversarialInputs = [
126
+ // Nested quantifier attack
127
+ "a".repeat(50) + "x",
128
+ // Alternation attack
129
+ "ab".repeat(50) + "x",
130
+ // Wildcard attack
131
+ "x".repeat(100),
132
+ // Mixed attack
133
+ "aaa".repeat(30) + "bbb".repeat(30) + "x"
134
+ ];
135
+ const maxExecutionTime = 5;
136
+ for (const input of adversarialInputs) {
137
+ const start = Date.now();
138
+ try {
139
+ regex.test(input);
140
+ const duration = Date.now() - start;
141
+ if (duration > maxExecutionTime) {
142
+ return {
143
+ safe: false,
144
+ reason: `runtime test exceeded ${maxExecutionTime}ms (took ${duration}ms on input length ${input.length})`
145
+ };
146
+ }
147
+ } catch (err) {
148
+ return { safe: false, reason: `runtime test threw error: ${err}` };
149
+ }
150
+ }
151
+ return { safe: true };
152
+ }
153
+ function safeCompileRegex(pattern, maxLength = 200) {
154
+ try {
155
+ if (!pattern) {
156
+ console.warn(`[SDK] DMCA pattern rejected: empty pattern`);
157
+ return null;
158
+ }
159
+ if (pattern.length > maxLength) {
160
+ console.warn(`[SDK] DMCA pattern rejected: length ${pattern.length} exceeds max ${maxLength} - pattern: ${pattern.substring(0, 50)}...`);
161
+ return null;
162
+ }
163
+ const staticAnalysis = analyzeRedosRisk(pattern);
164
+ if (!staticAnalysis.safe) {
165
+ console.warn(`[SDK] DMCA pattern rejected: static analysis failed (${staticAnalysis.reason}) - pattern: ${pattern.substring(0, 50)}...`);
166
+ return null;
167
+ }
168
+ let regex;
169
+ try {
170
+ regex = new RegExp(pattern);
171
+ } catch (compileErr) {
172
+ console.warn(`[SDK] DMCA pattern rejected: compilation failed - pattern: ${pattern.substring(0, 50)}...`, compileErr);
173
+ return null;
174
+ }
175
+ const runtimeTest = testRegexPerformance(regex);
176
+ if (!runtimeTest.safe) {
177
+ console.warn(`[SDK] DMCA pattern rejected: runtime test failed (${runtimeTest.reason}) - pattern: ${pattern.substring(0, 50)}...`);
178
+ return null;
179
+ }
180
+ return regex;
181
+ } catch (err) {
182
+ console.warn(`[SDK] DMCA pattern rejected: unexpected error - pattern: ${pattern.substring(0, 50)}...`, err);
183
+ return null;
184
+ }
185
+ }
186
+ function setDmcaLists(accounts = [], tags = [], patterns = []) {
187
+ CONFIG.dmcaAccounts = accounts;
188
+ CONFIG.dmcaTags = tags;
189
+ CONFIG.dmcaPatterns = patterns;
190
+ CONFIG.dmcaTagRegexes = tags.map((pattern) => safeCompileRegex(pattern)).filter((r) => r !== null);
191
+ CONFIG.dmcaPatternRegexes = [];
192
+ const rejectedTagCount = tags.length - CONFIG.dmcaTagRegexes.length;
193
+ if (!CONFIG._dmcaInitialized) {
194
+ console.log(`[SDK] DMCA configuration loaded:`);
195
+ console.log(` - Accounts: ${accounts.length}`);
196
+ console.log(` - Tag patterns: ${CONFIG.dmcaTagRegexes.length}/${tags.length} compiled (${rejectedTagCount} rejected)`);
197
+ console.log(` - Post patterns: ${patterns.length} (using exact string matching)`);
198
+ if (rejectedTagCount > 0) {
199
+ console.warn(`[SDK] ${rejectedTagCount} DMCA tag patterns were rejected due to security validation. Check warnings above for details.`);
200
+ }
201
+ CONFIG._dmcaInitialized = true;
202
+ }
203
+ }
204
+ ConfigManager2.setDmcaLists = setDmcaLists;
91
205
  })(exports.ConfigManager || (exports.ConfigManager = {}));
92
206
 
93
207
  // src/modules/core/utils/decoder-encoder.ts
@@ -493,6 +607,176 @@ function getAccountFullQueryOptions(username) {
493
607
  staleTime: 6e4
494
608
  });
495
609
  }
610
+ function sanitizeTokens(tokens) {
611
+ return tokens?.map(({ meta, ...rest }) => {
612
+ if (!meta || typeof meta !== "object") {
613
+ return { ...rest, meta };
614
+ }
615
+ const { privateKey, username, ...safeMeta } = meta;
616
+ return { ...rest, meta: safeMeta };
617
+ });
618
+ }
619
+ function parseProfileMetadata(postingJsonMetadata) {
620
+ if (!postingJsonMetadata) {
621
+ return {};
622
+ }
623
+ try {
624
+ const parsed = JSON.parse(postingJsonMetadata);
625
+ if (parsed && typeof parsed === "object" && parsed.profile && typeof parsed.profile === "object") {
626
+ return parsed.profile;
627
+ }
628
+ } catch (err) {
629
+ }
630
+ return {};
631
+ }
632
+ function extractAccountProfile(data) {
633
+ return parseProfileMetadata(data?.posting_json_metadata);
634
+ }
635
+ function buildProfileMetadata({
636
+ existingProfile,
637
+ profile,
638
+ tokens
639
+ }) {
640
+ const { tokens: profileTokens, version: _ignoredVersion, ...profileRest } = profile ?? {};
641
+ const metadata = R4__namespace.mergeDeep(
642
+ existingProfile ?? {},
643
+ profileRest
644
+ );
645
+ const nextTokens = tokens ?? profileTokens;
646
+ if (nextTokens && nextTokens.length > 0) {
647
+ metadata.tokens = nextTokens;
648
+ }
649
+ metadata.tokens = sanitizeTokens(metadata.tokens);
650
+ metadata.version = 2;
651
+ return metadata;
652
+ }
653
+
654
+ // src/modules/accounts/utils/parse-accounts.ts
655
+ function parseAccounts(rawAccounts) {
656
+ return rawAccounts.map((x) => {
657
+ const account = {
658
+ name: x.name,
659
+ owner: x.owner,
660
+ active: x.active,
661
+ posting: x.posting,
662
+ memo_key: x.memo_key,
663
+ post_count: x.post_count,
664
+ created: x.created,
665
+ reputation: x.reputation,
666
+ posting_json_metadata: x.posting_json_metadata,
667
+ last_vote_time: x.last_vote_time,
668
+ last_post: x.last_post,
669
+ json_metadata: x.json_metadata,
670
+ reward_hive_balance: x.reward_hive_balance,
671
+ reward_hbd_balance: x.reward_hbd_balance,
672
+ reward_vesting_hive: x.reward_vesting_hive,
673
+ reward_vesting_balance: x.reward_vesting_balance,
674
+ balance: x.balance,
675
+ hbd_balance: x.hbd_balance,
676
+ savings_balance: x.savings_balance,
677
+ savings_hbd_balance: x.savings_hbd_balance,
678
+ savings_hbd_last_interest_payment: x.savings_hbd_last_interest_payment,
679
+ savings_hbd_seconds_last_update: x.savings_hbd_seconds_last_update,
680
+ savings_hbd_seconds: x.savings_hbd_seconds,
681
+ next_vesting_withdrawal: x.next_vesting_withdrawal,
682
+ pending_claimed_accounts: x.pending_claimed_accounts,
683
+ vesting_shares: x.vesting_shares,
684
+ delegated_vesting_shares: x.delegated_vesting_shares,
685
+ received_vesting_shares: x.received_vesting_shares,
686
+ vesting_withdraw_rate: x.vesting_withdraw_rate,
687
+ to_withdraw: x.to_withdraw,
688
+ withdrawn: x.withdrawn,
689
+ witness_votes: x.witness_votes,
690
+ proxy: x.proxy,
691
+ recovery_account: x.recovery_account,
692
+ proxied_vsf_votes: x.proxied_vsf_votes,
693
+ voting_manabar: x.voting_manabar,
694
+ voting_power: x.voting_power,
695
+ downvote_manabar: x.downvote_manabar
696
+ };
697
+ let profile = parseProfileMetadata(
698
+ x.posting_json_metadata
699
+ );
700
+ if (!profile || Object.keys(profile).length === 0) {
701
+ try {
702
+ const jsonMetadata = JSON.parse(x.json_metadata || "{}");
703
+ if (jsonMetadata.profile) {
704
+ profile = jsonMetadata.profile;
705
+ }
706
+ } catch (e) {
707
+ }
708
+ }
709
+ if (!profile || Object.keys(profile).length === 0) {
710
+ profile = {
711
+ about: "",
712
+ cover_image: "",
713
+ location: "",
714
+ name: "",
715
+ profile_image: "",
716
+ website: ""
717
+ };
718
+ }
719
+ return { ...account, profile };
720
+ });
721
+ }
722
+
723
+ // src/modules/accounts/queries/get-accounts-query-options.ts
724
+ function getAccountsQueryOptions(usernames) {
725
+ return reactQuery.queryOptions({
726
+ queryKey: ["accounts", "get-accounts", usernames],
727
+ queryFn: async () => {
728
+ const response = await CONFIG.hiveClient.database.getAccounts(usernames);
729
+ return parseAccounts(response);
730
+ },
731
+ enabled: usernames.length > 0
732
+ });
733
+ }
734
+ function getFollowCountQueryOptions(username) {
735
+ return reactQuery.queryOptions({
736
+ queryKey: ["accounts", "follow-count", username],
737
+ queryFn: () => CONFIG.hiveClient.database.call("get_follow_count", [
738
+ username
739
+ ])
740
+ });
741
+ }
742
+ function getFollowingQueryOptions(follower, startFollowing, followType = "blog", limit = 100) {
743
+ return reactQuery.queryOptions({
744
+ queryKey: ["accounts", "following", follower, startFollowing, followType, limit],
745
+ queryFn: () => CONFIG.hiveClient.database.call("get_following", [
746
+ follower,
747
+ startFollowing,
748
+ followType,
749
+ limit
750
+ ]),
751
+ enabled: !!follower
752
+ });
753
+ }
754
+ function getMutedUsersQueryOptions(username, limit = 100) {
755
+ return reactQuery.queryOptions({
756
+ queryKey: ["accounts", "muted-users", username],
757
+ queryFn: async () => {
758
+ const response = await CONFIG.hiveClient.database.call("get_following", [
759
+ username,
760
+ "",
761
+ "ignore",
762
+ limit
763
+ ]);
764
+ return response.map((user) => user.following);
765
+ },
766
+ enabled: !!username
767
+ });
768
+ }
769
+ function lookupAccountsQueryOptions(query, limit = 50) {
770
+ return reactQuery.queryOptions({
771
+ queryKey: ["accounts", "lookup", query, limit],
772
+ queryFn: () => CONFIG.hiveClient.database.call("lookup_accounts", [
773
+ query,
774
+ limit
775
+ ]),
776
+ enabled: !!query,
777
+ staleTime: Infinity
778
+ });
779
+ }
496
780
  function getSearchAccountsByUsernameQueryOptions(query, limit = 5, excludeList = []) {
497
781
  return reactQuery.queryOptions({
498
782
  queryKey: ["accounts", "search", query, excludeList],
@@ -712,315 +996,1321 @@ function getAccountPendingRecoveryQueryOptions(username) {
712
996
  )
713
997
  });
714
998
  }
715
- function sanitizeTokens(tokens) {
716
- return tokens?.map(({ meta, ...rest }) => {
717
- if (!meta || typeof meta !== "object") {
718
- return { ...rest, meta };
719
- }
720
- const { privateKey, username, ...safeMeta } = meta;
721
- return { ...rest, meta: safeMeta };
999
+ var ops = dhive.utils.operationOrders;
1000
+ var ACCOUNT_OPERATION_GROUPS = {
1001
+ transfers: [
1002
+ ops.transfer,
1003
+ ops.transfer_to_savings,
1004
+ ops.transfer_from_savings,
1005
+ ops.cancel_transfer_from_savings,
1006
+ ops.recurrent_transfer,
1007
+ ops.fill_recurrent_transfer,
1008
+ ops.escrow_transfer,
1009
+ ops.fill_recurrent_transfer
1010
+ ],
1011
+ "market-orders": [
1012
+ ops.fill_convert_request,
1013
+ ops.fill_order,
1014
+ ops.fill_collateralized_convert_request,
1015
+ ops.limit_order_create2,
1016
+ ops.limit_order_create,
1017
+ ops.limit_order_cancel
1018
+ ],
1019
+ interests: [ops.interest],
1020
+ "stake-operations": [
1021
+ ops.return_vesting_delegation,
1022
+ ops.withdraw_vesting,
1023
+ ops.transfer_to_vesting,
1024
+ ops.set_withdraw_vesting_route,
1025
+ ops.update_proposal_votes,
1026
+ ops.fill_vesting_withdraw,
1027
+ ops.account_witness_proxy,
1028
+ ops.delegate_vesting_shares
1029
+ ],
1030
+ rewards: [
1031
+ ops.author_reward,
1032
+ ops.curation_reward,
1033
+ ops.producer_reward,
1034
+ ops.claim_reward_balance,
1035
+ ops.comment_benefactor_reward,
1036
+ ops.liquidity_reward,
1037
+ ops.proposal_pay
1038
+ ]
1039
+ };
1040
+ var ALL_ACCOUNT_OPERATIONS = [...Object.values(ACCOUNT_OPERATION_GROUPS)].reduce(
1041
+ (acc, val) => acc.concat(val),
1042
+ []
1043
+ );
1044
+ function getTransactionsInfiniteQueryOptions(username, limit = 20, group = "") {
1045
+ return reactQuery.infiniteQueryOptions({
1046
+ queryKey: ["accounts", "transactions", username ?? "", group, limit],
1047
+ initialPageParam: -1,
1048
+ queryFn: async ({ pageParam }) => {
1049
+ if (!username) {
1050
+ return [];
1051
+ }
1052
+ let filters;
1053
+ switch (group) {
1054
+ case "transfers":
1055
+ filters = dhive.utils.makeBitMaskFilter(ACCOUNT_OPERATION_GROUPS["transfers"]);
1056
+ break;
1057
+ case "market-orders":
1058
+ filters = dhive.utils.makeBitMaskFilter(ACCOUNT_OPERATION_GROUPS["market-orders"]);
1059
+ break;
1060
+ case "interests":
1061
+ filters = dhive.utils.makeBitMaskFilter(ACCOUNT_OPERATION_GROUPS["interests"]);
1062
+ break;
1063
+ case "stake-operations":
1064
+ filters = dhive.utils.makeBitMaskFilter(ACCOUNT_OPERATION_GROUPS["stake-operations"]);
1065
+ break;
1066
+ case "rewards":
1067
+ filters = dhive.utils.makeBitMaskFilter(ACCOUNT_OPERATION_GROUPS["rewards"]);
1068
+ break;
1069
+ default:
1070
+ filters = dhive.utils.makeBitMaskFilter(ALL_ACCOUNT_OPERATIONS);
1071
+ }
1072
+ const response = await (filters ? CONFIG.hiveClient.call("condenser_api", "get_account_history", [
1073
+ username,
1074
+ pageParam,
1075
+ limit,
1076
+ ...filters
1077
+ ]) : CONFIG.hiveClient.call("condenser_api", "get_account_history", [
1078
+ username,
1079
+ pageParam,
1080
+ limit
1081
+ ]));
1082
+ const mapped = response.map(([num, operation]) => {
1083
+ const base = {
1084
+ num,
1085
+ type: operation.op[0],
1086
+ timestamp: operation.timestamp,
1087
+ trx_id: operation.trx_id
1088
+ };
1089
+ const payload = operation.op[1];
1090
+ return { ...base, ...payload };
1091
+ }).filter(Boolean).sort((a, b) => b.num - a.num);
1092
+ return mapped;
1093
+ },
1094
+ getNextPageParam: (lastPage) => lastPage?.length ? (lastPage[lastPage.length - 1]?.num ?? 0) - 1 : -1
722
1095
  });
723
1096
  }
724
- function parseProfileMetadata(postingJsonMetadata) {
725
- if (!postingJsonMetadata) {
726
- return {};
727
- }
728
- try {
729
- const parsed = JSON.parse(postingJsonMetadata);
730
- if (parsed && typeof parsed === "object" && parsed.profile && typeof parsed.profile === "object") {
731
- return parsed.profile;
732
- }
733
- } catch (err) {
734
- }
735
- return {};
736
- }
737
- function extractAccountProfile(data) {
738
- return parseProfileMetadata(data?.posting_json_metadata);
739
- }
740
- function buildProfileMetadata({
741
- existingProfile,
742
- profile,
743
- tokens
744
- }) {
745
- const { tokens: profileTokens, version: _ignoredVersion, ...profileRest } = profile ?? {};
746
- const metadata = R4__namespace.mergeDeep(
747
- existingProfile ?? {},
748
- profileRest
749
- );
750
- const nextTokens = tokens ?? profileTokens;
751
- if (nextTokens && nextTokens.length > 0) {
752
- metadata.tokens = nextTokens;
753
- }
754
- metadata.tokens = sanitizeTokens(metadata.tokens);
755
- metadata.version = 2;
756
- return metadata;
757
- }
758
-
759
- // src/modules/accounts/mutations/use-account-update.ts
760
- function useAccountUpdate(username) {
761
- const queryClient = reactQuery.useQueryClient();
762
- const { data } = reactQuery.useQuery(getAccountFullQueryOptions(username));
763
- return useBroadcastMutation(
764
- ["accounts", "update"],
765
- username,
766
- (payload) => {
767
- if (!data) {
768
- throw new Error("[SDK][Accounts] \u2013 cannot update not existing account");
769
- }
770
- const profile = buildProfileMetadata({
771
- existingProfile: extractAccountProfile(data),
772
- profile: payload.profile,
773
- tokens: payload.tokens
1097
+ function getBotsQueryOptions() {
1098
+ return reactQuery.queryOptions({
1099
+ queryKey: ["accounts", "bots"],
1100
+ queryFn: async () => {
1101
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/public/bots", {
1102
+ method: "GET",
1103
+ headers: {
1104
+ "Content-Type": "application/json"
1105
+ }
774
1106
  });
775
- return [
776
- [
777
- "account_update2",
778
- {
779
- account: username,
780
- json_metadata: "",
781
- extensions: [],
782
- posting_json_metadata: JSON.stringify({
783
- profile
784
- })
785
- }
786
- ]
787
- ];
1107
+ if (!response.ok) {
1108
+ throw new Error(`Failed to fetch bots: ${response.status}`);
1109
+ }
1110
+ return response.json();
788
1111
  },
789
- (_, variables) => queryClient.setQueryData(
790
- getAccountFullQueryOptions(username).queryKey,
791
- (data2) => {
792
- if (!data2) {
793
- return data2;
1112
+ refetchOnMount: true,
1113
+ staleTime: Infinity
1114
+ });
1115
+ }
1116
+ function getReferralsInfiniteQueryOptions(username) {
1117
+ return reactQuery.infiniteQueryOptions({
1118
+ queryKey: ["accounts", "referrals", username],
1119
+ initialPageParam: { maxId: void 0 },
1120
+ queryFn: async ({ pageParam }) => {
1121
+ const { maxId } = pageParam ?? {};
1122
+ const url = new URL(CONFIG.privateApiHost + `/private-api/referrals/${username}`);
1123
+ if (maxId !== void 0) {
1124
+ url.searchParams.set("max_id", maxId.toString());
1125
+ }
1126
+ const response = await fetch(url.toString(), {
1127
+ method: "GET",
1128
+ headers: {
1129
+ "Content-Type": "application/json"
794
1130
  }
795
- const obj = R4__namespace.clone(data2);
796
- obj.profile = buildProfileMetadata({
797
- existingProfile: extractAccountProfile(data2),
798
- profile: variables.profile,
799
- tokens: variables.tokens
800
- });
801
- return obj;
1131
+ });
1132
+ if (!response.ok) {
1133
+ throw new Error(`Failed to fetch referrals: ${response.status}`);
802
1134
  }
803
- )
804
- );
1135
+ return response.json();
1136
+ },
1137
+ getNextPageParam: (lastPage) => {
1138
+ const nextMaxId = lastPage?.[lastPage.length - 1]?.id;
1139
+ return typeof nextMaxId === "number" ? { maxId: nextMaxId } : void 0;
1140
+ }
1141
+ });
805
1142
  }
806
- function useAccountRelationsUpdate(reference, target, onSuccess, onError) {
807
- return reactQuery.useMutation({
808
- mutationKey: ["accounts", "relation", "update", reference, target],
809
- mutationFn: async (kind) => {
810
- const relationsQuery = getRelationshipBetweenAccountsQueryOptions(
811
- reference,
812
- target
813
- );
814
- await getQueryClient().prefetchQuery(relationsQuery);
815
- const actualRelation = getQueryClient().getQueryData(
816
- relationsQuery.queryKey
817
- );
818
- await broadcastJson(reference, "follow", [
819
- "follow",
1143
+ function getReferralsStatsQueryOptions(username) {
1144
+ return reactQuery.queryOptions({
1145
+ queryKey: ["accounts", "referrals-stats", username],
1146
+ queryFn: async () => {
1147
+ const response = await fetch(
1148
+ CONFIG.privateApiHost + `/private-api/referrals/${username}/stats`,
820
1149
  {
821
- follower: reference,
822
- following: target,
823
- what: [
824
- ...kind === "toggle-ignore" && !actualRelation?.ignores ? ["ignore"] : [],
825
- ...kind === "toggle-follow" && !actualRelation?.follows ? ["blog"] : []
826
- ]
1150
+ method: "GET",
1151
+ headers: {
1152
+ "Content-Type": "application/json"
1153
+ }
827
1154
  }
828
- ]);
1155
+ );
1156
+ if (!response.ok) {
1157
+ throw new Error(`Failed to fetch referral stats: ${response.status}`);
1158
+ }
1159
+ const data = await response.json();
1160
+ if (!data) {
1161
+ throw new Error("No Referrals for this user!");
1162
+ }
829
1163
  return {
830
- ...actualRelation,
831
- ignores: kind === "toggle-ignore" ? !actualRelation?.ignores : actualRelation?.ignores,
832
- follows: kind === "toggle-follow" ? !actualRelation?.follows : actualRelation?.follows
1164
+ total: data.total ?? 0,
1165
+ rewarded: data.rewarded ?? 0
833
1166
  };
1167
+ }
1168
+ });
1169
+ }
1170
+ function getFriendsInfiniteQueryOptions(following, mode, options) {
1171
+ const { followType = "blog", limit = 100, enabled = true } = options ?? {};
1172
+ return reactQuery.infiniteQueryOptions({
1173
+ queryKey: ["accounts", "friends", following, mode, followType, limit],
1174
+ initialPageParam: { startFollowing: "" },
1175
+ enabled,
1176
+ refetchOnMount: true,
1177
+ queryFn: async ({ pageParam }) => {
1178
+ const { startFollowing } = pageParam;
1179
+ const response = await CONFIG.hiveClient.database.call(
1180
+ mode === "following" ? "get_following" : "get_followers",
1181
+ [following, startFollowing === "" ? null : startFollowing, followType, limit]
1182
+ );
1183
+ const accountNames = response.map(
1184
+ (e) => mode === "following" ? e.following : e.follower
1185
+ );
1186
+ const accounts = await CONFIG.hiveClient.call("bridge", "get_profiles", {
1187
+ accounts: accountNames,
1188
+ observer: void 0
1189
+ });
1190
+ const rows = (accounts ?? []).map((a) => ({
1191
+ name: a.name,
1192
+ reputation: a.reputation,
1193
+ active: a.active
1194
+ // Return raw timestamp
1195
+ }));
1196
+ return rows;
834
1197
  },
835
- onError,
836
- onSuccess(data) {
837
- onSuccess(data);
838
- getQueryClient().setQueryData(
839
- ["accounts", "relations", reference, target],
840
- data
1198
+ getNextPageParam: (lastPage) => lastPage && lastPage.length === limit ? { startFollowing: lastPage[lastPage.length - 1].name } : void 0
1199
+ });
1200
+ }
1201
+ var SEARCH_LIMIT = 30;
1202
+ function getSearchFriendsQueryOptions(username, mode, query) {
1203
+ return reactQuery.queryOptions({
1204
+ queryKey: ["accounts", "friends", "search", username, mode, query],
1205
+ refetchOnMount: false,
1206
+ enabled: false,
1207
+ // Manual query via refetch
1208
+ queryFn: async () => {
1209
+ if (!query) return [];
1210
+ const start = query.slice(0, -1);
1211
+ const response = await CONFIG.hiveClient.database.call(
1212
+ mode === "following" ? "get_following" : "get_followers",
1213
+ [username, start, "blog", 1e3]
841
1214
  );
1215
+ const accountNames = response.map((e) => mode === "following" ? e.following : e.follower).filter((name) => name.toLowerCase().includes(query.toLowerCase())).slice(0, SEARCH_LIMIT);
1216
+ const accounts = await CONFIG.hiveClient.call("bridge", "get_profiles", {
1217
+ accounts: accountNames,
1218
+ observer: void 0
1219
+ });
1220
+ return accounts?.map((a) => ({
1221
+ name: a.name,
1222
+ full_name: a.metadata.profile?.name || "",
1223
+ reputation: a.reputation,
1224
+ active: a.active
1225
+ // Return raw timestamp
1226
+ })) ?? [];
842
1227
  }
843
1228
  });
844
1229
  }
845
- function useBookmarkAdd(username, onSuccess, onError) {
846
- return reactQuery.useMutation({
847
- mutationKey: ["accounts", "bookmarks", "add", username],
848
- mutationFn: async ({ author, permlink }) => {
849
- if (!username) {
850
- throw new Error("[SDK][Account][Bookmarks] \u2013 no active user");
851
- }
1230
+ function getTrendingTagsQueryOptions(limit = 20) {
1231
+ return reactQuery.infiniteQueryOptions({
1232
+ queryKey: ["posts", "trending-tags"],
1233
+ queryFn: async ({ pageParam: { afterTag } }) => CONFIG.hiveClient.database.call("get_trending_tags", [afterTag, limit]).then(
1234
+ (tags) => tags.filter((x) => x.name !== "").filter((x) => !x.name.startsWith("hive-")).map((x) => x.name)
1235
+ ),
1236
+ initialPageParam: { afterTag: "" },
1237
+ getNextPageParam: (lastPage) => ({
1238
+ afterTag: lastPage?.[lastPage?.length - 1]
1239
+ }),
1240
+ staleTime: Infinity,
1241
+ refetchOnMount: true
1242
+ });
1243
+ }
1244
+ function getFragmentsQueryOptions(username) {
1245
+ return reactQuery.queryOptions({
1246
+ queryKey: ["posts", "fragments", username],
1247
+ queryFn: async () => {
852
1248
  const fetchApi = getBoundFetch();
853
1249
  const response = await fetchApi(
854
- CONFIG.privateApiHost + "/private-api/bookmarks-add",
1250
+ CONFIG.privateApiHost + "/private-api/fragments",
855
1251
  {
856
1252
  method: "POST",
857
- headers: {
858
- "Content-Type": "application/json"
859
- },
860
1253
  body: JSON.stringify({
861
- author,
862
- permlink,
863
1254
  code: getAccessToken(username)
864
- })
1255
+ }),
1256
+ headers: {
1257
+ "Content-Type": "application/json"
1258
+ }
865
1259
  }
866
1260
  );
867
1261
  return response.json();
868
1262
  },
869
- onSuccess: () => {
870
- onSuccess();
871
- getQueryClient().invalidateQueries({
872
- queryKey: ["accounts", "bookmarks", username]
873
- });
874
- },
875
- onError
1263
+ enabled: !!username
876
1264
  });
877
1265
  }
878
- function useBookmarkDelete(username, onSuccess, onError) {
879
- return reactQuery.useMutation({
880
- mutationKey: ["accounts", "bookmarks", "delete", username],
881
- mutationFn: async (bookmarkId) => {
882
- if (!username) {
883
- throw new Error("[SDK][Account][Bookmarks] \u2013 no active user");
1266
+ function getPromotedPostsQuery(type = "feed") {
1267
+ return reactQuery.queryOptions({
1268
+ queryKey: ["posts", "promoted", type],
1269
+ queryFn: async () => {
1270
+ const url = new URL(
1271
+ CONFIG.privateApiHost + "/private-api/promoted-entries"
1272
+ );
1273
+ if (type === "waves") {
1274
+ url.searchParams.append("short_content", "1");
884
1275
  }
885
1276
  const fetchApi = getBoundFetch();
886
- const response = await fetchApi(
887
- CONFIG.privateApiHost + "/private-api/bookmarks-delete",
888
- {
889
- method: "POST",
890
- headers: {
891
- "Content-Type": "application/json"
892
- },
893
- body: JSON.stringify({
894
- id: bookmarkId,
895
- code: getAccessToken(username)
896
- })
1277
+ const response = await fetchApi(url.toString(), {
1278
+ method: "GET",
1279
+ headers: {
1280
+ "Content-Type": "application/json"
897
1281
  }
898
- );
899
- return response.json();
1282
+ });
1283
+ const data = await response.json();
1284
+ return data;
1285
+ }
1286
+ });
1287
+ }
1288
+ function getEntryActiveVotesQueryOptions(entry) {
1289
+ return reactQuery.queryOptions({
1290
+ queryKey: ["posts", "entry-active-votes", entry?.author, entry?.permlink],
1291
+ queryFn: async () => {
1292
+ return CONFIG.hiveClient.database.call("get_active_votes", [
1293
+ entry?.author,
1294
+ entry?.permlink
1295
+ ]);
900
1296
  },
901
- onSuccess: () => {
902
- onSuccess();
903
- getQueryClient().invalidateQueries({
904
- queryKey: ["accounts", "bookmarks", username]
1297
+ enabled: !!entry
1298
+ });
1299
+ }
1300
+ function getPostHeaderQueryOptions(author, permlink) {
1301
+ return reactQuery.queryOptions({
1302
+ queryKey: ["posts", "post-header", author, permlink],
1303
+ queryFn: async () => {
1304
+ return CONFIG.hiveClient.call("bridge", "get_post_header", {
1305
+ author,
1306
+ permlink
905
1307
  });
906
1308
  },
907
- onError
1309
+ initialData: null
908
1310
  });
909
1311
  }
910
- function useAccountFavouriteAdd(username, onSuccess, onError) {
911
- return reactQuery.useMutation({
912
- mutationKey: ["accounts", "favourites", "add", username],
913
- mutationFn: async (account) => {
914
- if (!username) {
915
- throw new Error("[SDK][Account][Bookmarks] \u2013 no active user");
1312
+
1313
+ // src/modules/posts/utils/filter-dmca-entries.ts
1314
+ function filterDmcaEntry(entryOrEntries) {
1315
+ if (Array.isArray(entryOrEntries)) {
1316
+ return entryOrEntries.map((entry) => applyFilter(entry));
1317
+ }
1318
+ return applyFilter(entryOrEntries);
1319
+ }
1320
+ function applyFilter(entry) {
1321
+ if (!entry) return entry;
1322
+ const entryPath = `@${entry.author}/${entry.permlink}`;
1323
+ const isDmca = CONFIG.dmcaPatternRegexes.some((regex) => regex.test(entryPath));
1324
+ if (isDmca) {
1325
+ return {
1326
+ ...entry,
1327
+ body: "This post is not available due to a copyright/fraudulent claim.",
1328
+ title: ""
1329
+ };
1330
+ }
1331
+ return entry;
1332
+ }
1333
+
1334
+ // src/modules/posts/queries/get-post-query-options.ts
1335
+ function makeEntryPath(category, author, permlink) {
1336
+ return `${category}/@${author}/${permlink}`;
1337
+ }
1338
+ function getPostQueryOptions(author, permlink, observer = "", num) {
1339
+ const cleanPermlink = permlink?.trim();
1340
+ const entryPath = makeEntryPath("", author, cleanPermlink ?? "");
1341
+ return reactQuery.queryOptions({
1342
+ queryKey: ["posts", "entry", entryPath],
1343
+ queryFn: async () => {
1344
+ if (!cleanPermlink || cleanPermlink === "undefined") {
1345
+ return null;
916
1346
  }
917
- const fetchApi = getBoundFetch();
918
- const response = await fetchApi(
919
- CONFIG.privateApiHost + "/private-api/favorites-add",
920
- {
921
- method: "POST",
922
- headers: {
923
- "Content-Type": "application/json"
924
- },
925
- body: JSON.stringify({
926
- account,
927
- code: getAccessToken(username)
928
- })
929
- }
930
- );
931
- return response.json();
932
- },
933
- onSuccess: () => {
934
- onSuccess();
935
- getQueryClient().invalidateQueries({
936
- queryKey: ["accounts", "favourites", username]
1347
+ const response = await CONFIG.hiveClient.call("bridge", "get_post", {
1348
+ author,
1349
+ permlink: cleanPermlink,
1350
+ observer
937
1351
  });
1352
+ if (!response) {
1353
+ return null;
1354
+ }
1355
+ const entry = num !== void 0 ? { ...response, num } : response;
1356
+ return filterDmcaEntry(entry);
938
1357
  },
939
- onError
1358
+ enabled: !!author && !!permlink && permlink.trim() !== "" && permlink.trim() !== "undefined"
940
1359
  });
941
1360
  }
942
- function useAccountFavouriteDelete(username, onSuccess, onError) {
943
- return reactQuery.useMutation({
944
- mutationKey: ["accounts", "favourites", "add", username],
945
- mutationFn: async (account) => {
946
- if (!username) {
947
- throw new Error("[SDK][Account][Bookmarks] \u2013 no active user");
1361
+ var SortOrder = /* @__PURE__ */ ((SortOrder2) => {
1362
+ SortOrder2["trending"] = "trending";
1363
+ SortOrder2["author_reputation"] = "author_reputation";
1364
+ SortOrder2["votes"] = "votes";
1365
+ SortOrder2["created"] = "created";
1366
+ return SortOrder2;
1367
+ })(SortOrder || {});
1368
+ function parseAsset2(value) {
1369
+ const match = value.match(/^(\d+\.?\d*)\s*([A-Z]+)$/);
1370
+ if (!match) return { amount: 0, symbol: "" };
1371
+ return {
1372
+ amount: parseFloat(match[1]),
1373
+ symbol: match[2]
1374
+ };
1375
+ }
1376
+ function sortDiscussions(entry, discussion, order) {
1377
+ const allPayout = (c) => parseAsset2(c.pending_payout_value).amount + parseAsset2(c.author_payout_value).amount + parseAsset2(c.curator_payout_value).amount;
1378
+ const absNegative = (a) => a.net_rshares < 0;
1379
+ const isPinned = (a) => entry.json_metadata?.pinned_reply === `${a.author}/${a.permlink}`;
1380
+ const sortOrders = {
1381
+ trending: (a, b) => {
1382
+ if (absNegative(a)) {
1383
+ return 1;
948
1384
  }
949
- const fetchApi = getBoundFetch();
950
- const response = await fetchApi(
951
- CONFIG.privateApiHost + "/private-api/favorites-delete",
952
- {
953
- method: "POST",
954
- headers: {
955
- "Content-Type": "application/json"
956
- },
957
- body: JSON.stringify({
958
- account,
959
- code: getAccessToken(username)
960
- })
961
- }
962
- );
963
- return response.json();
1385
+ if (absNegative(b)) {
1386
+ return -1;
1387
+ }
1388
+ const _a = allPayout(a);
1389
+ const _b = allPayout(b);
1390
+ if (_a !== _b) {
1391
+ return _b - _a;
1392
+ }
1393
+ return 0;
964
1394
  },
965
- onSuccess: () => {
966
- onSuccess();
967
- getQueryClient().invalidateQueries({
968
- queryKey: ["accounts", "favourites", username]
969
- });
1395
+ author_reputation: (a, b) => {
1396
+ const keyA = a.author_reputation;
1397
+ const keyB = b.author_reputation;
1398
+ if (keyA > keyB) return -1;
1399
+ if (keyA < keyB) return 1;
1400
+ return 0;
970
1401
  },
971
- onError
972
- });
1402
+ votes: (a, b) => {
1403
+ const keyA = a.children;
1404
+ const keyB = b.children;
1405
+ if (keyA > keyB) return -1;
1406
+ if (keyA < keyB) return 1;
1407
+ return 0;
1408
+ },
1409
+ created: (a, b) => {
1410
+ if (absNegative(a)) {
1411
+ return 1;
1412
+ }
1413
+ if (absNegative(b)) {
1414
+ return -1;
1415
+ }
1416
+ const keyA = Date.parse(a.created);
1417
+ const keyB = Date.parse(b.created);
1418
+ if (keyA > keyB) return -1;
1419
+ if (keyA < keyB) return 1;
1420
+ return 0;
1421
+ }
1422
+ };
1423
+ const sorted = discussion.sort(sortOrders[order]);
1424
+ const pinnedIndex = sorted.findIndex((i) => isPinned(i));
1425
+ const pinned = sorted[pinnedIndex];
1426
+ if (pinnedIndex >= 0) {
1427
+ sorted.splice(pinnedIndex, 1);
1428
+ sorted.unshift(pinned);
1429
+ }
1430
+ return sorted;
973
1431
  }
974
- function dedupeAndSortKeyAuths(existing, additions) {
975
- const merged = /* @__PURE__ */ new Map();
976
- existing.forEach(([key, weight]) => {
977
- merged.set(key.toString(), weight);
978
- });
979
- additions.forEach(([key, weight]) => {
980
- merged.set(key.toString(), weight);
1432
+ function getDiscussionsQueryOptions(entry, order = "created" /* created */, enabled = true, observer) {
1433
+ return reactQuery.queryOptions({
1434
+ queryKey: [
1435
+ "posts",
1436
+ "discussions",
1437
+ entry?.author,
1438
+ entry?.permlink,
1439
+ order,
1440
+ observer || entry?.author
1441
+ ],
1442
+ queryFn: async () => {
1443
+ if (!entry) {
1444
+ return [];
1445
+ }
1446
+ const response = await CONFIG.hiveClient.call("bridge", "get_discussion", {
1447
+ author: entry.author,
1448
+ permlink: entry.permlink,
1449
+ observer: observer || entry.author
1450
+ });
1451
+ const results = response ? Array.from(Object.values(response)) : [];
1452
+ return filterDmcaEntry(results);
1453
+ },
1454
+ enabled: enabled && !!entry,
1455
+ select: (data) => sortDiscussions(entry, data, order)
981
1456
  });
982
- return Array.from(merged.entries()).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)).map(([key, weight]) => [key, weight]);
983
1457
  }
984
- function useAccountUpdateKeyAuths(username, options) {
985
- const { data: accountData } = reactQuery.useQuery(getAccountFullQueryOptions(username));
986
- return reactQuery.useMutation({
987
- mutationKey: ["accounts", "keys-update", username],
988
- mutationFn: async ({ keys, keepCurrent = false, currentKey }) => {
989
- if (!accountData) {
990
- throw new Error(
991
- "[SDK][Update password] \u2013 cannot update keys for anon user"
1458
+ function getAccountPostsInfiniteQueryOptions(username, filter = "posts", limit = 20, observer = "", enabled = true) {
1459
+ return reactQuery.infiniteQueryOptions({
1460
+ queryKey: ["posts", "account-posts", username ?? "", filter, limit, observer],
1461
+ enabled: !!username && enabled,
1462
+ initialPageParam: {
1463
+ author: void 0,
1464
+ permlink: void 0,
1465
+ hasNextPage: true
1466
+ },
1467
+ queryFn: async ({ pageParam }) => {
1468
+ if (!pageParam?.hasNextPage || !username) return [];
1469
+ const rpcParams = {
1470
+ sort: filter,
1471
+ account: username,
1472
+ limit,
1473
+ ...observer && observer.length > 0 ? { observer } : {},
1474
+ ...pageParam.author ? { start_author: pageParam.author } : {},
1475
+ ...pageParam.permlink ? { start_permlink: pageParam.permlink } : {}
1476
+ };
1477
+ try {
1478
+ if (CONFIG.dmcaAccounts.includes(username)) return [];
1479
+ const resp = await CONFIG.hiveClient.call(
1480
+ "bridge",
1481
+ "get_account_posts",
1482
+ rpcParams
992
1483
  );
1484
+ if (resp && Array.isArray(resp)) {
1485
+ return filterDmcaEntry(resp);
1486
+ }
1487
+ return [];
1488
+ } catch (err) {
1489
+ console.error("[SDK] get_account_posts error:", err);
1490
+ return [];
993
1491
  }
994
- const prepareAuth = (keyName) => {
995
- const auth = R4__namespace.clone(accountData[keyName]);
996
- auth.key_auths = dedupeAndSortKeyAuths(
997
- keepCurrent ? auth.key_auths : [],
998
- keys.map(
999
- (values, i) => [values[keyName].createPublic().toString(), i + 1]
1000
- )
1001
- );
1002
- return auth;
1003
- };
1004
- return CONFIG.hiveClient.broadcast.updateAccount(
1005
- {
1006
- account: username,
1007
- json_metadata: accountData.json_metadata,
1008
- owner: prepareAuth("owner"),
1009
- active: prepareAuth("active"),
1010
- posting: prepareAuth("posting"),
1011
- memo_key: keepCurrent ? accountData.memo_key : keys[0].memo_key.createPublic().toString()
1012
- },
1013
- currentKey
1014
- );
1015
1492
  },
1016
- ...options
1493
+ getNextPageParam: (lastPage) => {
1494
+ const last = lastPage?.[lastPage.length - 1];
1495
+ const hasNextPage = (lastPage?.length ?? 0) === limit;
1496
+ if (!hasNextPage) {
1497
+ return void 0;
1498
+ }
1499
+ return {
1500
+ author: last?.author,
1501
+ permlink: last?.permlink,
1502
+ hasNextPage
1503
+ };
1504
+ }
1017
1505
  });
1018
1506
  }
1019
- function useAccountUpdatePassword(username, options) {
1020
- const { data: accountData } = reactQuery.useQuery(getAccountFullQueryOptions(username));
1021
- const { mutateAsync: updateKeys } = useAccountUpdateKeyAuths(username);
1022
- return reactQuery.useMutation({
1023
- mutationKey: ["accounts", "password-update", username],
1507
+ function getPostsRankedInfiniteQueryOptions(sort, tag, limit = 20, observer = "", enabled = true, _options = {}) {
1508
+ return reactQuery.infiniteQueryOptions({
1509
+ queryKey: ["posts", "posts-ranked", sort, tag, limit, observer],
1510
+ queryFn: async ({ pageParam }) => {
1511
+ if (!pageParam.hasNextPage) {
1512
+ return [];
1513
+ }
1514
+ let sanitizedTag = tag;
1515
+ if (CONFIG.dmcaTagRegexes.some((regex) => regex.test(tag))) {
1516
+ sanitizedTag = "";
1517
+ }
1518
+ const response = await CONFIG.hiveClient.call("bridge", "get_ranked_posts", {
1519
+ sort,
1520
+ start_author: pageParam.author,
1521
+ start_permlink: pageParam.permlink,
1522
+ limit,
1523
+ tag: sanitizedTag,
1524
+ observer
1525
+ });
1526
+ if (response && Array.isArray(response)) {
1527
+ const data = response;
1528
+ const sorted = sort === "hot" ? data : data.sort(
1529
+ (a, b) => new Date(b.created).getTime() - new Date(a.created).getTime()
1530
+ );
1531
+ const pinnedEntry = sorted.find((s) => s.stats?.is_pinned);
1532
+ const nonPinnedEntries = sorted.filter((s) => !s.stats?.is_pinned);
1533
+ const combined = [pinnedEntry, ...nonPinnedEntries].filter((s) => !!s);
1534
+ return filterDmcaEntry(combined);
1535
+ }
1536
+ return [];
1537
+ },
1538
+ enabled,
1539
+ initialPageParam: {
1540
+ author: void 0,
1541
+ permlink: void 0,
1542
+ hasNextPage: true
1543
+ },
1544
+ getNextPageParam: (lastPage) => {
1545
+ const last = lastPage?.[lastPage.length - 1];
1546
+ return {
1547
+ author: last?.author,
1548
+ permlink: last?.permlink,
1549
+ hasNextPage: (lastPage?.length ?? 0) > 0
1550
+ };
1551
+ }
1552
+ });
1553
+ }
1554
+ function getReblogsQueryOptions(username, activeUsername, limit = 200) {
1555
+ return reactQuery.queryOptions({
1556
+ queryKey: ["posts", "reblogs", username ?? "", limit],
1557
+ queryFn: async () => {
1558
+ const response = await CONFIG.hiveClient.call("condenser_api", "get_blog_entries", [
1559
+ username ?? activeUsername,
1560
+ 0,
1561
+ limit
1562
+ ]);
1563
+ return response.filter(
1564
+ (i) => i.author !== activeUsername && !i.reblogged_on.startsWith("1970-")
1565
+ ).map((i) => ({ author: i.author, permlink: i.permlink }));
1566
+ },
1567
+ enabled: !!username
1568
+ });
1569
+ }
1570
+ function getSchedulesQueryOptions(activeUsername) {
1571
+ return reactQuery.queryOptions({
1572
+ queryKey: ["posts", "schedules", activeUsername],
1573
+ queryFn: async () => {
1574
+ if (!activeUsername) {
1575
+ return [];
1576
+ }
1577
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/schedules", {
1578
+ method: "POST",
1579
+ headers: {
1580
+ "Content-Type": "application/json"
1581
+ },
1582
+ body: JSON.stringify({
1583
+ code: getAccessToken(activeUsername)
1584
+ })
1585
+ });
1586
+ if (!response.ok) {
1587
+ throw new Error(`Failed to fetch schedules: ${response.status}`);
1588
+ }
1589
+ return response.json();
1590
+ },
1591
+ enabled: !!activeUsername
1592
+ });
1593
+ }
1594
+ function getDraftsQueryOptions(activeUsername) {
1595
+ return reactQuery.queryOptions({
1596
+ queryKey: ["posts", "drafts", activeUsername],
1597
+ queryFn: async () => {
1598
+ if (!activeUsername) {
1599
+ return [];
1600
+ }
1601
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/drafts", {
1602
+ method: "POST",
1603
+ headers: {
1604
+ "Content-Type": "application/json"
1605
+ },
1606
+ body: JSON.stringify({
1607
+ code: getAccessToken(activeUsername)
1608
+ })
1609
+ });
1610
+ if (!response.ok) {
1611
+ throw new Error(`Failed to fetch drafts: ${response.status}`);
1612
+ }
1613
+ return response.json();
1614
+ },
1615
+ enabled: !!activeUsername
1616
+ });
1617
+ }
1618
+ async function fetchUserImages(username) {
1619
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/images", {
1620
+ method: "POST",
1621
+ headers: {
1622
+ "Content-Type": "application/json"
1623
+ },
1624
+ body: JSON.stringify({
1625
+ code: getAccessToken(username)
1626
+ })
1627
+ });
1628
+ if (!response.ok) {
1629
+ throw new Error(`Failed to fetch images: ${response.status}`);
1630
+ }
1631
+ return response.json();
1632
+ }
1633
+ function getImagesQueryOptions(username) {
1634
+ return reactQuery.queryOptions({
1635
+ queryKey: ["posts", "images", username],
1636
+ queryFn: async () => {
1637
+ if (!username) {
1638
+ return [];
1639
+ }
1640
+ return fetchUserImages(username);
1641
+ },
1642
+ enabled: !!username
1643
+ });
1644
+ }
1645
+ function getGalleryImagesQueryOptions(activeUsername) {
1646
+ return reactQuery.queryOptions({
1647
+ queryKey: ["posts", "gallery-images", activeUsername],
1648
+ queryFn: async () => {
1649
+ if (!activeUsername) {
1650
+ return [];
1651
+ }
1652
+ return fetchUserImages(activeUsername);
1653
+ },
1654
+ enabled: !!activeUsername
1655
+ });
1656
+ }
1657
+ function getCommentHistoryQueryOptions(author, permlink, onlyMeta = false) {
1658
+ return reactQuery.queryOptions({
1659
+ queryKey: ["posts", "comment-history", author, permlink, onlyMeta],
1660
+ queryFn: async ({ signal }) => {
1661
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/comment-history", {
1662
+ method: "POST",
1663
+ headers: {
1664
+ "Content-Type": "application/json"
1665
+ },
1666
+ body: JSON.stringify({
1667
+ author,
1668
+ permlink,
1669
+ onlyMeta: onlyMeta ? "1" : ""
1670
+ }),
1671
+ signal
1672
+ });
1673
+ if (!response.ok) {
1674
+ throw new Error(`Failed to fetch comment history: ${response.status}`);
1675
+ }
1676
+ return response.json();
1677
+ },
1678
+ enabled: !!author && !!permlink
1679
+ });
1680
+ }
1681
+ function makeEntryPath2(author, permlink) {
1682
+ const cleanAuthor = author?.trim();
1683
+ const cleanPermlink = permlink?.trim();
1684
+ if (!cleanAuthor || !cleanPermlink) {
1685
+ throw new Error("Invalid entry path: author and permlink are required");
1686
+ }
1687
+ const normalizedAuthor = cleanAuthor.replace(/^@+/, "");
1688
+ const normalizedPermlink = cleanPermlink.replace(/^\/+/, "");
1689
+ if (!normalizedAuthor || !normalizedPermlink) {
1690
+ throw new Error("Invalid entry path: author and permlink cannot be empty after normalization");
1691
+ }
1692
+ return `@${normalizedAuthor}/${normalizedPermlink}`;
1693
+ }
1694
+ function getDeletedEntryQueryOptions(author, permlink) {
1695
+ const cleanPermlink = permlink?.trim();
1696
+ const cleanAuthor = author?.trim();
1697
+ const isValid = !!cleanAuthor && !!cleanPermlink && cleanPermlink !== "undefined";
1698
+ const entryPath = isValid ? makeEntryPath2(cleanAuthor, cleanPermlink) : "";
1699
+ return reactQuery.queryOptions({
1700
+ queryKey: ["posts", "deleted-entry", entryPath],
1701
+ queryFn: async ({ signal }) => {
1702
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/comment-history", {
1703
+ method: "POST",
1704
+ headers: {
1705
+ "Content-Type": "application/json"
1706
+ },
1707
+ body: JSON.stringify({
1708
+ author,
1709
+ permlink: cleanPermlink || ""
1710
+ }),
1711
+ signal
1712
+ });
1713
+ if (!response.ok) {
1714
+ throw new Error(`Failed to fetch comment history: ${response.status}`);
1715
+ }
1716
+ return response.json();
1717
+ },
1718
+ select: (history) => {
1719
+ if (!history?.list?.[0]) {
1720
+ return null;
1721
+ }
1722
+ const { body, title, tags } = history.list[0];
1723
+ return {
1724
+ body,
1725
+ title,
1726
+ tags
1727
+ };
1728
+ },
1729
+ enabled: isValid
1730
+ });
1731
+ }
1732
+ function getPostTipsQueryOptions(author, permlink, isEnabled = true) {
1733
+ return reactQuery.queryOptions({
1734
+ queryKey: ["posts", "tips", author, permlink],
1735
+ queryFn: async () => {
1736
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/post-tips", {
1737
+ method: "POST",
1738
+ headers: {
1739
+ "Content-Type": "application/json"
1740
+ },
1741
+ body: JSON.stringify({
1742
+ author,
1743
+ permlink
1744
+ })
1745
+ });
1746
+ if (!response.ok) {
1747
+ throw new Error(`Failed to fetch post tips: ${response.status}`);
1748
+ }
1749
+ return response.json();
1750
+ },
1751
+ enabled: !!author && !!permlink && isEnabled
1752
+ });
1753
+ }
1754
+
1755
+ // src/modules/posts/utils/waves-helpers.ts
1756
+ function normalizeContainer(entry, host) {
1757
+ return {
1758
+ ...entry,
1759
+ id: entry.id ?? entry.post_id,
1760
+ host
1761
+ };
1762
+ }
1763
+ function normalizeParent(entry) {
1764
+ return {
1765
+ ...entry,
1766
+ id: entry.id ?? entry.post_id
1767
+ };
1768
+ }
1769
+ function normalizeWaveEntryFromApi(entry, host) {
1770
+ if (!entry) {
1771
+ return null;
1772
+ }
1773
+ const containerSource = entry.container ?? entry;
1774
+ const container = normalizeContainer(containerSource, host);
1775
+ const parent = entry.parent ? normalizeParent(entry.parent) : void 0;
1776
+ return {
1777
+ ...entry,
1778
+ id: entry.id ?? entry.post_id,
1779
+ host,
1780
+ container,
1781
+ parent
1782
+ };
1783
+ }
1784
+ function toEntryArray(x) {
1785
+ return Array.isArray(x) ? x : [];
1786
+ }
1787
+ async function getVisibleFirstLevelThreadItems(container) {
1788
+ const queryOptions76 = getDiscussionsQueryOptions(container, "created" /* created */, true);
1789
+ const discussionItemsRaw = await CONFIG.queryClient.fetchQuery(queryOptions76);
1790
+ const discussionItems = toEntryArray(discussionItemsRaw);
1791
+ if (discussionItems.length <= 1) {
1792
+ return [];
1793
+ }
1794
+ const firstLevelItems = discussionItems.filter(
1795
+ ({ parent_author, parent_permlink }) => parent_author === container.author && parent_permlink === container.permlink
1796
+ );
1797
+ if (firstLevelItems.length === 0) {
1798
+ return [];
1799
+ }
1800
+ const visibleItems = firstLevelItems.filter((item) => !item.stats?.gray);
1801
+ return visibleItems;
1802
+ }
1803
+ function mapThreadItemsToWaveEntries(items, container, host) {
1804
+ if (items.length === 0) {
1805
+ return [];
1806
+ }
1807
+ return items.map((item) => {
1808
+ const parent = items.find(
1809
+ (i) => i.author === item.parent_author && i.permlink === item.parent_permlink && i.author !== host
1810
+ );
1811
+ return {
1812
+ ...item,
1813
+ id: item.post_id,
1814
+ host,
1815
+ container,
1816
+ parent
1817
+ };
1818
+ }).filter((entry) => entry.container.post_id !== entry.post_id).sort(
1819
+ (a, b) => new Date(b.created).getTime() - new Date(a.created).getTime()
1820
+ );
1821
+ }
1822
+
1823
+ // src/modules/posts/queries/get-waves-by-host-query-options.ts
1824
+ var THREAD_CONTAINER_BATCH_SIZE = 5;
1825
+ var MAX_CONTAINERS_TO_SCAN = 50;
1826
+ async function getThreads(host, pageParam) {
1827
+ let startAuthor = pageParam?.author;
1828
+ let startPermlink = pageParam?.permlink;
1829
+ let scannedContainers = 0;
1830
+ let skipContainerId = pageParam?.post_id;
1831
+ while (scannedContainers < MAX_CONTAINERS_TO_SCAN) {
1832
+ const rpcParams = {
1833
+ sort: "posts",
1834
+ // ProfileFilter.posts
1835
+ account: host,
1836
+ limit: THREAD_CONTAINER_BATCH_SIZE,
1837
+ ...startAuthor ? { start_author: startAuthor } : {},
1838
+ ...startPermlink ? { start_permlink: startPermlink } : {}
1839
+ };
1840
+ const containers = await CONFIG.hiveClient.call(
1841
+ "bridge",
1842
+ "get_account_posts",
1843
+ rpcParams
1844
+ );
1845
+ if (!containers || containers.length === 0) {
1846
+ return null;
1847
+ }
1848
+ const normalizedContainers = containers.map((container) => {
1849
+ container.id = container.post_id;
1850
+ container.host = host;
1851
+ return container;
1852
+ });
1853
+ for (const container of normalizedContainers) {
1854
+ if (skipContainerId && container.post_id === skipContainerId) {
1855
+ skipContainerId = void 0;
1856
+ continue;
1857
+ }
1858
+ scannedContainers += 1;
1859
+ if (container.stats?.gray) {
1860
+ startAuthor = container.author;
1861
+ startPermlink = container.permlink;
1862
+ continue;
1863
+ }
1864
+ const visibleItems = await getVisibleFirstLevelThreadItems(container);
1865
+ if (visibleItems.length === 0) {
1866
+ startAuthor = container.author;
1867
+ startPermlink = container.permlink;
1868
+ continue;
1869
+ }
1870
+ return {
1871
+ entries: mapThreadItemsToWaveEntries(visibleItems, container, host)
1872
+ };
1873
+ }
1874
+ const lastContainer = normalizedContainers[normalizedContainers.length - 1];
1875
+ if (!lastContainer) {
1876
+ return null;
1877
+ }
1878
+ startAuthor = lastContainer.author;
1879
+ startPermlink = lastContainer.permlink;
1880
+ }
1881
+ return null;
1882
+ }
1883
+ function getWavesByHostQueryOptions(host) {
1884
+ return reactQuery.infiniteQueryOptions({
1885
+ queryKey: ["posts", "waves", "by-host", host],
1886
+ initialPageParam: void 0,
1887
+ queryFn: async ({ pageParam }) => {
1888
+ const result = await getThreads(host, pageParam);
1889
+ if (!result) return [];
1890
+ return result.entries;
1891
+ },
1892
+ getNextPageParam: (lastPage) => lastPage?.[0]?.container
1893
+ });
1894
+ }
1895
+ var DEFAULT_TAG_FEED_LIMIT = 40;
1896
+ function getWavesByTagQueryOptions(host, tag, limit = DEFAULT_TAG_FEED_LIMIT) {
1897
+ return reactQuery.infiniteQueryOptions({
1898
+ queryKey: ["posts", "waves", "by-tag", host, tag],
1899
+ initialPageParam: void 0,
1900
+ queryFn: async ({ signal }) => {
1901
+ try {
1902
+ const url = new URL(CONFIG.privateApiHost + "/private-api/waves/tags");
1903
+ url.searchParams.set("container", host);
1904
+ url.searchParams.set("tag", tag);
1905
+ const response = await fetch(url.toString(), {
1906
+ method: "GET",
1907
+ headers: {
1908
+ "Content-Type": "application/json"
1909
+ },
1910
+ signal
1911
+ });
1912
+ if (!response.ok) {
1913
+ throw new Error(`Failed to fetch waves by tag: ${response.status}`);
1914
+ }
1915
+ const data = await response.json();
1916
+ const result = data.slice(0, limit).map((entry) => normalizeWaveEntryFromApi(entry, host)).filter((entry) => Boolean(entry));
1917
+ return result.sort(
1918
+ (a, b) => new Date(b.created).getTime() - new Date(a.created).getTime()
1919
+ );
1920
+ } catch (error) {
1921
+ console.error("[SDK] Failed to fetch waves by tag", error);
1922
+ return [];
1923
+ }
1924
+ },
1925
+ getNextPageParam: () => void 0
1926
+ });
1927
+ }
1928
+ function getWavesFollowingQueryOptions(host, username) {
1929
+ const normalizedUsername = username?.trim().toLowerCase();
1930
+ return reactQuery.infiniteQueryOptions({
1931
+ queryKey: ["posts", "waves", "following", host, normalizedUsername ?? ""],
1932
+ enabled: Boolean(normalizedUsername),
1933
+ initialPageParam: void 0,
1934
+ queryFn: async ({ signal }) => {
1935
+ if (!normalizedUsername) {
1936
+ return [];
1937
+ }
1938
+ try {
1939
+ const url = new URL(CONFIG.privateApiHost + "/private-api/waves/following");
1940
+ url.searchParams.set("container", host);
1941
+ url.searchParams.set("username", normalizedUsername);
1942
+ const response = await fetch(url.toString(), {
1943
+ method: "GET",
1944
+ headers: {
1945
+ "Content-Type": "application/json"
1946
+ },
1947
+ signal
1948
+ });
1949
+ if (!response.ok) {
1950
+ throw new Error(`Failed to fetch waves following feed: ${response.status}`);
1951
+ }
1952
+ const data = await response.json();
1953
+ if (!Array.isArray(data) || data.length === 0) {
1954
+ return [];
1955
+ }
1956
+ const flattened = data.map((entry) => normalizeWaveEntryFromApi(entry, host)).filter((entry) => Boolean(entry));
1957
+ if (flattened.length === 0) {
1958
+ return [];
1959
+ }
1960
+ return flattened.sort(
1961
+ (a, b) => new Date(b.created).getTime() - new Date(a.created).getTime()
1962
+ );
1963
+ } catch (error) {
1964
+ console.error("[SDK] Failed to fetch waves following feed", error);
1965
+ return [];
1966
+ }
1967
+ },
1968
+ getNextPageParam: () => void 0
1969
+ });
1970
+ }
1971
+ function getWavesTrendingTagsQueryOptions(host, hours = 24) {
1972
+ return reactQuery.queryOptions({
1973
+ queryKey: ["posts", "waves", "trending-tags", host, hours],
1974
+ queryFn: async ({ signal }) => {
1975
+ try {
1976
+ const url = new URL(CONFIG.privateApiHost + "/private-api/waves/trending/tags");
1977
+ url.searchParams.set("container", host);
1978
+ url.searchParams.set("hours", hours.toString());
1979
+ const response = await fetch(url.toString(), {
1980
+ method: "GET",
1981
+ headers: {
1982
+ "Content-Type": "application/json"
1983
+ },
1984
+ signal
1985
+ });
1986
+ if (!response.ok) {
1987
+ throw new Error(`Failed to fetch waves trending tags: ${response.status}`);
1988
+ }
1989
+ const data = await response.json();
1990
+ return data.map(({ tag, posts }) => ({ tag, posts }));
1991
+ } catch (error) {
1992
+ console.error("[SDK] Failed to fetch waves trending tags", error);
1993
+ return [];
1994
+ }
1995
+ }
1996
+ });
1997
+ }
1998
+
1999
+ // src/modules/accounts/queries/get-account-vote-history-infinite-query-options.ts
2000
+ function isEntry(x) {
2001
+ return !!x && typeof x === "object" && "author" in x && "permlink" in x && "active_votes" in x;
2002
+ }
2003
+ function getDays(createdDate) {
2004
+ const past = new Date(createdDate);
2005
+ const now = /* @__PURE__ */ new Date();
2006
+ const diffMs = now.getTime() - past.getTime();
2007
+ return diffMs / (1e3 * 60 * 60 * 24);
2008
+ }
2009
+ function getAccountVoteHistoryInfiniteQueryOptions(username, options) {
2010
+ const { limit = 20, filters = [], dayLimit = 7 } = options ?? {};
2011
+ return reactQuery.infiniteQueryOptions({
2012
+ queryKey: ["accounts", "vote-history", username, limit],
2013
+ initialPageParam: { start: -1 },
2014
+ queryFn: async ({ pageParam }) => {
2015
+ const { start } = pageParam;
2016
+ const response = await CONFIG.hiveClient.call(
2017
+ "condenser_api",
2018
+ "get_account_history",
2019
+ [username, start, limit, ...filters]
2020
+ );
2021
+ const mappedResults = response.map(([num, historyObj]) => ({
2022
+ ...historyObj.op[1],
2023
+ num,
2024
+ timestamp: historyObj.timestamp
2025
+ }));
2026
+ const result = mappedResults.filter(
2027
+ (filtered) => filtered.voter === username && filtered.weight !== 0 && getDays(filtered.timestamp) <= dayLimit
2028
+ );
2029
+ const entries = [];
2030
+ for (const obj of result) {
2031
+ const post = await CONFIG.queryClient.fetchQuery(
2032
+ getPostQueryOptions(obj.author, obj.permlink)
2033
+ );
2034
+ if (isEntry(post)) entries.push(post);
2035
+ }
2036
+ const [firstHistory] = response;
2037
+ return {
2038
+ lastDate: firstHistory ? getDays(firstHistory[1].timestamp) : 0,
2039
+ lastItemFetched: firstHistory ? firstHistory[0] : start,
2040
+ entries
2041
+ };
2042
+ },
2043
+ getNextPageParam: (lastPage) => ({
2044
+ start: lastPage.lastItemFetched
2045
+ })
2046
+ });
2047
+ }
2048
+
2049
+ // src/modules/accounts/mutations/use-account-update.ts
2050
+ function useAccountUpdate(username) {
2051
+ const queryClient = reactQuery.useQueryClient();
2052
+ const { data } = reactQuery.useQuery(getAccountFullQueryOptions(username));
2053
+ return useBroadcastMutation(
2054
+ ["accounts", "update"],
2055
+ username,
2056
+ (payload) => {
2057
+ if (!data) {
2058
+ throw new Error("[SDK][Accounts] \u2013 cannot update not existing account");
2059
+ }
2060
+ const profile = buildProfileMetadata({
2061
+ existingProfile: extractAccountProfile(data),
2062
+ profile: payload.profile,
2063
+ tokens: payload.tokens
2064
+ });
2065
+ return [
2066
+ [
2067
+ "account_update2",
2068
+ {
2069
+ account: username,
2070
+ json_metadata: "",
2071
+ extensions: [],
2072
+ posting_json_metadata: JSON.stringify({
2073
+ profile
2074
+ })
2075
+ }
2076
+ ]
2077
+ ];
2078
+ },
2079
+ (_, variables) => queryClient.setQueryData(
2080
+ getAccountFullQueryOptions(username).queryKey,
2081
+ (data2) => {
2082
+ if (!data2) {
2083
+ return data2;
2084
+ }
2085
+ const obj = R4__namespace.clone(data2);
2086
+ obj.profile = buildProfileMetadata({
2087
+ existingProfile: extractAccountProfile(data2),
2088
+ profile: variables.profile,
2089
+ tokens: variables.tokens
2090
+ });
2091
+ return obj;
2092
+ }
2093
+ )
2094
+ );
2095
+ }
2096
+ function useAccountRelationsUpdate(reference, target, onSuccess, onError) {
2097
+ return reactQuery.useMutation({
2098
+ mutationKey: ["accounts", "relation", "update", reference, target],
2099
+ mutationFn: async (kind) => {
2100
+ const relationsQuery = getRelationshipBetweenAccountsQueryOptions(
2101
+ reference,
2102
+ target
2103
+ );
2104
+ await getQueryClient().prefetchQuery(relationsQuery);
2105
+ const actualRelation = getQueryClient().getQueryData(
2106
+ relationsQuery.queryKey
2107
+ );
2108
+ await broadcastJson(reference, "follow", [
2109
+ "follow",
2110
+ {
2111
+ follower: reference,
2112
+ following: target,
2113
+ what: [
2114
+ ...kind === "toggle-ignore" && !actualRelation?.ignores ? ["ignore"] : [],
2115
+ ...kind === "toggle-follow" && !actualRelation?.follows ? ["blog"] : []
2116
+ ]
2117
+ }
2118
+ ]);
2119
+ return {
2120
+ ...actualRelation,
2121
+ ignores: kind === "toggle-ignore" ? !actualRelation?.ignores : actualRelation?.ignores,
2122
+ follows: kind === "toggle-follow" ? !actualRelation?.follows : actualRelation?.follows
2123
+ };
2124
+ },
2125
+ onError,
2126
+ onSuccess(data) {
2127
+ onSuccess(data);
2128
+ getQueryClient().setQueryData(
2129
+ ["accounts", "relations", reference, target],
2130
+ data
2131
+ );
2132
+ }
2133
+ });
2134
+ }
2135
+ function useBookmarkAdd(username, onSuccess, onError) {
2136
+ return reactQuery.useMutation({
2137
+ mutationKey: ["accounts", "bookmarks", "add", username],
2138
+ mutationFn: async ({ author, permlink }) => {
2139
+ if (!username) {
2140
+ throw new Error("[SDK][Account][Bookmarks] \u2013 no active user");
2141
+ }
2142
+ const fetchApi = getBoundFetch();
2143
+ const response = await fetchApi(
2144
+ CONFIG.privateApiHost + "/private-api/bookmarks-add",
2145
+ {
2146
+ method: "POST",
2147
+ headers: {
2148
+ "Content-Type": "application/json"
2149
+ },
2150
+ body: JSON.stringify({
2151
+ author,
2152
+ permlink,
2153
+ code: getAccessToken(username)
2154
+ })
2155
+ }
2156
+ );
2157
+ return response.json();
2158
+ },
2159
+ onSuccess: () => {
2160
+ onSuccess();
2161
+ getQueryClient().invalidateQueries({
2162
+ queryKey: ["accounts", "bookmarks", username]
2163
+ });
2164
+ },
2165
+ onError
2166
+ });
2167
+ }
2168
+ function useBookmarkDelete(username, onSuccess, onError) {
2169
+ return reactQuery.useMutation({
2170
+ mutationKey: ["accounts", "bookmarks", "delete", username],
2171
+ mutationFn: async (bookmarkId) => {
2172
+ if (!username) {
2173
+ throw new Error("[SDK][Account][Bookmarks] \u2013 no active user");
2174
+ }
2175
+ const fetchApi = getBoundFetch();
2176
+ const response = await fetchApi(
2177
+ CONFIG.privateApiHost + "/private-api/bookmarks-delete",
2178
+ {
2179
+ method: "POST",
2180
+ headers: {
2181
+ "Content-Type": "application/json"
2182
+ },
2183
+ body: JSON.stringify({
2184
+ id: bookmarkId,
2185
+ code: getAccessToken(username)
2186
+ })
2187
+ }
2188
+ );
2189
+ return response.json();
2190
+ },
2191
+ onSuccess: () => {
2192
+ onSuccess();
2193
+ getQueryClient().invalidateQueries({
2194
+ queryKey: ["accounts", "bookmarks", username]
2195
+ });
2196
+ },
2197
+ onError
2198
+ });
2199
+ }
2200
+ function useAccountFavouriteAdd(username, onSuccess, onError) {
2201
+ return reactQuery.useMutation({
2202
+ mutationKey: ["accounts", "favourites", "add", username],
2203
+ mutationFn: async (account) => {
2204
+ if (!username) {
2205
+ throw new Error("[SDK][Account][Bookmarks] \u2013 no active user");
2206
+ }
2207
+ const fetchApi = getBoundFetch();
2208
+ const response = await fetchApi(
2209
+ CONFIG.privateApiHost + "/private-api/favorites-add",
2210
+ {
2211
+ method: "POST",
2212
+ headers: {
2213
+ "Content-Type": "application/json"
2214
+ },
2215
+ body: JSON.stringify({
2216
+ account,
2217
+ code: getAccessToken(username)
2218
+ })
2219
+ }
2220
+ );
2221
+ return response.json();
2222
+ },
2223
+ onSuccess: () => {
2224
+ onSuccess();
2225
+ getQueryClient().invalidateQueries({
2226
+ queryKey: ["accounts", "favourites", username]
2227
+ });
2228
+ },
2229
+ onError
2230
+ });
2231
+ }
2232
+ function useAccountFavouriteDelete(username, onSuccess, onError) {
2233
+ return reactQuery.useMutation({
2234
+ mutationKey: ["accounts", "favourites", "add", username],
2235
+ mutationFn: async (account) => {
2236
+ if (!username) {
2237
+ throw new Error("[SDK][Account][Bookmarks] \u2013 no active user");
2238
+ }
2239
+ const fetchApi = getBoundFetch();
2240
+ const response = await fetchApi(
2241
+ CONFIG.privateApiHost + "/private-api/favorites-delete",
2242
+ {
2243
+ method: "POST",
2244
+ headers: {
2245
+ "Content-Type": "application/json"
2246
+ },
2247
+ body: JSON.stringify({
2248
+ account,
2249
+ code: getAccessToken(username)
2250
+ })
2251
+ }
2252
+ );
2253
+ return response.json();
2254
+ },
2255
+ onSuccess: () => {
2256
+ onSuccess();
2257
+ getQueryClient().invalidateQueries({
2258
+ queryKey: ["accounts", "favourites", username]
2259
+ });
2260
+ },
2261
+ onError
2262
+ });
2263
+ }
2264
+ function dedupeAndSortKeyAuths(existing, additions) {
2265
+ const merged = /* @__PURE__ */ new Map();
2266
+ existing.forEach(([key, weight]) => {
2267
+ merged.set(key.toString(), weight);
2268
+ });
2269
+ additions.forEach(([key, weight]) => {
2270
+ merged.set(key.toString(), weight);
2271
+ });
2272
+ return Array.from(merged.entries()).sort(([keyA], [keyB]) => keyA.localeCompare(keyB)).map(([key, weight]) => [key, weight]);
2273
+ }
2274
+ function useAccountUpdateKeyAuths(username, options) {
2275
+ const { data: accountData } = reactQuery.useQuery(getAccountFullQueryOptions(username));
2276
+ return reactQuery.useMutation({
2277
+ mutationKey: ["accounts", "keys-update", username],
2278
+ mutationFn: async ({ keys, keepCurrent = false, currentKey }) => {
2279
+ if (!accountData) {
2280
+ throw new Error(
2281
+ "[SDK][Update password] \u2013 cannot update keys for anon user"
2282
+ );
2283
+ }
2284
+ const prepareAuth = (keyName) => {
2285
+ const auth = R4__namespace.clone(accountData[keyName]);
2286
+ auth.key_auths = dedupeAndSortKeyAuths(
2287
+ keepCurrent ? auth.key_auths : [],
2288
+ keys.map(
2289
+ (values, i) => [values[keyName].createPublic().toString(), i + 1]
2290
+ )
2291
+ );
2292
+ return auth;
2293
+ };
2294
+ return CONFIG.hiveClient.broadcast.updateAccount(
2295
+ {
2296
+ account: username,
2297
+ json_metadata: accountData.json_metadata,
2298
+ owner: prepareAuth("owner"),
2299
+ active: prepareAuth("active"),
2300
+ posting: prepareAuth("posting"),
2301
+ memo_key: keepCurrent ? accountData.memo_key : keys[0].memo_key.createPublic().toString()
2302
+ },
2303
+ currentKey
2304
+ );
2305
+ },
2306
+ ...options
2307
+ });
2308
+ }
2309
+ function useAccountUpdatePassword(username, options) {
2310
+ const { data: accountData } = reactQuery.useQuery(getAccountFullQueryOptions(username));
2311
+ const { mutateAsync: updateKeys } = useAccountUpdateKeyAuths(username);
2312
+ return reactQuery.useMutation({
2313
+ mutationKey: ["accounts", "password-update", username],
1024
2314
  mutationFn: async ({
1025
2315
  newPassword,
1026
2316
  currentPassword,
@@ -1028,751 +2318,1598 @@ function useAccountUpdatePassword(username, options) {
1028
2318
  }) => {
1029
2319
  if (!accountData) {
1030
2320
  throw new Error(
1031
- "[SDK][Update password] \u2013 cannot update password for anon user"
2321
+ "[SDK][Update password] \u2013 cannot update password for anon user"
2322
+ );
2323
+ }
2324
+ const currentKey = dhive.PrivateKey.fromLogin(
2325
+ username,
2326
+ currentPassword,
2327
+ "owner"
2328
+ );
2329
+ return updateKeys({
2330
+ currentKey,
2331
+ keepCurrent,
2332
+ keys: [
2333
+ {
2334
+ owner: dhive.PrivateKey.fromLogin(username, newPassword, "owner"),
2335
+ active: dhive.PrivateKey.fromLogin(username, newPassword, "active"),
2336
+ posting: dhive.PrivateKey.fromLogin(username, newPassword, "posting"),
2337
+ memo_key: dhive.PrivateKey.fromLogin(username, newPassword, "memo")
2338
+ }
2339
+ ]
2340
+ });
2341
+ },
2342
+ ...options
2343
+ });
2344
+ }
2345
+ function useAccountRevokePosting(username, options) {
2346
+ const queryClient = reactQuery.useQueryClient();
2347
+ const { data } = reactQuery.useQuery(getAccountFullQueryOptions(username));
2348
+ return reactQuery.useMutation({
2349
+ mutationKey: ["accounts", "revoke-posting", data?.name],
2350
+ mutationFn: async ({ accountName, type, key }) => {
2351
+ if (!data) {
2352
+ throw new Error(
2353
+ "[SDK][Accounts] \u2013\xA0cannot revoke posting for anonymous user"
2354
+ );
2355
+ }
2356
+ const posting = R4__namespace.pipe(
2357
+ {},
2358
+ R4__namespace.mergeDeep(data.posting)
2359
+ );
2360
+ posting.account_auths = posting.account_auths.filter(
2361
+ ([account]) => account !== accountName
2362
+ );
2363
+ const operationBody = {
2364
+ account: data.name,
2365
+ posting,
2366
+ memo_key: data.memo_key,
2367
+ json_metadata: data.json_metadata
2368
+ };
2369
+ if (type === "key" && key) {
2370
+ return CONFIG.hiveClient.broadcast.updateAccount(operationBody, key);
2371
+ } else if (type === "keychain") {
2372
+ return keychain_exports.broadcast(
2373
+ data.name,
2374
+ [["account_update", operationBody]],
2375
+ "Active"
2376
+ );
2377
+ } else {
2378
+ const params = {
2379
+ callback: `https://ecency.com/@${data.name}/permissions`
2380
+ };
2381
+ return hs__default.default.sendOperation(
2382
+ ["account_update", operationBody],
2383
+ params,
2384
+ () => {
2385
+ }
2386
+ );
2387
+ }
2388
+ },
2389
+ onError: options.onError,
2390
+ onSuccess: (resp, payload, ctx) => {
2391
+ options.onSuccess?.(resp, payload, ctx);
2392
+ queryClient.setQueryData(
2393
+ getAccountFullQueryOptions(username).queryKey,
2394
+ (data2) => ({
2395
+ ...data2,
2396
+ posting: {
2397
+ ...data2?.posting,
2398
+ account_auths: data2?.posting?.account_auths?.filter(
2399
+ ([account]) => account !== payload.accountName
2400
+ ) ?? []
2401
+ }
2402
+ })
2403
+ );
2404
+ }
2405
+ });
2406
+ }
2407
+ function useAccountUpdateRecovery(username, options) {
2408
+ const { data } = reactQuery.useQuery(getAccountFullQueryOptions(username));
2409
+ return reactQuery.useMutation({
2410
+ mutationKey: ["accounts", "recovery", data?.name],
2411
+ mutationFn: async ({ accountName, type, key, email }) => {
2412
+ if (!data) {
2413
+ throw new Error(
2414
+ "[SDK][Accounts] \u2013\xA0cannot change recovery for anonymous user"
2415
+ );
2416
+ }
2417
+ const operationBody = {
2418
+ account_to_recover: data.name,
2419
+ new_recovery_account: accountName,
2420
+ extensions: []
2421
+ };
2422
+ if (type === "ecency") {
2423
+ const fetchApi = getBoundFetch();
2424
+ return fetchApi(CONFIG.privateApiHost + "/private-api/recoveries-add", {
2425
+ method: "POST",
2426
+ body: JSON.stringify({
2427
+ code: getAccessToken(data.name),
2428
+ email,
2429
+ publicKeys: [
2430
+ ...data.owner.key_auths,
2431
+ ...data.active.key_auths,
2432
+ ...data.posting.key_auths,
2433
+ data.memo_key
2434
+ ]
2435
+ })
2436
+ });
2437
+ } else if (type === "key" && key) {
2438
+ return CONFIG.hiveClient.broadcast.sendOperations(
2439
+ [["change_recovery_account", operationBody]],
2440
+ key
2441
+ );
2442
+ } else if (type === "keychain") {
2443
+ return keychain_exports.broadcast(
2444
+ data.name,
2445
+ [["change_recovery_account", operationBody]],
2446
+ "Active"
2447
+ );
2448
+ } else {
2449
+ const params = {
2450
+ callback: `https://ecency.com/@${data.name}/permissions`
2451
+ };
2452
+ return hs__default.default.sendOperation(
2453
+ ["change_recovery_account", operationBody],
2454
+ params,
2455
+ () => {
2456
+ }
2457
+ );
2458
+ }
2459
+ },
2460
+ onError: options.onError,
2461
+ onSuccess: options.onSuccess
2462
+ });
2463
+ }
2464
+ function useAccountRevokeKey(username, options) {
2465
+ const { data: accountData } = reactQuery.useQuery(getAccountFullQueryOptions(username));
2466
+ return reactQuery.useMutation({
2467
+ mutationKey: ["accounts", "revoke-key", accountData?.name],
2468
+ mutationFn: async ({ currentKey, revokingKey }) => {
2469
+ if (!accountData) {
2470
+ throw new Error(
2471
+ "[SDK][Update password] \u2013 cannot update keys for anon user"
2472
+ );
2473
+ }
2474
+ const prepareAuth = (keyName) => {
2475
+ const auth = R4__namespace.clone(accountData[keyName]);
2476
+ auth.key_auths = auth.key_auths.filter(
2477
+ ([key]) => key !== revokingKey.toString()
2478
+ );
2479
+ return auth;
2480
+ };
2481
+ return CONFIG.hiveClient.broadcast.updateAccount(
2482
+ {
2483
+ account: accountData.name,
2484
+ json_metadata: accountData.json_metadata,
2485
+ owner: prepareAuth("owner"),
2486
+ active: prepareAuth("active"),
2487
+ posting: prepareAuth("posting"),
2488
+ memo_key: accountData.memo_key
2489
+ },
2490
+ currentKey
2491
+ );
2492
+ },
2493
+ ...options
2494
+ });
2495
+ }
2496
+ function useSignOperationByKey(username) {
2497
+ return reactQuery.useMutation({
2498
+ mutationKey: ["operations", "sign", username],
2499
+ mutationFn: ({
2500
+ operation,
2501
+ keyOrSeed
2502
+ }) => {
2503
+ if (!username) {
2504
+ throw new Error("[Operations][Sign] \u2013 cannot sign op with anon user");
2505
+ }
2506
+ let privateKey;
2507
+ if (keyOrSeed.split(" ").length === 12) {
2508
+ privateKey = dhive.PrivateKey.fromLogin(username, keyOrSeed, "active");
2509
+ } else if (dhive.cryptoUtils.isWif(keyOrSeed)) {
2510
+ privateKey = dhive.PrivateKey.fromString(keyOrSeed);
2511
+ } else {
2512
+ privateKey = dhive.PrivateKey.from(keyOrSeed);
2513
+ }
2514
+ return CONFIG.hiveClient.broadcast.sendOperations(
2515
+ [operation],
2516
+ privateKey
2517
+ );
2518
+ }
2519
+ });
2520
+ }
2521
+ function useSignOperationByKeychain(username, keyType = "Active") {
2522
+ return reactQuery.useMutation({
2523
+ mutationKey: ["operations", "sign-keychain", username],
2524
+ mutationFn: ({ operation }) => {
2525
+ if (!username) {
2526
+ throw new Error(
2527
+ "[SDK][Keychain] \u2013\xA0cannot sign operation with anon user"
1032
2528
  );
1033
2529
  }
1034
- const currentKey = dhive.PrivateKey.fromLogin(
1035
- username,
1036
- currentPassword,
1037
- "owner"
2530
+ return keychain_exports.broadcast(username, [operation], keyType);
2531
+ }
2532
+ });
2533
+ }
2534
+ function useSignOperationByHivesigner(callbackUri = "/") {
2535
+ return reactQuery.useMutation({
2536
+ mutationKey: ["operations", "sign-hivesigner", callbackUri],
2537
+ mutationFn: async ({ operation }) => {
2538
+ return hs__default.default.sendOperation(operation, { callback: callbackUri }, () => {
2539
+ });
2540
+ }
2541
+ });
2542
+ }
2543
+ function getChainPropertiesQueryOptions() {
2544
+ return reactQuery.queryOptions({
2545
+ queryKey: ["operations", "chain-properties"],
2546
+ queryFn: async () => {
2547
+ return await CONFIG.hiveClient.database.getChainProperties();
2548
+ }
2549
+ });
2550
+ }
2551
+ function useAddFragment(username) {
2552
+ return reactQuery.useMutation({
2553
+ mutationKey: ["posts", "add-fragment", username],
2554
+ mutationFn: async ({ title, body }) => {
2555
+ const fetchApi = getBoundFetch();
2556
+ const response = await fetchApi(
2557
+ CONFIG.privateApiHost + "/private-api/fragments-add",
2558
+ {
2559
+ method: "POST",
2560
+ body: JSON.stringify({
2561
+ code: getAccessToken(username),
2562
+ title,
2563
+ body
2564
+ }),
2565
+ headers: {
2566
+ "Content-Type": "application/json"
2567
+ }
2568
+ }
1038
2569
  );
1039
- return updateKeys({
1040
- currentKey,
1041
- keepCurrent,
1042
- keys: [
1043
- {
1044
- owner: dhive.PrivateKey.fromLogin(username, newPassword, "owner"),
1045
- active: dhive.PrivateKey.fromLogin(username, newPassword, "active"),
1046
- posting: dhive.PrivateKey.fromLogin(username, newPassword, "posting"),
1047
- memo_key: dhive.PrivateKey.fromLogin(username, newPassword, "memo")
2570
+ return response.json();
2571
+ },
2572
+ onSuccess(response) {
2573
+ getQueryClient().setQueryData(
2574
+ getFragmentsQueryOptions(username).queryKey,
2575
+ (data) => [response, ...data ?? []]
2576
+ );
2577
+ }
2578
+ });
2579
+ }
2580
+ function useEditFragment(username, fragmentId) {
2581
+ return reactQuery.useMutation({
2582
+ mutationKey: ["posts", "edit-fragment", username, fragmentId],
2583
+ mutationFn: async ({ title, body }) => {
2584
+ const fetchApi = getBoundFetch();
2585
+ const response = await fetchApi(
2586
+ CONFIG.privateApiHost + "/private-api/fragments-update",
2587
+ {
2588
+ method: "POST",
2589
+ body: JSON.stringify({
2590
+ code: getAccessToken(username),
2591
+ id: fragmentId,
2592
+ title,
2593
+ body
2594
+ }),
2595
+ headers: {
2596
+ "Content-Type": "application/json"
1048
2597
  }
1049
- ]
2598
+ }
2599
+ );
2600
+ return response.json();
2601
+ },
2602
+ onSuccess(response) {
2603
+ getQueryClient().setQueryData(
2604
+ getFragmentsQueryOptions(username).queryKey,
2605
+ (data) => {
2606
+ if (!data) {
2607
+ return [];
2608
+ }
2609
+ const index = data.findIndex(({ id }) => id === fragmentId);
2610
+ if (index >= 0) {
2611
+ data[index] = response;
2612
+ }
2613
+ return [...data];
2614
+ }
2615
+ );
2616
+ }
2617
+ });
2618
+ }
2619
+ function useRemoveFragment(username, fragmentId) {
2620
+ return reactQuery.useMutation({
2621
+ mutationKey: ["posts", "remove-fragment", username],
2622
+ mutationFn: async () => {
2623
+ const fetchApi = getBoundFetch();
2624
+ return fetchApi(CONFIG.privateApiHost + "/private-api/fragments-delete", {
2625
+ method: "POST",
2626
+ body: JSON.stringify({
2627
+ code: getAccessToken(username),
2628
+ id: fragmentId
2629
+ }),
2630
+ headers: {
2631
+ "Content-Type": "application/json"
2632
+ }
1050
2633
  });
1051
2634
  },
1052
- ...options
2635
+ onSuccess() {
2636
+ getQueryClient().setQueryData(
2637
+ getFragmentsQueryOptions(username).queryKey,
2638
+ (data) => [...data ?? []].filter(({ id }) => id !== fragmentId)
2639
+ );
2640
+ }
2641
+ });
2642
+ }
2643
+
2644
+ // src/modules/analytics/mutations/index.ts
2645
+ var mutations_exports = {};
2646
+ __export(mutations_exports, {
2647
+ useRecordActivity: () => useRecordActivity
2648
+ });
2649
+ function useRecordActivity(username, activityType) {
2650
+ return reactQuery.useMutation({
2651
+ mutationKey: ["analytics", activityType],
2652
+ mutationFn: async () => {
2653
+ if (!activityType) {
2654
+ throw new Error("[SDK][Analytics] \u2013 no activity type provided");
2655
+ }
2656
+ const fetchApi = getBoundFetch();
2657
+ await fetchApi(CONFIG.plausibleHost + "/api/event", {
2658
+ method: "POST",
2659
+ headers: {
2660
+ "Content-Type": "application/json"
2661
+ },
2662
+ body: JSON.stringify({
2663
+ name: activityType,
2664
+ url: window.location.href,
2665
+ domain: window.location.host,
2666
+ props: {
2667
+ username
2668
+ }
2669
+ })
2670
+ });
2671
+ }
2672
+ });
2673
+ }
2674
+ function getDiscoverLeaderboardQueryOptions(duration) {
2675
+ return reactQuery.queryOptions({
2676
+ queryKey: ["analytics", "discover-leaderboard", duration],
2677
+ queryFn: async ({ signal }) => {
2678
+ const response = await fetch(
2679
+ CONFIG.privateApiHost + `/private-api/leaderboard/${duration}`,
2680
+ { signal }
2681
+ );
2682
+ if (!response.ok) {
2683
+ throw new Error(`Failed to fetch leaderboard: ${response.status}`);
2684
+ }
2685
+ return response.json();
2686
+ }
2687
+ });
2688
+ }
2689
+ function getDiscoverCurationQueryOptions(duration) {
2690
+ return reactQuery.queryOptions({
2691
+ queryKey: ["analytics", "discover-curation", duration],
2692
+ queryFn: async ({ signal }) => {
2693
+ const response = await fetch(
2694
+ CONFIG.privateApiHost + `/private-api/curation/${duration}`,
2695
+ { signal }
2696
+ );
2697
+ if (!response.ok) {
2698
+ throw new Error(`Failed to fetch curation data: ${response.status}`);
2699
+ }
2700
+ const data = await response.json();
2701
+ const accounts = data.map((item) => item.account);
2702
+ const accountsResponse = await CONFIG.hiveClient.database.getAccounts(accounts);
2703
+ for (let index = 0; index < accountsResponse.length; index++) {
2704
+ const element = accountsResponse[index];
2705
+ const curator = data[index];
2706
+ const vestingShares = typeof element.vesting_shares === "string" ? element.vesting_shares : element.vesting_shares.toString();
2707
+ const receivedVestingShares = typeof element.received_vesting_shares === "string" ? element.received_vesting_shares : element.received_vesting_shares.toString();
2708
+ const delegatedVestingShares = typeof element.delegated_vesting_shares === "string" ? element.delegated_vesting_shares : element.delegated_vesting_shares.toString();
2709
+ const vestingWithdrawRate = typeof element.vesting_withdraw_rate === "string" ? element.vesting_withdraw_rate : element.vesting_withdraw_rate.toString();
2710
+ const effectiveVest = parseFloat(vestingShares) + parseFloat(receivedVestingShares) - parseFloat(delegatedVestingShares) - parseFloat(vestingWithdrawRate);
2711
+ curator.efficiency = curator.vests / effectiveVest;
2712
+ }
2713
+ data.sort((a, b) => b.efficiency - a.efficiency);
2714
+ return data;
2715
+ }
2716
+ });
2717
+ }
2718
+ function getPageStatsQueryOptions(url, dimensions = [], metrics = ["visitors", "pageviews", "visit_duration"], dateRange) {
2719
+ return reactQuery.queryOptions({
2720
+ queryKey: ["analytics", "page-stats", url, dimensions, metrics, dateRange],
2721
+ queryFn: async ({ signal }) => {
2722
+ const response = await fetch(CONFIG.privateApiHost + "/api/stats", {
2723
+ method: "POST",
2724
+ headers: {
2725
+ "Content-Type": "application/json"
2726
+ },
2727
+ body: JSON.stringify({
2728
+ metrics,
2729
+ url: encodeURIComponent(url),
2730
+ dimensions,
2731
+ date_range: dateRange
2732
+ }),
2733
+ signal
2734
+ });
2735
+ if (!response.ok) {
2736
+ throw new Error(`Failed to fetch page stats: ${response.status}`);
2737
+ }
2738
+ return response.json();
2739
+ },
2740
+ enabled: !!url
2741
+ });
2742
+ }
2743
+
2744
+ // src/modules/integrations/3speak/queries/index.ts
2745
+ var queries_exports2 = {};
2746
+ __export(queries_exports2, {
2747
+ getAccountTokenQueryOptions: () => getAccountTokenQueryOptions,
2748
+ getAccountVideosQueryOptions: () => getAccountVideosQueryOptions
2749
+ });
2750
+
2751
+ // src/modules/integrations/hivesigner/queries/index.ts
2752
+ var queries_exports = {};
2753
+ __export(queries_exports, {
2754
+ getDecodeMemoQueryOptions: () => getDecodeMemoQueryOptions
2755
+ });
2756
+ function getDecodeMemoQueryOptions(username, memo) {
2757
+ return reactQuery.queryOptions({
2758
+ queryKey: ["integrations", "hivesigner", "decode-memo", username],
2759
+ queryFn: async () => {
2760
+ const accessToken = getAccessToken(username);
2761
+ if (accessToken) {
2762
+ const hsClient = new hs__default.default.Client({
2763
+ accessToken
2764
+ });
2765
+ return hsClient.decode(memo);
2766
+ }
2767
+ }
2768
+ });
2769
+ }
2770
+
2771
+ // src/modules/integrations/hivesigner/index.ts
2772
+ var HiveSignerIntegration = {
2773
+ queries: queries_exports
2774
+ };
2775
+
2776
+ // src/modules/integrations/3speak/queries/get-account-token-query-options.ts
2777
+ function getAccountTokenQueryOptions(username) {
2778
+ return reactQuery.queryOptions({
2779
+ queryKey: ["integrations", "3speak", "authenticate", username],
2780
+ enabled: !!username,
2781
+ queryFn: async () => {
2782
+ if (!username) {
2783
+ throw new Error("[SDK][Integrations][3Speak] \u2013\xA0anon user");
2784
+ }
2785
+ const fetchApi = getBoundFetch();
2786
+ const response = await fetchApi(
2787
+ `https://studio.3speak.tv/mobile/login?username=${username}&hivesigner=true`,
2788
+ {
2789
+ headers: {
2790
+ "Content-Type": "application/json"
2791
+ }
2792
+ }
2793
+ );
2794
+ const memoQueryOptions = HiveSignerIntegration.queries.getDecodeMemoQueryOptions(
2795
+ username,
2796
+ (await response.json()).memo
2797
+ );
2798
+ await getQueryClient().prefetchQuery(memoQueryOptions);
2799
+ const { memoDecoded } = getQueryClient().getQueryData(
2800
+ memoQueryOptions.queryKey
2801
+ );
2802
+ return memoDecoded.replace("#", "");
2803
+ }
1053
2804
  });
1054
2805
  }
1055
- function useAccountRevokePosting(username, options) {
1056
- const queryClient = reactQuery.useQueryClient();
1057
- const { data } = reactQuery.useQuery(getAccountFullQueryOptions(username));
1058
- return reactQuery.useMutation({
1059
- mutationKey: ["accounts", "revoke-posting", data?.name],
1060
- mutationFn: async ({ accountName, type, key }) => {
1061
- if (!data) {
1062
- throw new Error(
1063
- "[SDK][Accounts] \u2013\xA0cannot revoke posting for anonymous user"
1064
- );
1065
- }
1066
- const posting = R4__namespace.pipe(
1067
- {},
1068
- R4__namespace.mergeDeep(data.posting)
2806
+ function getAccountVideosQueryOptions(username) {
2807
+ return reactQuery.queryOptions({
2808
+ queryKey: ["integrations", "3speak", "videos", username],
2809
+ enabled: !!username,
2810
+ queryFn: async () => {
2811
+ await getQueryClient().prefetchQuery(
2812
+ getAccountTokenQueryOptions(username)
1069
2813
  );
1070
- posting.account_auths = posting.account_auths.filter(
1071
- ([account]) => account !== accountName
2814
+ const token = getQueryClient().getQueryData(
2815
+ getAccountTokenQueryOptions(username).queryKey
1072
2816
  );
1073
- const operationBody = {
1074
- account: data.name,
1075
- posting,
1076
- memo_key: data.memo_key,
1077
- json_metadata: data.json_metadata
1078
- };
1079
- if (type === "key" && key) {
1080
- return CONFIG.hiveClient.broadcast.updateAccount(operationBody, key);
1081
- } else if (type === "keychain") {
1082
- return keychain_exports.broadcast(
1083
- data.name,
1084
- [["account_update", operationBody]],
1085
- "Active"
1086
- );
1087
- } else {
1088
- const params = {
1089
- callback: `https://ecency.com/@${data.name}/permissions`
1090
- };
1091
- return hs__default.default.sendOperation(
1092
- ["account_update", operationBody],
1093
- params,
1094
- () => {
1095
- }
1096
- );
1097
- }
1098
- },
1099
- onError: options.onError,
1100
- onSuccess: (resp, payload, ctx) => {
1101
- options.onSuccess?.(resp, payload, ctx);
1102
- queryClient.setQueryData(
1103
- getAccountFullQueryOptions(username).queryKey,
1104
- (data2) => ({
1105
- ...data2,
1106
- posting: {
1107
- ...data2?.posting,
1108
- account_auths: data2?.posting?.account_auths?.filter(
1109
- ([account]) => account !== payload.accountName
1110
- ) ?? []
2817
+ const fetchApi = getBoundFetch();
2818
+ const response = await fetchApi(
2819
+ `https://studio.3speak.tv/mobile/api/my-videos`,
2820
+ {
2821
+ headers: {
2822
+ "Content-Type": "application/json",
2823
+ Authorization: `Bearer ${token}`
1111
2824
  }
1112
- })
2825
+ }
1113
2826
  );
2827
+ return await response.json();
1114
2828
  }
1115
2829
  });
1116
2830
  }
1117
- function useAccountUpdateRecovery(username, options) {
1118
- const { data } = reactQuery.useQuery(getAccountFullQueryOptions(username));
1119
- return reactQuery.useMutation({
1120
- mutationKey: ["accounts", "recovery", data?.name],
1121
- mutationFn: async ({ accountName, type, key, email }) => {
1122
- if (!data) {
1123
- throw new Error(
1124
- "[SDK][Accounts] \u2013\xA0cannot change recovery for anonymous user"
1125
- );
1126
- }
1127
- const operationBody = {
1128
- account_to_recover: data.name,
1129
- new_recovery_account: accountName,
1130
- extensions: []
1131
- };
1132
- if (type === "ecency") {
2831
+
2832
+ // src/modules/integrations/3speak/index.ts
2833
+ var ThreeSpeakIntegration = {
2834
+ queries: queries_exports2
2835
+ };
2836
+ function getHivePoshLinksQueryOptions(username) {
2837
+ return reactQuery.queryOptions({
2838
+ queryKey: ["integrations", "hiveposh", "links", username],
2839
+ retry: false,
2840
+ // Don't retry on user not found errors
2841
+ queryFn: async () => {
2842
+ try {
1133
2843
  const fetchApi = getBoundFetch();
1134
- return fetchApi(CONFIG.privateApiHost + "/private-api/recoveries-add", {
1135
- method: "POST",
1136
- body: JSON.stringify({
1137
- code: getAccessToken(data.name),
1138
- email,
1139
- publicKeys: [
1140
- ...data.owner.key_auths,
1141
- ...data.active.key_auths,
1142
- ...data.posting.key_auths,
1143
- data.memo_key
1144
- ]
1145
- })
1146
- });
1147
- } else if (type === "key" && key) {
1148
- return CONFIG.hiveClient.broadcast.sendOperations(
1149
- [["change_recovery_account", operationBody]],
1150
- key
1151
- );
1152
- } else if (type === "keychain") {
1153
- return keychain_exports.broadcast(
1154
- data.name,
1155
- [["change_recovery_account", operationBody]],
1156
- "Active"
1157
- );
1158
- } else {
1159
- const params = {
1160
- callback: `https://ecency.com/@${data.name}/permissions`
1161
- };
1162
- return hs__default.default.sendOperation(
1163
- ["change_recovery_account", operationBody],
1164
- params,
1165
- () => {
2844
+ const response = await fetchApi(
2845
+ `https://hiveposh.com/api/v0/linked-accounts/${username}`,
2846
+ {
2847
+ headers: {
2848
+ "Content-Type": "application/json"
2849
+ }
1166
2850
  }
1167
2851
  );
2852
+ if (response.status === 400) {
2853
+ const errorData = await response.json().catch(() => ({}));
2854
+ if (errorData?.message === "User Not Connected") {
2855
+ return null;
2856
+ }
2857
+ }
2858
+ if (!response.ok) {
2859
+ return null;
2860
+ }
2861
+ const data = await response.json();
2862
+ return {
2863
+ twitter: {
2864
+ username: data.twitter_username,
2865
+ profile: data.twitter_profile
2866
+ },
2867
+ reddit: {
2868
+ username: data.reddit_username,
2869
+ profile: data.reddit_profile
2870
+ }
2871
+ };
2872
+ } catch (err) {
2873
+ return null;
1168
2874
  }
2875
+ }
2876
+ });
2877
+ }
2878
+ function getStatsQueryOptions({
2879
+ url,
2880
+ dimensions = [],
2881
+ metrics = ["visitors", "pageviews", "visit_duration"],
2882
+ enabled = true
2883
+ }) {
2884
+ return reactQuery.queryOptions({
2885
+ queryKey: ["integrations", "plausible", url, dimensions, metrics],
2886
+ queryFn: async () => {
2887
+ const fetchApi = getBoundFetch();
2888
+ const response = await fetchApi(`https://ecency.com/api/stats`, {
2889
+ method: "POST",
2890
+ body: JSON.stringify({
2891
+ metrics,
2892
+ url: encodeURIComponent(url),
2893
+ dimensions
2894
+ }),
2895
+ headers: {
2896
+ "Content-Type": "application/json"
2897
+ }
2898
+ });
2899
+ return await response.json();
1169
2900
  },
1170
- onError: options.onError,
1171
- onSuccess: options.onSuccess
2901
+ enabled: !!url && enabled
1172
2902
  });
1173
2903
  }
1174
- function useAccountRevokeKey(username, options) {
1175
- const { data: accountData } = reactQuery.useQuery(getAccountFullQueryOptions(username));
1176
- return reactQuery.useMutation({
1177
- mutationKey: ["accounts", "revoke-key", accountData?.name],
1178
- mutationFn: async ({ currentKey, revokingKey }) => {
1179
- if (!accountData) {
1180
- throw new Error(
1181
- "[SDK][Update password] \u2013 cannot update keys for anon user"
1182
- );
1183
- }
1184
- const prepareAuth = (keyName) => {
1185
- const auth = R4__namespace.clone(accountData[keyName]);
1186
- auth.key_auths = auth.key_auths.filter(
1187
- ([key]) => key !== revokingKey.toString()
1188
- );
1189
- return auth;
1190
- };
1191
- return CONFIG.hiveClient.broadcast.updateAccount(
1192
- {
1193
- account: accountData.name,
1194
- json_metadata: accountData.json_metadata,
1195
- owner: prepareAuth("owner"),
1196
- active: prepareAuth("active"),
1197
- posting: prepareAuth("posting"),
1198
- memo_key: accountData.memo_key
1199
- },
1200
- currentKey
2904
+ function getRcStatsQueryOptions() {
2905
+ return reactQuery.queryOptions({
2906
+ queryKey: ["resource-credits", "stats"],
2907
+ queryFn: async () => {
2908
+ const response = await CONFIG.hiveClient.call(
2909
+ "rc_api",
2910
+ "get_rc_stats",
2911
+ {}
1201
2912
  );
2913
+ return response.rc_stats;
2914
+ }
2915
+ });
2916
+ }
2917
+ function getAccountRcQueryOptions(username) {
2918
+ return reactQuery.queryOptions({
2919
+ queryKey: ["resource-credits", "account", username],
2920
+ queryFn: async () => {
2921
+ const rcClient = new dhive.RCAPI(CONFIG.hiveClient);
2922
+ return rcClient.findRCAccounts([username]);
1202
2923
  },
1203
- ...options
2924
+ enabled: !!username
1204
2925
  });
1205
2926
  }
1206
- function useSignOperationByKey(username) {
1207
- return reactQuery.useMutation({
1208
- mutationKey: ["operations", "sign", username],
1209
- mutationFn: ({
1210
- operation,
1211
- keyOrSeed
1212
- }) => {
2927
+ function getGameStatusCheckQueryOptions(username, gameType) {
2928
+ return reactQuery.queryOptions({
2929
+ queryKey: ["games", "status-check", gameType, username],
2930
+ enabled: !!username,
2931
+ queryFn: async () => {
1213
2932
  if (!username) {
1214
- throw new Error("[Operations][Sign] \u2013 cannot sign op with anon user");
1215
- }
1216
- let privateKey;
1217
- if (keyOrSeed.split(" ").length === 12) {
1218
- privateKey = dhive.PrivateKey.fromLogin(username, keyOrSeed, "active");
1219
- } else if (dhive.cryptoUtils.isWif(keyOrSeed)) {
1220
- privateKey = dhive.PrivateKey.fromString(keyOrSeed);
1221
- } else {
1222
- privateKey = dhive.PrivateKey.from(keyOrSeed);
2933
+ throw new Error("[SDK][Games] \u2013 anon user in status check");
1223
2934
  }
1224
- return CONFIG.hiveClient.broadcast.sendOperations(
1225
- [operation],
1226
- privateKey
2935
+ const fetchApi = getBoundFetch();
2936
+ const response = await fetchApi(
2937
+ CONFIG.privateApiHost + "/private-api/get-game",
2938
+ {
2939
+ method: "POST",
2940
+ body: JSON.stringify({
2941
+ game_type: gameType,
2942
+ code: getAccessToken(username)
2943
+ }),
2944
+ headers: {
2945
+ "Content-Type": "application/json"
2946
+ }
2947
+ }
1227
2948
  );
2949
+ return await response.json();
1228
2950
  }
1229
2951
  });
1230
2952
  }
1231
- function useSignOperationByKeychain(username, keyType = "Active") {
2953
+ function useGameClaim(username, gameType, key) {
2954
+ const { mutateAsync: recordActivity } = useRecordActivity(
2955
+ username,
2956
+ "spin-rolled"
2957
+ );
1232
2958
  return reactQuery.useMutation({
1233
- mutationKey: ["operations", "sign-keychain", username],
1234
- mutationFn: ({ operation }) => {
2959
+ mutationKey: ["games", "post", gameType, username],
2960
+ mutationFn: async () => {
1235
2961
  if (!username) {
1236
- throw new Error(
1237
- "[SDK][Keychain] \u2013\xA0cannot sign operation with anon user"
1238
- );
2962
+ throw new Error("[SDK][Games] \u2013 anon user in game post");
1239
2963
  }
1240
- return keychain_exports.broadcast(username, [operation], keyType);
2964
+ const fetchApi = getBoundFetch();
2965
+ const response = await fetchApi(
2966
+ CONFIG.privateApiHost + "/private-api/post-game",
2967
+ {
2968
+ method: "POST",
2969
+ body: JSON.stringify({
2970
+ game_type: gameType,
2971
+ code: getAccessToken(username),
2972
+ key
2973
+ }),
2974
+ headers: {
2975
+ "Content-Type": "application/json"
2976
+ }
2977
+ }
2978
+ );
2979
+ return await response.json();
2980
+ },
2981
+ onSuccess() {
2982
+ recordActivity();
1241
2983
  }
1242
2984
  });
1243
2985
  }
1244
- function useSignOperationByHivesigner(callbackUri = "/") {
1245
- return reactQuery.useMutation({
1246
- mutationKey: ["operations", "sign-hivesigner", callbackUri],
1247
- mutationFn: async ({ operation }) => {
1248
- return hs__default.default.sendOperation(operation, { callback: callbackUri }, () => {
1249
- });
2986
+ function getCommunitiesQueryOptions(sort, query, limit = 100, observer = void 0, enabled = true) {
2987
+ return reactQuery.queryOptions({
2988
+ queryKey: ["communities", "list", sort, query, limit],
2989
+ enabled,
2990
+ queryFn: async () => {
2991
+ const response = await CONFIG.hiveClient.call(
2992
+ "bridge",
2993
+ "list_communities",
2994
+ {
2995
+ last: "",
2996
+ limit,
2997
+ sort: sort === "hot" ? "rank" : sort,
2998
+ query: query ? query : null,
2999
+ observer
3000
+ }
3001
+ );
3002
+ return response ? sort === "hot" ? response.sort(() => Math.random() - 0.5) : response : [];
1250
3003
  }
1251
3004
  });
1252
3005
  }
1253
- function getChainPropertiesQueryOptions() {
3006
+ function getCommunityContextQueryOptions(username, communityName) {
1254
3007
  return reactQuery.queryOptions({
1255
- queryKey: ["operations", "chain-properties"],
3008
+ queryKey: ["community", "context", username, communityName],
3009
+ enabled: !!username && !!communityName,
1256
3010
  queryFn: async () => {
1257
- return await CONFIG.hiveClient.database.getChainProperties();
3011
+ const response = await CONFIG.hiveClient.call(
3012
+ "bridge",
3013
+ "get_community_context",
3014
+ {
3015
+ account: username,
3016
+ name: communityName
3017
+ }
3018
+ );
3019
+ return {
3020
+ role: response?.role ?? "guest",
3021
+ subscribed: response?.subscribed ?? false
3022
+ };
1258
3023
  }
1259
3024
  });
1260
3025
  }
1261
- function getTrendingTagsQueryOptions(limit = 20) {
3026
+ function getCommunitySubscribersQueryOptions(communityName) {
3027
+ return reactQuery.queryOptions({
3028
+ queryKey: ["communities", "subscribers", communityName],
3029
+ queryFn: async () => {
3030
+ const response = await CONFIG.hiveClient.call("bridge", "list_subscribers", {
3031
+ community: communityName
3032
+ });
3033
+ return response ?? [];
3034
+ },
3035
+ staleTime: 6e4
3036
+ });
3037
+ }
3038
+ function getAccountNotificationsInfiniteQueryOptions(account, limit) {
1262
3039
  return reactQuery.infiniteQueryOptions({
1263
- queryKey: ["posts", "trending-tags"],
1264
- queryFn: async ({ pageParam: { afterTag } }) => CONFIG.hiveClient.database.call("get_trending_tags", [afterTag, limit]).then(
1265
- (tags) => tags.filter((x) => x.name !== "").filter((x) => !x.name.startsWith("hive-")).map((x) => x.name)
1266
- ),
1267
- initialPageParam: { afterTag: "" },
1268
- getNextPageParam: (lastPage) => ({
1269
- afterTag: lastPage?.[lastPage?.length - 1]
1270
- }),
1271
- staleTime: Infinity,
1272
- refetchOnMount: true
3040
+ queryKey: ["communities", "account-notifications", account, limit],
3041
+ initialPageParam: null,
3042
+ queryFn: async ({ pageParam }) => {
3043
+ try {
3044
+ const response = await CONFIG.hiveClient.call("bridge", "account_notifications", {
3045
+ account,
3046
+ limit,
3047
+ last_id: pageParam ?? void 0
3048
+ });
3049
+ return response ?? [];
3050
+ } catch {
3051
+ return [];
3052
+ }
3053
+ },
3054
+ getNextPageParam: (lastPage) => lastPage?.length > 0 ? lastPage[lastPage.length - 1].id : null
1273
3055
  });
1274
3056
  }
1275
- function getFragmentsQueryOptions(username) {
3057
+ function getRewardedCommunitiesQueryOptions() {
1276
3058
  return reactQuery.queryOptions({
1277
- queryKey: ["posts", "fragments", username],
3059
+ queryKey: ["communities", "rewarded"],
1278
3060
  queryFn: async () => {
1279
- const fetchApi = getBoundFetch();
1280
- const response = await fetchApi(
1281
- CONFIG.privateApiHost + "/private-api/fragments",
3061
+ const response = await fetch(
3062
+ CONFIG.privateApiHost + "/private-api/rewarded-communities",
1282
3063
  {
1283
- method: "POST",
1284
- body: JSON.stringify({
1285
- code: getAccessToken(username)
1286
- }),
3064
+ method: "GET",
1287
3065
  headers: {
1288
3066
  "Content-Type": "application/json"
1289
3067
  }
1290
3068
  }
1291
3069
  );
3070
+ if (!response.ok) {
3071
+ throw new Error(`Failed to fetch rewarded communities: ${response.status}`);
3072
+ }
1292
3073
  return response.json();
1293
- },
1294
- enabled: !!username
3074
+ }
1295
3075
  });
1296
3076
  }
1297
- function getPromotedPostsQuery(type = "feed") {
1298
- return reactQuery.queryOptions({
1299
- queryKey: ["posts", "promoted", type],
1300
- queryFn: async () => {
1301
- const url = new URL(
1302
- CONFIG.privateApiHost + "/private-api/promoted-entries"
1303
- );
1304
- if (type === "waves") {
1305
- url.searchParams.append("short_content", "1");
1306
- }
1307
- const fetchApi = getBoundFetch();
1308
- const response = await fetchApi(url.toString(), {
1309
- method: "GET",
1310
- headers: {
1311
- "Content-Type": "application/json"
1312
- }
1313
- });
1314
- const data = await response.json();
1315
- return data;
3077
+
3078
+ // src/modules/communities/types/community.ts
3079
+ var ROLES = /* @__PURE__ */ ((ROLES2) => {
3080
+ ROLES2["OWNER"] = "owner";
3081
+ ROLES2["ADMIN"] = "admin";
3082
+ ROLES2["MOD"] = "mod";
3083
+ ROLES2["MEMBER"] = "member";
3084
+ ROLES2["GUEST"] = "guest";
3085
+ ROLES2["MUTED"] = "muted";
3086
+ return ROLES2;
3087
+ })(ROLES || {});
3088
+ var roleMap = {
3089
+ ["owner" /* OWNER */]: [
3090
+ "admin" /* ADMIN */,
3091
+ "mod" /* MOD */,
3092
+ "member" /* MEMBER */,
3093
+ "guest" /* GUEST */,
3094
+ "muted" /* MUTED */
3095
+ ],
3096
+ ["admin" /* ADMIN */]: ["mod" /* MOD */, "member" /* MEMBER */, "guest" /* GUEST */, "muted" /* MUTED */],
3097
+ ["mod" /* MOD */]: ["member" /* MEMBER */, "guest" /* GUEST */, "muted" /* MUTED */]
3098
+ };
3099
+
3100
+ // src/modules/communities/utils/index.ts
3101
+ function getCommunityType(name, type_id) {
3102
+ if (name.startsWith("hive-3") || type_id === 3) return "Council";
3103
+ if (name.startsWith("hive-2") || type_id === 2) return "Journal";
3104
+ return "Topic";
3105
+ }
3106
+ function getCommunityPermissions({
3107
+ communityType,
3108
+ userRole,
3109
+ subscribed
3110
+ }) {
3111
+ const canPost = (() => {
3112
+ if (userRole === "muted" /* MUTED */) return false;
3113
+ if (communityType === "Topic") return true;
3114
+ return ["owner" /* OWNER */, "admin" /* ADMIN */, "mod" /* MOD */, "member" /* MEMBER */].includes(
3115
+ userRole
3116
+ );
3117
+ })();
3118
+ const canComment = (() => {
3119
+ if (userRole === "muted" /* MUTED */) return false;
3120
+ switch (communityType) {
3121
+ case "Topic":
3122
+ return true;
3123
+ case "Journal":
3124
+ return userRole !== "guest" /* GUEST */ || subscribed;
3125
+ case "Council":
3126
+ return canPost;
1316
3127
  }
1317
- });
3128
+ })();
3129
+ const isModerator = ["owner" /* OWNER */, "admin" /* ADMIN */, "mod" /* MOD */].includes(userRole);
3130
+ return {
3131
+ canPost,
3132
+ canComment,
3133
+ isModerator
3134
+ };
1318
3135
  }
1319
- function useAddFragment(username) {
1320
- return reactQuery.useMutation({
1321
- mutationKey: ["posts", "add-fragment", username],
1322
- mutationFn: async ({ title, body }) => {
1323
- const fetchApi = getBoundFetch();
1324
- const response = await fetchApi(
1325
- CONFIG.privateApiHost + "/private-api/fragments-add",
3136
+ function getNotificationsUnreadCountQueryOptions(activeUsername) {
3137
+ return reactQuery.queryOptions({
3138
+ queryKey: ["notifications", "unread", activeUsername],
3139
+ queryFn: async () => {
3140
+ const response = await fetch(
3141
+ `${CONFIG.privateApiHost}/private-api/notifications/unread`,
1326
3142
  {
1327
3143
  method: "POST",
1328
- body: JSON.stringify({
1329
- code: getAccessToken(username),
1330
- title,
1331
- body
1332
- }),
3144
+ body: JSON.stringify({ code: getAccessToken(activeUsername) }),
1333
3145
  headers: {
1334
3146
  "Content-Type": "application/json"
1335
3147
  }
1336
3148
  }
1337
3149
  );
1338
- return response.json();
3150
+ const data = await response.json();
3151
+ return data.count;
1339
3152
  },
1340
- onSuccess(response) {
1341
- getQueryClient().setQueryData(
1342
- getFragmentsQueryOptions(username).queryKey,
1343
- (data) => [response, ...data ?? []]
1344
- );
1345
- }
3153
+ enabled: !!activeUsername,
3154
+ initialData: 0,
3155
+ refetchInterval: 6e4
1346
3156
  });
1347
3157
  }
1348
- function useEditFragment(username, fragmentId) {
1349
- return reactQuery.useMutation({
1350
- mutationKey: ["posts", "edit-fragment", username, fragmentId],
1351
- mutationFn: async ({ title, body }) => {
1352
- const fetchApi = getBoundFetch();
1353
- const response = await fetchApi(
1354
- CONFIG.privateApiHost + "/private-api/fragments-update",
3158
+ function getNotificationsInfiniteQueryOptions(activeUsername, filter = void 0) {
3159
+ return reactQuery.infiniteQueryOptions({
3160
+ queryKey: ["notifications", activeUsername, filter],
3161
+ queryFn: async ({ pageParam }) => {
3162
+ const data = {
3163
+ code: getAccessToken(activeUsername),
3164
+ filter,
3165
+ since: pageParam,
3166
+ user: void 0
3167
+ };
3168
+ const response = await fetch(
3169
+ CONFIG.privateApiHost + "/private-api/notifications",
1355
3170
  {
1356
3171
  method: "POST",
1357
- body: JSON.stringify({
1358
- code: getAccessToken(username),
1359
- id: fragmentId,
1360
- title,
1361
- body
1362
- }),
1363
3172
  headers: {
1364
3173
  "Content-Type": "application/json"
1365
- }
3174
+ },
3175
+ body: JSON.stringify(data)
1366
3176
  }
1367
3177
  );
1368
3178
  return response.json();
1369
3179
  },
1370
- onSuccess(response) {
1371
- getQueryClient().setQueryData(
1372
- getFragmentsQueryOptions(username).queryKey,
1373
- (data) => {
1374
- if (!data) {
1375
- return [];
1376
- }
1377
- const index = data.findIndex(({ id }) => id === fragmentId);
1378
- if (index >= 0) {
1379
- data[index] = response;
3180
+ enabled: !!activeUsername,
3181
+ initialData: { pages: [], pageParams: [] },
3182
+ initialPageParam: "",
3183
+ getNextPageParam: (lastPage) => lastPage?.[lastPage.length - 1]?.id ?? "",
3184
+ refetchOnMount: true
3185
+ });
3186
+ }
3187
+
3188
+ // src/modules/notifications/enums/notification-filter.ts
3189
+ var NotificationFilter = /* @__PURE__ */ ((NotificationFilter2) => {
3190
+ NotificationFilter2["VOTES"] = "rvotes";
3191
+ NotificationFilter2["MENTIONS"] = "mentions";
3192
+ NotificationFilter2["FAVORITES"] = "nfavorites";
3193
+ NotificationFilter2["BOOKMARKS"] = "nbookmarks";
3194
+ NotificationFilter2["FOLLOWS"] = "follows";
3195
+ NotificationFilter2["REPLIES"] = "replies";
3196
+ NotificationFilter2["REBLOGS"] = "reblogs";
3197
+ NotificationFilter2["TRANSFERS"] = "transfers";
3198
+ NotificationFilter2["DELEGATIONS"] = "delegations";
3199
+ return NotificationFilter2;
3200
+ })(NotificationFilter || {});
3201
+
3202
+ // src/modules/notifications/enums/notify-types.ts
3203
+ var NotifyTypes = /* @__PURE__ */ ((NotifyTypes2) => {
3204
+ NotifyTypes2[NotifyTypes2["VOTE"] = 1] = "VOTE";
3205
+ NotifyTypes2[NotifyTypes2["MENTION"] = 2] = "MENTION";
3206
+ NotifyTypes2[NotifyTypes2["FOLLOW"] = 3] = "FOLLOW";
3207
+ NotifyTypes2[NotifyTypes2["COMMENT"] = 4] = "COMMENT";
3208
+ NotifyTypes2[NotifyTypes2["RE_BLOG"] = 5] = "RE_BLOG";
3209
+ NotifyTypes2[NotifyTypes2["TRANSFERS"] = 6] = "TRANSFERS";
3210
+ NotifyTypes2[NotifyTypes2["FAVORITES"] = 13] = "FAVORITES";
3211
+ NotifyTypes2[NotifyTypes2["BOOKMARKS"] = 15] = "BOOKMARKS";
3212
+ NotifyTypes2["ALLOW_NOTIFY"] = "ALLOW_NOTIFY";
3213
+ return NotifyTypes2;
3214
+ })(NotifyTypes || {});
3215
+ var ALL_NOTIFY_TYPES = [
3216
+ 1 /* VOTE */,
3217
+ 2 /* MENTION */,
3218
+ 3 /* FOLLOW */,
3219
+ 4 /* COMMENT */,
3220
+ 5 /* RE_BLOG */,
3221
+ 6 /* TRANSFERS */,
3222
+ 13 /* FAVORITES */,
3223
+ 15 /* BOOKMARKS */
3224
+ ];
3225
+ var NotificationViewType = /* @__PURE__ */ ((NotificationViewType2) => {
3226
+ NotificationViewType2["ALL"] = "All";
3227
+ NotificationViewType2["UNREAD"] = "Unread";
3228
+ NotificationViewType2["READ"] = "Read";
3229
+ return NotificationViewType2;
3230
+ })(NotificationViewType || {});
3231
+
3232
+ // src/modules/notifications/queries/get-notifications-settings-query-options.ts
3233
+ function getNotificationsSettingsQueryOptions(activeUsername) {
3234
+ return reactQuery.queryOptions({
3235
+ queryKey: ["notifications", "settings", activeUsername],
3236
+ queryFn: async () => {
3237
+ let token = activeUsername + "-web";
3238
+ const response = await fetch(
3239
+ CONFIG.privateApiHost + "/private-api/detail-device",
3240
+ {
3241
+ body: JSON.stringify({
3242
+ code: getAccessToken(activeUsername),
3243
+ username: activeUsername,
3244
+ token
3245
+ }),
3246
+ method: "POST",
3247
+ headers: {
3248
+ "Content-Type": "application/json"
1380
3249
  }
1381
- return [...data];
1382
3250
  }
1383
3251
  );
3252
+ if (!response.ok) {
3253
+ throw new Error(`Failed to fetch notification settings: ${response.status}`);
3254
+ }
3255
+ return response.json();
3256
+ },
3257
+ enabled: !!activeUsername,
3258
+ refetchOnMount: false,
3259
+ initialData: () => {
3260
+ const wasMutedPreviously = typeof window !== "undefined" ? localStorage.getItem("notifications") !== "true" : false;
3261
+ return {
3262
+ status: 0,
3263
+ system: "web",
3264
+ allows_notify: 0,
3265
+ notify_types: wasMutedPreviously ? [] : [
3266
+ 4 /* COMMENT */,
3267
+ 3 /* FOLLOW */,
3268
+ 2 /* MENTION */,
3269
+ 13 /* FAVORITES */,
3270
+ 15 /* BOOKMARKS */,
3271
+ 1 /* VOTE */,
3272
+ 5 /* RE_BLOG */,
3273
+ 6 /* TRANSFERS */
3274
+ ]
3275
+ };
1384
3276
  }
1385
3277
  });
1386
3278
  }
1387
- function useRemoveFragment(username, fragmentId) {
1388
- return reactQuery.useMutation({
1389
- mutationKey: ["posts", "remove-fragment", username],
1390
- mutationFn: async () => {
1391
- const fetchApi = getBoundFetch();
1392
- return fetchApi(CONFIG.privateApiHost + "/private-api/fragments-delete", {
1393
- method: "POST",
1394
- body: JSON.stringify({
1395
- code: getAccessToken(username),
1396
- id: fragmentId
1397
- }),
3279
+ function getAnnouncementsQueryOptions() {
3280
+ return reactQuery.queryOptions({
3281
+ queryKey: ["notifications", "announcements"],
3282
+ queryFn: async () => {
3283
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/announcements", {
3284
+ method: "GET",
1398
3285
  headers: {
1399
3286
  "Content-Type": "application/json"
1400
3287
  }
1401
3288
  });
3289
+ if (!response.ok) {
3290
+ throw new Error(`Failed to fetch announcements: ${response.status}`);
3291
+ }
3292
+ const data = await response.json();
3293
+ return data || [];
1402
3294
  },
1403
- onSuccess() {
1404
- getQueryClient().setQueryData(
1405
- getFragmentsQueryOptions(username).queryKey,
1406
- (data) => [...data ?? []].filter(({ id }) => id !== fragmentId)
1407
- );
1408
- }
3295
+ staleTime: 36e5
1409
3296
  });
1410
3297
  }
1411
-
1412
- // src/modules/analytics/mutations/index.ts
1413
- var mutations_exports = {};
1414
- __export(mutations_exports, {
1415
- useRecordActivity: () => useRecordActivity
1416
- });
1417
- function useRecordActivity(username, activityType) {
1418
- return reactQuery.useMutation({
1419
- mutationKey: ["analytics", activityType],
1420
- mutationFn: async () => {
1421
- if (!activityType) {
1422
- throw new Error("[SDK][Analytics] \u2013 no activity type provided");
3298
+ function getProposalQueryOptions(id) {
3299
+ return reactQuery.queryOptions({
3300
+ queryKey: ["proposals", "proposal", id],
3301
+ queryFn: async () => {
3302
+ const r = await CONFIG.hiveClient.call("condenser_api", "find_proposals", [[id]]);
3303
+ const proposal = r[0];
3304
+ if (new Date(proposal.start_date) < /* @__PURE__ */ new Date() && new Date(proposal.end_date) >= /* @__PURE__ */ new Date()) {
3305
+ proposal.status = "active";
3306
+ } else if (new Date(proposal.end_date) < /* @__PURE__ */ new Date()) {
3307
+ proposal.status = "expired";
3308
+ } else {
3309
+ proposal.status = "inactive";
1423
3310
  }
1424
- const fetchApi = getBoundFetch();
1425
- await fetchApi(CONFIG.plausibleHost + "/api/event", {
1426
- method: "POST",
1427
- headers: {
1428
- "Content-Type": "application/json"
1429
- },
1430
- body: JSON.stringify({
1431
- name: activityType,
1432
- url: window.location.href,
1433
- domain: window.location.host,
1434
- props: {
1435
- username
1436
- }
1437
- })
3311
+ return proposal;
3312
+ }
3313
+ });
3314
+ }
3315
+ function getProposalsQueryOptions() {
3316
+ return reactQuery.queryOptions({
3317
+ queryKey: ["proposals", "list"],
3318
+ queryFn: async () => {
3319
+ const response = await CONFIG.hiveClient.call("database_api", "list_proposals", {
3320
+ start: [-1],
3321
+ limit: 500,
3322
+ order: "by_total_votes",
3323
+ order_direction: "descending",
3324
+ status: "all"
1438
3325
  });
3326
+ const proposals = response.proposals;
3327
+ const expired = proposals.filter((x) => x.status === "expired");
3328
+ const others = proposals.filter((x) => x.status !== "expired");
3329
+ return [...others, ...expired];
1439
3330
  }
1440
3331
  });
1441
3332
  }
1442
-
1443
- // src/modules/integrations/3speak/queries/index.ts
1444
- var queries_exports2 = {};
1445
- __export(queries_exports2, {
1446
- getAccountTokenQueryOptions: () => getAccountTokenQueryOptions,
1447
- getAccountVideosQueryOptions: () => getAccountVideosQueryOptions
1448
- });
1449
-
1450
- // src/modules/integrations/hivesigner/queries/index.ts
1451
- var queries_exports = {};
1452
- __export(queries_exports, {
1453
- getDecodeMemoQueryOptions: () => getDecodeMemoQueryOptions
1454
- });
1455
- function getDecodeMemoQueryOptions(username, memo) {
3333
+ function getProposalVotesInfiniteQueryOptions(proposalId, voter, limit) {
3334
+ return reactQuery.infiniteQueryOptions({
3335
+ queryKey: ["proposals", "votes", proposalId, voter, limit],
3336
+ initialPageParam: voter,
3337
+ refetchOnMount: true,
3338
+ staleTime: 0,
3339
+ // Always refetch on mount
3340
+ queryFn: async ({ pageParam }) => {
3341
+ const startParam = pageParam ?? voter;
3342
+ const response = await CONFIG.hiveClient.call("condenser_api", "list_proposal_votes", [
3343
+ [proposalId, startParam],
3344
+ limit,
3345
+ "by_proposal_voter"
3346
+ ]);
3347
+ const list = response.filter((x) => x.proposal?.proposal_id === proposalId).map((x) => ({ id: x.id, voter: x.voter }));
3348
+ const rawAccounts = await CONFIG.hiveClient.database.getAccounts(list.map((l) => l.voter));
3349
+ const accounts = parseAccounts(rawAccounts);
3350
+ const page = list.map((i) => ({
3351
+ ...i,
3352
+ voterAccount: accounts.find((a) => i.voter === a.name)
3353
+ }));
3354
+ return page;
3355
+ },
3356
+ getNextPageParam: (lastPage) => {
3357
+ const last = lastPage?.[lastPage.length - 1];
3358
+ return last?.voter ?? void 0;
3359
+ }
3360
+ });
3361
+ }
3362
+ function getUserProposalVotesQueryOptions(voter) {
1456
3363
  return reactQuery.queryOptions({
1457
- queryKey: ["integrations", "hivesigner", "decode-memo", username],
3364
+ queryKey: ["proposals", "votes", "by-user", voter],
3365
+ enabled: !!voter && voter !== "",
3366
+ staleTime: 60 * 1e3,
3367
+ // Cache for 1 minute
1458
3368
  queryFn: async () => {
1459
- const accessToken = getAccessToken(username);
1460
- if (accessToken) {
1461
- const hsClient = new hs__default.default.Client({
1462
- accessToken
1463
- });
1464
- return hsClient.decode(memo);
3369
+ if (!voter || voter === "") {
3370
+ return [];
1465
3371
  }
3372
+ const response = await CONFIG.hiveClient.call("database_api", "list_proposal_votes", {
3373
+ start: [voter],
3374
+ limit: 1e3,
3375
+ order: "by_voter_proposal",
3376
+ order_direction: "ascending",
3377
+ status: "votable"
3378
+ });
3379
+ const userVotes = (response.proposal_votes || []).filter((vote) => vote.voter === voter);
3380
+ return userVotes;
1466
3381
  }
1467
3382
  });
1468
3383
  }
1469
-
1470
- // src/modules/integrations/hivesigner/index.ts
1471
- var HiveSignerIntegration = {
1472
- queries: queries_exports
1473
- };
1474
-
1475
- // src/modules/integrations/3speak/queries/get-account-token-query-options.ts
1476
- function getAccountTokenQueryOptions(username) {
3384
+ function getVestingDelegationsQueryOptions(username, from, limit = 50) {
1477
3385
  return reactQuery.queryOptions({
1478
- queryKey: ["integrations", "3speak", "authenticate", username],
1479
- enabled: !!username,
1480
- queryFn: async () => {
1481
- if (!username) {
1482
- throw new Error("[SDK][Integrations][3Speak] \u2013\xA0anon user");
3386
+ queryKey: ["wallet", "vesting-delegations", username, from, limit],
3387
+ queryFn: () => CONFIG.hiveClient.database.call("get_vesting_delegations", [
3388
+ username,
3389
+ from,
3390
+ limit
3391
+ ]),
3392
+ enabled: !!username
3393
+ });
3394
+ }
3395
+ function getConversionRequestsQueryOptions(account) {
3396
+ return reactQuery.queryOptions({
3397
+ queryKey: ["wallet", "conversion-requests", account],
3398
+ queryFn: () => CONFIG.hiveClient.database.call("get_conversion_requests", [
3399
+ account
3400
+ ]),
3401
+ select: (data) => data.sort((a, b) => a.requestid - b.requestid)
3402
+ });
3403
+ }
3404
+ function getCollateralizedConversionRequestsQueryOptions(account) {
3405
+ return reactQuery.queryOptions({
3406
+ queryKey: ["wallet", "collateralized-conversion-requests", account],
3407
+ queryFn: () => CONFIG.hiveClient.database.call("get_collateralized_conversion_requests", [
3408
+ account
3409
+ ]),
3410
+ select: (data) => data.sort((a, b) => a.requestid - b.requestid)
3411
+ });
3412
+ }
3413
+ function getSavingsWithdrawFromQueryOptions(account) {
3414
+ return reactQuery.queryOptions({
3415
+ queryKey: ["wallet", "savings-withdraw", account],
3416
+ queryFn: () => CONFIG.hiveClient.database.call("get_savings_withdraw_from", [
3417
+ account
3418
+ ]),
3419
+ select: (data) => data.sort((a, b) => a.request_id - b.request_id)
3420
+ });
3421
+ }
3422
+ function getWithdrawRoutesQueryOptions(account) {
3423
+ return reactQuery.queryOptions({
3424
+ queryKey: ["wallet", "withdraw-routes", account],
3425
+ queryFn: () => CONFIG.hiveClient.database.call("get_withdraw_routes", [
3426
+ account,
3427
+ "outgoing"
3428
+ ])
3429
+ });
3430
+ }
3431
+ function getOpenOrdersQueryOptions(user) {
3432
+ return reactQuery.queryOptions({
3433
+ queryKey: ["wallet", "open-orders", user],
3434
+ queryFn: () => CONFIG.hiveClient.call("condenser_api", "get_open_orders", [
3435
+ user
3436
+ ]),
3437
+ select: (data) => data.sort((a, b) => a.orderid - b.orderid),
3438
+ enabled: !!user
3439
+ });
3440
+ }
3441
+ function getOutgoingRcDelegationsInfiniteQueryOptions(username, limit = 100) {
3442
+ return reactQuery.infiniteQueryOptions({
3443
+ queryKey: ["wallet", "outgoing-rc-delegations", username, limit],
3444
+ initialPageParam: null,
3445
+ queryFn: async ({ pageParam }) => {
3446
+ const response = await CONFIG.hiveClient.call("rc_api", "list_rc_direct_delegations", {
3447
+ start: [username, pageParam ?? ""],
3448
+ limit
3449
+ }).then((r) => r);
3450
+ let delegations = response.rc_direct_delegations || [];
3451
+ if (pageParam) {
3452
+ delegations = delegations.filter((delegation) => delegation.to !== pageParam);
1483
3453
  }
1484
- const fetchApi = getBoundFetch();
1485
- const response = await fetchApi(
1486
- `https://studio.3speak.tv/mobile/login?username=${username}&hivesigner=true`,
1487
- {
1488
- headers: {
1489
- "Content-Type": "application/json"
1490
- }
1491
- }
1492
- );
1493
- const memoQueryOptions = HiveSignerIntegration.queries.getDecodeMemoQueryOptions(
1494
- username,
1495
- (await response.json()).memo
1496
- );
1497
- await getQueryClient().prefetchQuery(memoQueryOptions);
1498
- const { memoDecoded } = getQueryClient().getQueryData(
1499
- memoQueryOptions.queryKey
3454
+ return delegations;
3455
+ },
3456
+ getNextPageParam: (lastPage) => lastPage.length === limit ? lastPage[lastPage.length - 1].to : null
3457
+ });
3458
+ }
3459
+ function getReceivedVestingSharesQueryOptions(username) {
3460
+ return reactQuery.queryOptions({
3461
+ queryKey: ["wallet", "received-vesting-shares", username],
3462
+ queryFn: async () => {
3463
+ const response = await fetch(
3464
+ CONFIG.privateApiHost + `/private-api/received-vesting/${username}`
1500
3465
  );
1501
- return memoDecoded.replace("#", "");
3466
+ if (!response.ok) {
3467
+ throw new Error(`Failed to fetch received vesting shares: ${response.status}`);
3468
+ }
3469
+ const data = await response.json();
3470
+ return data.list;
1502
3471
  }
1503
3472
  });
1504
3473
  }
1505
- function getAccountVideosQueryOptions(username) {
3474
+ function getWitnessesInfiniteQueryOptions(limit) {
3475
+ return reactQuery.infiniteQueryOptions({
3476
+ queryKey: ["witnesses", "list", limit],
3477
+ initialPageParam: "",
3478
+ queryFn: async ({ pageParam }) => CONFIG.hiveClient.call("condenser_api", "get_witnesses_by_vote", [
3479
+ pageParam,
3480
+ limit
3481
+ ]),
3482
+ getNextPageParam: (lastPage) => {
3483
+ const last = lastPage?.[lastPage.length - 1];
3484
+ return last ? last.owner : void 0;
3485
+ }
3486
+ });
3487
+ }
3488
+ function getOrderBookQueryOptions(limit = 500) {
1506
3489
  return reactQuery.queryOptions({
1507
- queryKey: ["integrations", "3speak", "videos", username],
1508
- enabled: !!username,
3490
+ queryKey: ["market", "order-book", limit],
3491
+ queryFn: () => CONFIG.hiveClient.call("condenser_api", "get_order_book", [
3492
+ limit
3493
+ ])
3494
+ });
3495
+ }
3496
+ function getMarketStatisticsQueryOptions() {
3497
+ return reactQuery.queryOptions({
3498
+ queryKey: ["market", "statistics"],
3499
+ queryFn: () => CONFIG.hiveClient.call("condenser_api", "get_ticker", [])
3500
+ });
3501
+ }
3502
+ function getMarketHistoryQueryOptions(seconds, startDate, endDate) {
3503
+ const formatDate = (date) => {
3504
+ return date.toISOString().replace(/\.\d{3}Z$/, "");
3505
+ };
3506
+ return reactQuery.queryOptions({
3507
+ queryKey: ["market", "history", seconds, startDate.getTime(), endDate.getTime()],
3508
+ queryFn: () => CONFIG.hiveClient.call("condenser_api", "get_market_history", [
3509
+ seconds,
3510
+ formatDate(startDate),
3511
+ formatDate(endDate)
3512
+ ])
3513
+ });
3514
+ }
3515
+ function getHiveHbdStatsQueryOptions() {
3516
+ return reactQuery.queryOptions({
3517
+ queryKey: ["market", "hive-hbd-stats"],
1509
3518
  queryFn: async () => {
1510
- await getQueryClient().prefetchQuery(
1511
- getAccountTokenQueryOptions(username)
3519
+ const stats = await CONFIG.hiveClient.call(
3520
+ "condenser_api",
3521
+ "get_ticker",
3522
+ []
1512
3523
  );
1513
- const token = getQueryClient().getQueryData(
1514
- getAccountTokenQueryOptions(username).queryKey
3524
+ const now = /* @__PURE__ */ new Date();
3525
+ const oneDayAgo = new Date(now.getTime() - 864e5);
3526
+ const formatDate = (date) => {
3527
+ return date.toISOString().replace(/\.\d{3}Z$/, "");
3528
+ };
3529
+ const dayChange = await CONFIG.hiveClient.call(
3530
+ "condenser_api",
3531
+ "get_market_history",
3532
+ [86400, formatDate(oneDayAgo), formatDate(now)]
1515
3533
  );
1516
- const fetchApi = getBoundFetch();
1517
- const response = await fetchApi(
1518
- `https://studio.3speak.tv/mobile/api/my-videos`,
3534
+ const result = {
3535
+ price: +stats.latest,
3536
+ close: dayChange[0] ? dayChange[0].non_hive.open / dayChange[0].hive.open : 0,
3537
+ high: dayChange[0] ? dayChange[0].non_hive.high / dayChange[0].hive.high : 0,
3538
+ low: dayChange[0] ? dayChange[0].non_hive.low / dayChange[0].hive.low : 0,
3539
+ percent: dayChange[0] ? 100 - dayChange[0].non_hive.open / dayChange[0].hive.open * 100 / +stats.latest : 0,
3540
+ totalFromAsset: stats.hive_volume.split(" ")[0],
3541
+ totalToAsset: stats.hbd_volume.split(" ")[0]
3542
+ };
3543
+ return result;
3544
+ }
3545
+ });
3546
+ }
3547
+ function getMarketDataQueryOptions(coin, vsCurrency, fromTs, toTs) {
3548
+ return reactQuery.queryOptions({
3549
+ queryKey: ["market", "data", coin, vsCurrency, fromTs, toTs],
3550
+ queryFn: async ({ signal }) => {
3551
+ const url = `https://api.coingecko.com/api/v3/coins/${coin}/market_chart/range?vs_currency=${vsCurrency}&from=${fromTs}&to=${toTs}`;
3552
+ const response = await fetch(url, { signal });
3553
+ if (!response.ok) {
3554
+ throw new Error(`Failed to fetch market data: ${response.status}`);
3555
+ }
3556
+ return response.json();
3557
+ }
3558
+ });
3559
+ }
3560
+ function getPointsQueryOptions(username, filter = 0) {
3561
+ return reactQuery.queryOptions({
3562
+ queryKey: ["points", username, filter],
3563
+ queryFn: async () => {
3564
+ if (!username) {
3565
+ throw new Error("Get points query \u2013 username wasn't provided");
3566
+ }
3567
+ const name = username.replace("@", "");
3568
+ const pointsResponse = await fetch(CONFIG.privateApiHost + "/private-api/points", {
3569
+ method: "POST",
3570
+ headers: {
3571
+ "Content-Type": "application/json"
3572
+ },
3573
+ body: JSON.stringify({ username: name })
3574
+ });
3575
+ if (!pointsResponse.ok) {
3576
+ throw new Error(`Failed to fetch points: ${pointsResponse.status}`);
3577
+ }
3578
+ const points = await pointsResponse.json();
3579
+ const transactionsResponse = await fetch(
3580
+ CONFIG.privateApiHost + "/private-api/point-list",
1519
3581
  {
3582
+ method: "POST",
1520
3583
  headers: {
1521
- "Content-Type": "application/json",
1522
- Authorization: `Bearer ${token}`
1523
- }
3584
+ "Content-Type": "application/json"
3585
+ },
3586
+ body: JSON.stringify({ username: name, type: filter })
1524
3587
  }
1525
3588
  );
1526
- return await response.json();
3589
+ if (!transactionsResponse.ok) {
3590
+ throw new Error(`Failed to fetch point transactions: ${transactionsResponse.status}`);
3591
+ }
3592
+ const transactions = await transactionsResponse.json();
3593
+ return {
3594
+ points: points.points,
3595
+ uPoints: points.unclaimed_points,
3596
+ transactions
3597
+ };
3598
+ },
3599
+ staleTime: 3e4,
3600
+ refetchOnMount: true,
3601
+ enabled: !!username
3602
+ });
3603
+ }
3604
+ function searchQueryOptions(q, sort, hideLow, since, scroll_id, votes) {
3605
+ return reactQuery.queryOptions({
3606
+ queryKey: ["search", q, sort, hideLow, since, scroll_id, votes],
3607
+ queryFn: async () => {
3608
+ const data = { q, sort, hide_low: hideLow };
3609
+ if (since) data.since = since;
3610
+ if (scroll_id) data.scroll_id = scroll_id;
3611
+ if (votes) data.votes = votes;
3612
+ const response = await fetch(CONFIG.privateApiHost + "/search-api/search", {
3613
+ method: "POST",
3614
+ headers: {
3615
+ "Content-Type": "application/json"
3616
+ },
3617
+ body: JSON.stringify(data)
3618
+ });
3619
+ if (!response.ok) {
3620
+ throw new Error(`Search failed: ${response.status}`);
3621
+ }
3622
+ return response.json();
1527
3623
  }
1528
3624
  });
1529
3625
  }
1530
-
1531
- // src/modules/integrations/3speak/index.ts
1532
- var ThreeSpeakIntegration = {
1533
- queries: queries_exports2
1534
- };
1535
- function getHivePoshLinksQueryOptions(username) {
3626
+ function getControversialRisingInfiniteQueryOptions(what, tag, enabled = true) {
3627
+ return reactQuery.infiniteQueryOptions({
3628
+ queryKey: ["search", "controversial-rising", what, tag],
3629
+ initialPageParam: { sid: void 0, hasNextPage: true },
3630
+ queryFn: async ({ pageParam }) => {
3631
+ if (!pageParam.hasNextPage) {
3632
+ return {
3633
+ hits: 0,
3634
+ took: 0,
3635
+ results: []
3636
+ };
3637
+ }
3638
+ let sinceDate;
3639
+ const now = /* @__PURE__ */ new Date();
3640
+ switch (tag) {
3641
+ case "today":
3642
+ sinceDate = new Date(now.getTime() - 24 * 60 * 60 * 1e3);
3643
+ break;
3644
+ case "week":
3645
+ sinceDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1e3);
3646
+ break;
3647
+ case "month":
3648
+ sinceDate = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1e3);
3649
+ break;
3650
+ case "year":
3651
+ sinceDate = new Date(now.getTime() - 365 * 24 * 60 * 60 * 1e3);
3652
+ break;
3653
+ default:
3654
+ sinceDate = void 0;
3655
+ }
3656
+ const q = "* type:post";
3657
+ const sort = what === "rising" ? "children" : what;
3658
+ const since = sinceDate ? sinceDate.toISOString().split(".")[0] : void 0;
3659
+ const hideLow = "0";
3660
+ const votes = tag === "today" ? 50 : 200;
3661
+ const data = { q, sort, hide_low: hideLow };
3662
+ if (since) data.since = since;
3663
+ if (pageParam.sid) data.scroll_id = pageParam.sid;
3664
+ data.votes = votes;
3665
+ const response = await fetch(CONFIG.privateApiHost + "/search-api/search", {
3666
+ method: "POST",
3667
+ headers: {
3668
+ "Content-Type": "application/json"
3669
+ },
3670
+ body: JSON.stringify(data)
3671
+ });
3672
+ if (!response.ok) {
3673
+ throw new Error(`Search failed: ${response.status}`);
3674
+ }
3675
+ return response.json();
3676
+ },
3677
+ getNextPageParam: (resp) => {
3678
+ return {
3679
+ sid: resp?.scroll_id,
3680
+ hasNextPage: resp.results.length > 0
3681
+ };
3682
+ },
3683
+ enabled
3684
+ });
3685
+ }
3686
+ function buildQuery(entry, retry = 3) {
3687
+ const { json_metadata, permlink } = entry;
3688
+ let q = "*";
3689
+ q += ` -dporn type:post`;
3690
+ let tags;
3691
+ if (json_metadata && json_metadata.tags && Array.isArray(json_metadata.tags)) {
3692
+ tags = json_metadata.tags.filter((tag) => tag && tag !== "").filter((tag) => !tag.startsWith("hive-")).filter((_tag, ind) => ind < +retry).join(",");
3693
+ }
3694
+ if (tags && tags.length > 0) {
3695
+ q += ` tag:${tags}`;
3696
+ } else {
3697
+ const fperm = permlink.split("-");
3698
+ tags = fperm.filter((part) => part !== "").filter((part) => !/^-?\d+$/.test(part)).filter((part) => part.length > 2).join(",");
3699
+ q += ` tag:${tags}`;
3700
+ }
3701
+ return q;
3702
+ }
3703
+ function getSimilarEntriesQueryOptions(entry) {
3704
+ const query = buildQuery(entry);
1536
3705
  return reactQuery.queryOptions({
1537
- queryKey: ["integrations", "hiveposh", "links", username],
3706
+ queryKey: ["search", "similar-entries", entry.author, entry.permlink, query],
1538
3707
  queryFn: async () => {
1539
- const fetchApi = getBoundFetch();
1540
- const response = await fetchApi(
1541
- `https://hiveposh.com/api/v0/linked-accounts/${username}`,
1542
- {
1543
- headers: {
1544
- "Content-Type": "application/json"
1545
- }
1546
- }
1547
- );
1548
- const data = await response.json();
1549
- return {
1550
- twitter: {
1551
- username: data.twitter_username,
1552
- profile: data.twitter_profile
3708
+ const data = {
3709
+ q: query,
3710
+ sort: "newest",
3711
+ hide_low: "0"
3712
+ };
3713
+ const response = await fetch(CONFIG.privateApiHost + "/search-api/search", {
3714
+ method: "POST",
3715
+ headers: {
3716
+ "Content-Type": "application/json"
1553
3717
  },
1554
- reddit: {
1555
- username: data.reddit_username,
1556
- profile: data.reddit_profile
3718
+ body: JSON.stringify(data)
3719
+ });
3720
+ if (!response.ok) {
3721
+ throw new Error(`Search failed: ${response.status}`);
3722
+ }
3723
+ const searchResponse = await response.json();
3724
+ const rawEntries = searchResponse.results.filter(
3725
+ (r) => r.permlink !== entry.permlink && r.tags.indexOf("nsfw") === -1
3726
+ );
3727
+ const entries = [];
3728
+ for (const result of rawEntries) {
3729
+ if (entries.find((y) => y.author === result.author) === void 0) {
3730
+ entries.push(result);
1557
3731
  }
1558
- };
3732
+ }
3733
+ return entries.slice(0, 3);
1559
3734
  }
1560
3735
  });
1561
3736
  }
1562
- function getStatsQueryOptions({
1563
- url,
1564
- dimensions = [],
1565
- metrics = ["visitors", "pageviews", "visit_duration"],
1566
- enabled = true
1567
- }) {
3737
+ function getSearchAccountQueryOptions(q, limit = 5, random = false) {
1568
3738
  return reactQuery.queryOptions({
1569
- queryKey: ["integrations", "plausible", url, dimensions, metrics],
3739
+ queryKey: ["search", "account", q, limit],
1570
3740
  queryFn: async () => {
1571
- const fetchApi = getBoundFetch();
1572
- const response = await fetchApi(`https://ecency.com/api/stats`, {
3741
+ const data = { q, limit, random: +random };
3742
+ const response = await fetch(CONFIG.privateApiHost + "/search-api/search-account", {
1573
3743
  method: "POST",
1574
- body: JSON.stringify({
1575
- metrics,
1576
- url: encodeURIComponent(url),
1577
- dimensions
1578
- }),
1579
3744
  headers: {
1580
3745
  "Content-Type": "application/json"
1581
- }
3746
+ },
3747
+ body: JSON.stringify(data)
1582
3748
  });
1583
- return await response.json();
3749
+ if (!response.ok) {
3750
+ throw new Error(`Failed to search accounts: ${response.status}`);
3751
+ }
3752
+ return response.json();
1584
3753
  },
1585
- enabled: !!url && enabled
3754
+ enabled: !!q
1586
3755
  });
1587
3756
  }
1588
- function getRcStatsQueryOptions() {
3757
+ function getSearchTopicsQueryOptions(q, limit = 20, random = false) {
1589
3758
  return reactQuery.queryOptions({
1590
- queryKey: ["resource-credits", "stats"],
3759
+ queryKey: ["search", "topics", q],
1591
3760
  queryFn: async () => {
1592
- const response = await CONFIG.hiveClient.call(
1593
- "rc_api",
1594
- "get_rc_stats",
1595
- {}
1596
- );
1597
- return response.rc_stats;
1598
- }
3761
+ const data = { q, limit, random: +random };
3762
+ const response = await fetch(CONFIG.privateApiHost + "/search-api/search-tag", {
3763
+ method: "POST",
3764
+ headers: {
3765
+ "Content-Type": "application/json"
3766
+ },
3767
+ body: JSON.stringify(data)
3768
+ });
3769
+ if (!response.ok) {
3770
+ throw new Error(`Failed to search topics: ${response.status}`);
3771
+ }
3772
+ return response.json();
3773
+ },
3774
+ enabled: !!q
1599
3775
  });
1600
3776
  }
1601
- function getAccountRcQueryOptions(username) {
1602
- return reactQuery.queryOptions({
1603
- queryKey: ["resource-credits", "account", username],
1604
- queryFn: async () => {
1605
- const rcClient = new dhive.RCAPI(CONFIG.hiveClient);
1606
- return rcClient.findRCAccounts([username]);
3777
+ function getSearchApiInfiniteQueryOptions(q, sort, hideLow, since, votes) {
3778
+ return reactQuery.infiniteQueryOptions({
3779
+ queryKey: ["search", "api", q, sort, hideLow, since, votes],
3780
+ queryFn: async ({ pageParam }) => {
3781
+ const payload = { q, sort, hide_low: hideLow };
3782
+ if (since) {
3783
+ payload.since = since;
3784
+ }
3785
+ if (pageParam) {
3786
+ payload.scroll_id = pageParam;
3787
+ }
3788
+ if (votes !== void 0) {
3789
+ payload.votes = votes;
3790
+ }
3791
+ const response = await fetch(CONFIG.privateApiHost + "/search-api/search", {
3792
+ method: "POST",
3793
+ headers: {
3794
+ "Content-Type": "application/json"
3795
+ },
3796
+ body: JSON.stringify(payload)
3797
+ });
3798
+ if (!response.ok) {
3799
+ throw new Error(`Search failed: ${response.status}`);
3800
+ }
3801
+ return response.json();
1607
3802
  },
1608
- enabled: !!username
3803
+ initialPageParam: void 0,
3804
+ getNextPageParam: (lastPage) => lastPage?.scroll_id,
3805
+ enabled: !!q
1609
3806
  });
1610
3807
  }
1611
- function getGameStatusCheckQueryOptions(username, gameType) {
3808
+ function getSearchPathQueryOptions(q) {
1612
3809
  return reactQuery.queryOptions({
1613
- queryKey: ["games", "status-check", gameType, username],
1614
- enabled: !!username,
3810
+ queryKey: ["search", "path", q],
1615
3811
  queryFn: async () => {
1616
- if (!username) {
1617
- throw new Error("[SDK][Games] \u2013 anon user in status check");
3812
+ const response = await fetch(CONFIG.privateApiHost + "/search-api/search-path", {
3813
+ method: "POST",
3814
+ headers: {
3815
+ "Content-Type": "application/json"
3816
+ },
3817
+ body: JSON.stringify({ q })
3818
+ });
3819
+ if (!response.ok) {
3820
+ throw new Error(`Search path failed: ${response.status}`);
1618
3821
  }
1619
- const fetchApi = getBoundFetch();
1620
- const response = await fetchApi(
1621
- CONFIG.privateApiHost + "/private-api/get-game",
1622
- {
1623
- method: "POST",
1624
- body: JSON.stringify({
1625
- game_type: gameType,
1626
- code: getAccessToken(username)
1627
- }),
1628
- headers: {
1629
- "Content-Type": "application/json"
1630
- }
1631
- }
1632
- );
1633
- return await response.json();
3822
+ const data = await response.json();
3823
+ if (data?.length > 0) {
3824
+ return data;
3825
+ }
3826
+ return [q];
1634
3827
  }
1635
3828
  });
1636
3829
  }
1637
- function useGameClaim(username, gameType, key) {
1638
- const { mutateAsync: recordActivity } = useRecordActivity(
1639
- username,
1640
- "spin-rolled"
1641
- );
1642
- return reactQuery.useMutation({
1643
- mutationKey: ["games", "post", gameType, username],
1644
- mutationFn: async () => {
1645
- if (!username) {
1646
- throw new Error("[SDK][Games] \u2013 anon user in game post");
3830
+ function getBoostPlusPricesQueryOptions(accessToken) {
3831
+ return reactQuery.queryOptions({
3832
+ queryKey: ["promotions", "boost-plus-prices"],
3833
+ queryFn: async () => {
3834
+ if (!accessToken) {
3835
+ return [];
3836
+ }
3837
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/boost-plus-price", {
3838
+ method: "POST",
3839
+ headers: {
3840
+ "Content-Type": "application/json"
3841
+ },
3842
+ body: JSON.stringify({ code: accessToken })
3843
+ });
3844
+ if (!response.ok) {
3845
+ throw new Error(`Failed to fetch boost plus prices: ${response.status}`);
1647
3846
  }
1648
- const fetchApi = getBoundFetch();
1649
- const response = await fetchApi(
1650
- CONFIG.privateApiHost + "/private-api/post-game",
1651
- {
1652
- method: "POST",
1653
- body: JSON.stringify({
1654
- game_type: gameType,
1655
- code: getAccessToken(username),
1656
- key
1657
- }),
1658
- headers: {
1659
- "Content-Type": "application/json"
1660
- }
1661
- }
1662
- );
1663
3847
  return await response.json();
1664
3848
  },
1665
- onSuccess() {
1666
- recordActivity();
1667
- }
3849
+ staleTime: Infinity,
3850
+ refetchOnMount: true,
3851
+ enabled: !!accessToken
1668
3852
  });
1669
3853
  }
1670
- function getCommunitiesQueryOptions(sort, query, limit = 100, observer = void 0, enabled = true) {
3854
+ function getPromotePriceQueryOptions(accessToken) {
1671
3855
  return reactQuery.queryOptions({
1672
- queryKey: ["communities", "list", sort, query, limit],
1673
- enabled,
3856
+ queryKey: ["promotions", "promote-price"],
1674
3857
  queryFn: async () => {
1675
- const response = await CONFIG.hiveClient.call(
1676
- "bridge",
1677
- "list_communities",
1678
- {
1679
- last: "",
1680
- limit,
1681
- sort: sort === "hot" ? "rank" : sort,
1682
- query: query ? query : null,
1683
- observer
1684
- }
1685
- );
1686
- return response ? sort === "hot" ? response.sort(() => Math.random() - 0.5) : response : [];
1687
- }
3858
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/promote-price", {
3859
+ method: "POST",
3860
+ headers: {
3861
+ "Content-Type": "application/json"
3862
+ },
3863
+ body: JSON.stringify({ code: accessToken })
3864
+ });
3865
+ if (!response.ok) {
3866
+ throw new Error(`Failed to fetch promote prices: ${response.status}`);
3867
+ }
3868
+ return await response.json();
3869
+ },
3870
+ enabled: !!accessToken
1688
3871
  });
1689
3872
  }
1690
- function getCommunityContextQueryOptions(username, communityName) {
3873
+ function getBoostPlusAccountPricesQueryOptions(account, accessToken) {
1691
3874
  return reactQuery.queryOptions({
1692
- queryKey: ["community", "context", username, communityName],
1693
- enabled: !!username && !!communityName,
3875
+ queryKey: ["promotions", "boost-plus-accounts", account],
1694
3876
  queryFn: async () => {
1695
- const response = await CONFIG.hiveClient.call(
1696
- "bridge",
1697
- "get_community_context",
1698
- {
1699
- account: username,
1700
- name: communityName
1701
- }
1702
- );
1703
- return {
1704
- role: response?.role ?? "guest",
1705
- subscribed: response?.subscribed ?? false
1706
- };
1707
- }
3877
+ if (!accessToken || !account) {
3878
+ return null;
3879
+ }
3880
+ const response = await fetch(CONFIG.privateApiHost + "/private-api/boosted-plus-account", {
3881
+ method: "POST",
3882
+ headers: {
3883
+ "Content-Type": "application/json"
3884
+ },
3885
+ body: JSON.stringify({ code: accessToken, account })
3886
+ });
3887
+ if (!response.ok) {
3888
+ throw new Error(`Failed to fetch boost plus account prices: ${response.status}`);
3889
+ }
3890
+ const responseData = await response.json();
3891
+ return responseData ? {
3892
+ account: responseData.account,
3893
+ expires: new Date(responseData.expires)
3894
+ } : null;
3895
+ },
3896
+ enabled: !!account && !!accessToken
1708
3897
  });
1709
3898
  }
1710
3899
 
1711
- // src/modules/communities/types/community.ts
1712
- var ROLES = /* @__PURE__ */ ((ROLES2) => {
1713
- ROLES2["OWNER"] = "owner";
1714
- ROLES2["ADMIN"] = "admin";
1715
- ROLES2["MOD"] = "mod";
1716
- ROLES2["MEMBER"] = "member";
1717
- ROLES2["GUEST"] = "guest";
1718
- ROLES2["MUTED"] = "muted";
1719
- return ROLES2;
1720
- })(ROLES || {});
1721
- var roleMap = {
1722
- ["owner" /* OWNER */]: [
1723
- "admin" /* ADMIN */,
1724
- "mod" /* MOD */,
1725
- "member" /* MEMBER */,
1726
- "guest" /* GUEST */,
1727
- "muted" /* MUTED */
1728
- ],
1729
- ["admin" /* ADMIN */]: ["mod" /* MOD */, "member" /* MEMBER */, "guest" /* GUEST */, "muted" /* MUTED */],
1730
- ["mod" /* MOD */]: ["member" /* MEMBER */, "guest" /* GUEST */, "muted" /* MUTED */]
1731
- };
1732
-
1733
- // src/modules/communities/utils/index.ts
1734
- function getCommunityType(name, type_id) {
1735
- if (name.startsWith("hive-3") || type_id === 3) return "Council";
1736
- if (name.startsWith("hive-2") || type_id === 2) return "Journal";
1737
- return "Topic";
1738
- }
1739
- function getCommunityPermissions({
1740
- communityType,
1741
- userRole,
1742
- subscribed
1743
- }) {
1744
- const canPost = (() => {
1745
- if (userRole === "muted" /* MUTED */) return false;
1746
- if (communityType === "Topic") return true;
1747
- return ["owner" /* OWNER */, "admin" /* ADMIN */, "mod" /* MOD */, "member" /* MEMBER */].includes(
1748
- userRole
1749
- );
1750
- })();
1751
- const canComment = (() => {
1752
- if (userRole === "muted" /* MUTED */) return false;
1753
- switch (communityType) {
1754
- case "Topic":
1755
- return true;
1756
- case "Journal":
1757
- return userRole !== "guest" /* GUEST */ || subscribed;
1758
- case "Council":
1759
- return canPost;
1760
- }
1761
- })();
1762
- const isModerator = ["owner" /* OWNER */, "admin" /* ADMIN */, "mod" /* MOD */].includes(userRole);
1763
- return {
1764
- canPost,
1765
- canComment,
1766
- isModerator
1767
- };
1768
- }
1769
-
3900
+ exports.ACCOUNT_OPERATION_GROUPS = ACCOUNT_OPERATION_GROUPS;
3901
+ exports.ALL_ACCOUNT_OPERATIONS = ALL_ACCOUNT_OPERATIONS;
3902
+ exports.ALL_NOTIFY_TYPES = ALL_NOTIFY_TYPES;
1770
3903
  exports.CONFIG = CONFIG;
1771
3904
  exports.EcencyAnalytics = mutations_exports;
1772
3905
  exports.HiveSignerIntegration = HiveSignerIntegration;
1773
3906
  exports.Keychain = keychain_exports;
1774
3907
  exports.NaiMap = NaiMap;
3908
+ exports.NotificationFilter = NotificationFilter;
3909
+ exports.NotificationViewType = NotificationViewType;
3910
+ exports.NotifyTypes = NotifyTypes;
1775
3911
  exports.ROLES = ROLES;
3912
+ exports.SortOrder = SortOrder;
1776
3913
  exports.Symbol = Symbol2;
1777
3914
  exports.ThreeSpeakIntegration = ThreeSpeakIntegration;
1778
3915
  exports.broadcastJson = broadcastJson;
@@ -1784,37 +3921,112 @@ exports.encodeObj = encodeObj;
1784
3921
  exports.extractAccountProfile = extractAccountProfile;
1785
3922
  exports.getAccessToken = getAccessToken;
1786
3923
  exports.getAccountFullQueryOptions = getAccountFullQueryOptions;
3924
+ exports.getAccountNotificationsInfiniteQueryOptions = getAccountNotificationsInfiniteQueryOptions;
1787
3925
  exports.getAccountPendingRecoveryQueryOptions = getAccountPendingRecoveryQueryOptions;
3926
+ exports.getAccountPostsInfiniteQueryOptions = getAccountPostsInfiniteQueryOptions;
1788
3927
  exports.getAccountRcQueryOptions = getAccountRcQueryOptions;
1789
3928
  exports.getAccountRecoveriesQueryOptions = getAccountRecoveriesQueryOptions;
1790
3929
  exports.getAccountSubscriptionsQueryOptions = getAccountSubscriptionsQueryOptions;
3930
+ exports.getAccountVoteHistoryInfiniteQueryOptions = getAccountVoteHistoryInfiniteQueryOptions;
3931
+ exports.getAccountsQueryOptions = getAccountsQueryOptions;
1791
3932
  exports.getActiveAccountBookmarksQueryOptions = getActiveAccountBookmarksQueryOptions;
1792
3933
  exports.getActiveAccountFavouritesQueryOptions = getActiveAccountFavouritesQueryOptions;
3934
+ exports.getAnnouncementsQueryOptions = getAnnouncementsQueryOptions;
3935
+ exports.getBoostPlusAccountPricesQueryOptions = getBoostPlusAccountPricesQueryOptions;
3936
+ exports.getBoostPlusPricesQueryOptions = getBoostPlusPricesQueryOptions;
3937
+ exports.getBotsQueryOptions = getBotsQueryOptions;
1793
3938
  exports.getBoundFetch = getBoundFetch;
1794
3939
  exports.getChainPropertiesQueryOptions = getChainPropertiesQueryOptions;
3940
+ exports.getCollateralizedConversionRequestsQueryOptions = getCollateralizedConversionRequestsQueryOptions;
3941
+ exports.getCommentHistoryQueryOptions = getCommentHistoryQueryOptions;
1795
3942
  exports.getCommunitiesQueryOptions = getCommunitiesQueryOptions;
1796
3943
  exports.getCommunityContextQueryOptions = getCommunityContextQueryOptions;
1797
3944
  exports.getCommunityPermissions = getCommunityPermissions;
3945
+ exports.getCommunitySubscribersQueryOptions = getCommunitySubscribersQueryOptions;
1798
3946
  exports.getCommunityType = getCommunityType;
3947
+ exports.getControversialRisingInfiniteQueryOptions = getControversialRisingInfiniteQueryOptions;
3948
+ exports.getConversionRequestsQueryOptions = getConversionRequestsQueryOptions;
3949
+ exports.getDeletedEntryQueryOptions = getDeletedEntryQueryOptions;
3950
+ exports.getDiscoverCurationQueryOptions = getDiscoverCurationQueryOptions;
3951
+ exports.getDiscoverLeaderboardQueryOptions = getDiscoverLeaderboardQueryOptions;
3952
+ exports.getDiscussionsQueryOptions = getDiscussionsQueryOptions;
3953
+ exports.getDraftsQueryOptions = getDraftsQueryOptions;
1799
3954
  exports.getDynamicPropsQueryOptions = getDynamicPropsQueryOptions;
3955
+ exports.getEntryActiveVotesQueryOptions = getEntryActiveVotesQueryOptions;
3956
+ exports.getFollowCountQueryOptions = getFollowCountQueryOptions;
3957
+ exports.getFollowingQueryOptions = getFollowingQueryOptions;
1800
3958
  exports.getFragmentsQueryOptions = getFragmentsQueryOptions;
3959
+ exports.getFriendsInfiniteQueryOptions = getFriendsInfiniteQueryOptions;
3960
+ exports.getGalleryImagesQueryOptions = getGalleryImagesQueryOptions;
1801
3961
  exports.getGameStatusCheckQueryOptions = getGameStatusCheckQueryOptions;
3962
+ exports.getHiveHbdStatsQueryOptions = getHiveHbdStatsQueryOptions;
1802
3963
  exports.getHivePoshLinksQueryOptions = getHivePoshLinksQueryOptions;
3964
+ exports.getImagesQueryOptions = getImagesQueryOptions;
1803
3965
  exports.getLoginType = getLoginType;
3966
+ exports.getMarketDataQueryOptions = getMarketDataQueryOptions;
3967
+ exports.getMarketHistoryQueryOptions = getMarketHistoryQueryOptions;
3968
+ exports.getMarketStatisticsQueryOptions = getMarketStatisticsQueryOptions;
3969
+ exports.getMutedUsersQueryOptions = getMutedUsersQueryOptions;
3970
+ exports.getNotificationsInfiniteQueryOptions = getNotificationsInfiniteQueryOptions;
3971
+ exports.getNotificationsSettingsQueryOptions = getNotificationsSettingsQueryOptions;
3972
+ exports.getNotificationsUnreadCountQueryOptions = getNotificationsUnreadCountQueryOptions;
3973
+ exports.getOpenOrdersQueryOptions = getOpenOrdersQueryOptions;
3974
+ exports.getOrderBookQueryOptions = getOrderBookQueryOptions;
3975
+ exports.getOutgoingRcDelegationsInfiniteQueryOptions = getOutgoingRcDelegationsInfiniteQueryOptions;
3976
+ exports.getPageStatsQueryOptions = getPageStatsQueryOptions;
3977
+ exports.getPointsQueryOptions = getPointsQueryOptions;
3978
+ exports.getPostHeaderQueryOptions = getPostHeaderQueryOptions;
3979
+ exports.getPostQueryOptions = getPostQueryOptions;
3980
+ exports.getPostTipsQueryOptions = getPostTipsQueryOptions;
1804
3981
  exports.getPostingKey = getPostingKey;
3982
+ exports.getPostsRankedInfiniteQueryOptions = getPostsRankedInfiniteQueryOptions;
3983
+ exports.getPromotePriceQueryOptions = getPromotePriceQueryOptions;
1805
3984
  exports.getPromotedPostsQuery = getPromotedPostsQuery;
3985
+ exports.getProposalQueryOptions = getProposalQueryOptions;
3986
+ exports.getProposalVotesInfiniteQueryOptions = getProposalVotesInfiniteQueryOptions;
3987
+ exports.getProposalsQueryOptions = getProposalsQueryOptions;
1806
3988
  exports.getQueryClient = getQueryClient;
1807
3989
  exports.getRcStatsQueryOptions = getRcStatsQueryOptions;
3990
+ exports.getReblogsQueryOptions = getReblogsQueryOptions;
3991
+ exports.getReceivedVestingSharesQueryOptions = getReceivedVestingSharesQueryOptions;
3992
+ exports.getReferralsInfiniteQueryOptions = getReferralsInfiniteQueryOptions;
3993
+ exports.getReferralsStatsQueryOptions = getReferralsStatsQueryOptions;
1808
3994
  exports.getRefreshToken = getRefreshToken;
1809
3995
  exports.getRelationshipBetweenAccountsQueryOptions = getRelationshipBetweenAccountsQueryOptions;
3996
+ exports.getRewardedCommunitiesQueryOptions = getRewardedCommunitiesQueryOptions;
3997
+ exports.getSavingsWithdrawFromQueryOptions = getSavingsWithdrawFromQueryOptions;
3998
+ exports.getSchedulesQueryOptions = getSchedulesQueryOptions;
3999
+ exports.getSearchAccountQueryOptions = getSearchAccountQueryOptions;
1810
4000
  exports.getSearchAccountsByUsernameQueryOptions = getSearchAccountsByUsernameQueryOptions;
4001
+ exports.getSearchApiInfiniteQueryOptions = getSearchApiInfiniteQueryOptions;
4002
+ exports.getSearchFriendsQueryOptions = getSearchFriendsQueryOptions;
4003
+ exports.getSearchPathQueryOptions = getSearchPathQueryOptions;
4004
+ exports.getSearchTopicsQueryOptions = getSearchTopicsQueryOptions;
4005
+ exports.getSimilarEntriesQueryOptions = getSimilarEntriesQueryOptions;
1811
4006
  exports.getStatsQueryOptions = getStatsQueryOptions;
4007
+ exports.getTransactionsInfiniteQueryOptions = getTransactionsInfiniteQueryOptions;
1812
4008
  exports.getTrendingTagsQueryOptions = getTrendingTagsQueryOptions;
1813
4009
  exports.getUser = getUser;
4010
+ exports.getUserProposalVotesQueryOptions = getUserProposalVotesQueryOptions;
4011
+ exports.getVestingDelegationsQueryOptions = getVestingDelegationsQueryOptions;
4012
+ exports.getVisibleFirstLevelThreadItems = getVisibleFirstLevelThreadItems;
4013
+ exports.getWavesByHostQueryOptions = getWavesByHostQueryOptions;
4014
+ exports.getWavesByTagQueryOptions = getWavesByTagQueryOptions;
4015
+ exports.getWavesFollowingQueryOptions = getWavesFollowingQueryOptions;
4016
+ exports.getWavesTrendingTagsQueryOptions = getWavesTrendingTagsQueryOptions;
4017
+ exports.getWithdrawRoutesQueryOptions = getWithdrawRoutesQueryOptions;
4018
+ exports.getWitnessesInfiniteQueryOptions = getWitnessesInfiniteQueryOptions;
4019
+ exports.lookupAccountsQueryOptions = lookupAccountsQueryOptions;
1814
4020
  exports.makeQueryClient = makeQueryClient;
4021
+ exports.mapThreadItemsToWaveEntries = mapThreadItemsToWaveEntries;
4022
+ exports.normalizeWaveEntryFromApi = normalizeWaveEntryFromApi;
4023
+ exports.parseAccounts = parseAccounts;
1815
4024
  exports.parseAsset = parseAsset;
1816
4025
  exports.parseProfileMetadata = parseProfileMetadata;
1817
4026
  exports.roleMap = roleMap;
4027
+ exports.searchQueryOptions = searchQueryOptions;
4028
+ exports.sortDiscussions = sortDiscussions;
4029
+ exports.toEntryArray = toEntryArray;
1818
4030
  exports.useAccountFavouriteAdd = useAccountFavouriteAdd;
1819
4031
  exports.useAccountFavouriteDelete = useAccountFavouriteDelete;
1820
4032
  exports.useAccountRelationsUpdate = useAccountRelationsUpdate;
@@ -1830,6 +4042,7 @@ exports.useBookmarkDelete = useBookmarkDelete;
1830
4042
  exports.useBroadcastMutation = useBroadcastMutation;
1831
4043
  exports.useEditFragment = useEditFragment;
1832
4044
  exports.useGameClaim = useGameClaim;
4045
+ exports.useRecordActivity = useRecordActivity;
1833
4046
  exports.useRemoveFragment = useRemoveFragment;
1834
4047
  exports.useSignOperationByHivesigner = useSignOperationByHivesigner;
1835
4048
  exports.useSignOperationByKey = useSignOperationByKey;