@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.
- package/dist/browser/index.d.ts +1935 -25
- package/dist/browser/index.js +2969 -835
- package/dist/browser/index.js.map +1 -1
- package/dist/node/index.cjs +3049 -832
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.mjs +2969 -835
- package/dist/node/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/node/index.cjs
CHANGED
|
@@ -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
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
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
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
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
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
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
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
1130
|
+
const response = await fetch(url.toString(), {
|
|
1131
|
+
method: "GET",
|
|
1132
|
+
headers: {
|
|
1133
|
+
"Content-Type": "application/json"
|
|
1134
|
+
}
|
|
774
1135
|
});
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
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
|
-
(
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
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
|
-
|
|
796
|
-
|
|
797
|
-
|
|
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
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
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
|
-
|
|
815
|
-
|
|
816
|
-
relationsQuery.queryKey
|
|
1187
|
+
const accountNames = response.map(
|
|
1188
|
+
(e) => mode === "following" ? e.following : e.follower
|
|
817
1189
|
);
|
|
818
|
-
await
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
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
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
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
|
|
846
|
-
return reactQuery.
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
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/
|
|
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
|
-
|
|
870
|
-
onSuccess();
|
|
871
|
-
getQueryClient().invalidateQueries({
|
|
872
|
-
queryKey: ["accounts", "bookmarks", username]
|
|
873
|
-
});
|
|
874
|
-
},
|
|
875
|
-
onError
|
|
1267
|
+
enabled: !!username
|
|
876
1268
|
});
|
|
877
1269
|
}
|
|
878
|
-
function
|
|
879
|
-
return reactQuery.
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
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
|
-
|
|
888
|
-
{
|
|
889
|
-
|
|
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
|
-
|
|
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
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
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
|
-
|
|
1313
|
+
initialData: null
|
|
908
1314
|
});
|
|
909
1315
|
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
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
|
|
918
|
-
|
|
919
|
-
|
|
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
|
-
|
|
1362
|
+
enabled: !!author && !!permlink && permlink.trim() !== "" && permlink.trim() !== "undefined"
|
|
940
1363
|
});
|
|
941
1364
|
}
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
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
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
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
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
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
|
-
|
|
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
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
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
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
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
|
-
|
|
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
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
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
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
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
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
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
|
-
|
|
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
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
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
|
-
|
|
1071
|
-
(
|
|
2818
|
+
const token = getQueryClient().getQueryData(
|
|
2819
|
+
getAccountTokenQueryOptions(username).queryKey
|
|
1072
2820
|
);
|
|
1073
|
-
const
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
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
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
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
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
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
|
-
|
|
1171
|
-
onSuccess: options.onSuccess
|
|
2905
|
+
enabled: !!url && enabled
|
|
1172
2906
|
});
|
|
1173
2907
|
}
|
|
1174
|
-
function
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
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
|
-
|
|
2928
|
+
enabled: !!username
|
|
1204
2929
|
});
|
|
1205
2930
|
}
|
|
1206
|
-
function
|
|
1207
|
-
return reactQuery.
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
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("[
|
|
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
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
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
|
|
2957
|
+
function useGameClaim(username, gameType, key) {
|
|
2958
|
+
const { mutateAsync: recordActivity } = useRecordActivity(
|
|
2959
|
+
username,
|
|
2960
|
+
"spin-rolled"
|
|
2961
|
+
);
|
|
1232
2962
|
return reactQuery.useMutation({
|
|
1233
|
-
mutationKey: ["
|
|
1234
|
-
mutationFn: (
|
|
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
|
-
|
|
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
|
|
1245
|
-
return reactQuery.
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
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
|
|
3010
|
+
function getCommunityContextQueryOptions(username, communityName) {
|
|
1254
3011
|
return reactQuery.queryOptions({
|
|
1255
|
-
queryKey: ["
|
|
3012
|
+
queryKey: ["community", "context", username, communityName],
|
|
3013
|
+
enabled: !!username && !!communityName,
|
|
1256
3014
|
queryFn: async () => {
|
|
1257
|
-
|
|
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
|
|
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: ["
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
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
|
|
3061
|
+
function getRewardedCommunitiesQueryOptions() {
|
|
1276
3062
|
return reactQuery.queryOptions({
|
|
1277
|
-
queryKey: ["
|
|
3063
|
+
queryKey: ["communities", "rewarded"],
|
|
1278
3064
|
queryFn: async () => {
|
|
1279
|
-
const
|
|
1280
|
-
|
|
1281
|
-
CONFIG.privateApiHost + "/private-api/fragments",
|
|
3065
|
+
const response = await fetch(
|
|
3066
|
+
CONFIG.privateApiHost + "/private-api/rewarded-communities",
|
|
1282
3067
|
{
|
|
1283
|
-
method: "
|
|
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
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
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
|
|
1320
|
-
return reactQuery.
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
const
|
|
1324
|
-
|
|
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
|
-
|
|
3154
|
+
const data = await response.json();
|
|
3155
|
+
return data.count;
|
|
1339
3156
|
},
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
(data) => [response, ...data ?? []]
|
|
1344
|
-
);
|
|
1345
|
-
}
|
|
3157
|
+
enabled: !!activeUsername,
|
|
3158
|
+
initialData: 0,
|
|
3159
|
+
refetchInterval: 6e4
|
|
1346
3160
|
});
|
|
1347
3161
|
}
|
|
1348
|
-
function
|
|
1349
|
-
return reactQuery.
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
const
|
|
1353
|
-
|
|
1354
|
-
|
|
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
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
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
|
|
1388
|
-
return reactQuery.
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
const
|
|
1392
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
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
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
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
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
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: ["
|
|
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
|
-
|
|
1460
|
-
|
|
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: ["
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
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
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
const
|
|
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
|
-
|
|
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
|
|
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: ["
|
|
1508
|
-
|
|
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
|
|
1511
|
-
|
|
3523
|
+
const stats = await CONFIG.hiveClient.call(
|
|
3524
|
+
"condenser_api",
|
|
3525
|
+
"get_ticker",
|
|
3526
|
+
[]
|
|
1512
3527
|
);
|
|
1513
|
-
const
|
|
1514
|
-
|
|
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
|
|
1517
|
-
|
|
1518
|
-
|
|
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
|
-
|
|
1523
|
-
}
|
|
3588
|
+
"Content-Type": "application/json"
|
|
3589
|
+
},
|
|
3590
|
+
body: JSON.stringify({ username: name, type: filter })
|
|
1524
3591
|
}
|
|
1525
3592
|
);
|
|
1526
|
-
|
|
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
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
}
|
|
1535
|
-
|
|
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: ["
|
|
3710
|
+
queryKey: ["search", "similar-entries", entry.author, entry.permlink, query],
|
|
1538
3711
|
queryFn: async () => {
|
|
1539
|
-
const
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
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
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
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
|
|
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: ["
|
|
3743
|
+
queryKey: ["search", "account", q, limit],
|
|
1570
3744
|
queryFn: async () => {
|
|
1571
|
-
const
|
|
1572
|
-
const response = await
|
|
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
|
-
|
|
3753
|
+
if (!response.ok) {
|
|
3754
|
+
throw new Error(`Failed to search accounts: ${response.status}`);
|
|
3755
|
+
}
|
|
3756
|
+
return response.json();
|
|
1584
3757
|
},
|
|
1585
|
-
enabled: !!
|
|
3758
|
+
enabled: !!q
|
|
1586
3759
|
});
|
|
1587
3760
|
}
|
|
1588
|
-
function
|
|
3761
|
+
function getSearchTopicsQueryOptions(q, limit = 20, random = false) {
|
|
1589
3762
|
return reactQuery.queryOptions({
|
|
1590
|
-
queryKey: ["
|
|
3763
|
+
queryKey: ["search", "topics", q],
|
|
1591
3764
|
queryFn: async () => {
|
|
1592
|
-
const
|
|
1593
|
-
|
|
1594
|
-
"
|
|
1595
|
-
{
|
|
1596
|
-
|
|
1597
|
-
|
|
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
|
|
1602
|
-
return reactQuery.
|
|
1603
|
-
queryKey: ["
|
|
1604
|
-
queryFn: async () => {
|
|
1605
|
-
const
|
|
1606
|
-
|
|
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
|
-
|
|
3807
|
+
initialPageParam: void 0,
|
|
3808
|
+
getNextPageParam: (lastPage) => lastPage?.scroll_id,
|
|
3809
|
+
enabled: !!q
|
|
1609
3810
|
});
|
|
1610
3811
|
}
|
|
1611
|
-
function
|
|
3812
|
+
function getSearchPathQueryOptions(q) {
|
|
1612
3813
|
return reactQuery.queryOptions({
|
|
1613
|
-
queryKey: ["
|
|
1614
|
-
enabled: !!username,
|
|
3814
|
+
queryKey: ["search", "path", q],
|
|
1615
3815
|
queryFn: async () => {
|
|
1616
|
-
|
|
1617
|
-
|
|
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
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
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
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
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
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
3853
|
+
staleTime: Infinity,
|
|
3854
|
+
refetchOnMount: true,
|
|
3855
|
+
enabled: !!accessToken
|
|
1668
3856
|
});
|
|
1669
3857
|
}
|
|
1670
|
-
function
|
|
3858
|
+
function getPromotePriceQueryOptions(accessToken) {
|
|
1671
3859
|
return reactQuery.queryOptions({
|
|
1672
|
-
queryKey: ["
|
|
1673
|
-
enabled,
|
|
3860
|
+
queryKey: ["promotions", "promote-price"],
|
|
1674
3861
|
queryFn: async () => {
|
|
1675
|
-
const response = await CONFIG.
|
|
1676
|
-
"
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
);
|
|
1686
|
-
|
|
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
|
|
3877
|
+
function getBoostPlusAccountPricesQueryOptions(account, accessToken) {
|
|
1691
3878
|
return reactQuery.queryOptions({
|
|
1692
|
-
queryKey: ["
|
|
1693
|
-
enabled: !!username && !!communityName,
|
|
3879
|
+
queryKey: ["promotions", "boost-plus-accounts", account],
|
|
1694
3880
|
queryFn: async () => {
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
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
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
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;
|