@ecency/sdk 1.3.6 → 1.3.9

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