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