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