@ghostspeak/sdk 2.0.6 → 2.0.7
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/README.md +152 -30
- package/dist/GhostSpeakClient-CWmGaM9Q.d.ts +1007 -0
- package/dist/StakingModule-C5rzuOWb.d.ts +2526 -0
- package/dist/{agent-M74TCRON.js → agent-5YLZ7DAC.js} +4 -4
- package/dist/{agent-M74TCRON.js.map → agent-5YLZ7DAC.js.map} +1 -1
- package/dist/batch-operations-45CQFEID.js +4 -0
- package/dist/batch-operations-45CQFEID.js.map +1 -0
- package/dist/browser.d.ts +45 -554
- package/dist/browser.js +15 -842
- package/dist/browser.js.map +1 -1
- package/dist/chunk-AL3HQN73.js +754 -0
- package/dist/chunk-AL3HQN73.js.map +1 -0
- package/dist/chunk-BF3IQ35I.js +284 -0
- package/dist/chunk-BF3IQ35I.js.map +1 -0
- package/dist/chunk-BQDGRTVP.js +168 -0
- package/dist/chunk-BQDGRTVP.js.map +1 -0
- package/dist/chunk-C5CDA3WX.js +7314 -0
- package/dist/chunk-C5CDA3WX.js.map +1 -0
- package/dist/chunk-E3FD2CNY.js +1869 -0
- package/dist/chunk-E3FD2CNY.js.map +1 -0
- package/dist/{chunk-F3DZMBUA.js → chunk-G7S6B6WB.js} +327 -493
- package/dist/chunk-G7S6B6WB.js.map +1 -0
- package/dist/chunk-IHVDQ4YI.js +4231 -0
- package/dist/chunk-IHVDQ4YI.js.map +1 -0
- package/dist/chunk-JV2SWONF.js +98 -0
- package/dist/chunk-JV2SWONF.js.map +1 -0
- package/dist/chunk-KB6CKIUK.js +231 -0
- package/dist/chunk-KB6CKIUK.js.map +1 -0
- package/dist/chunk-S74EH3KD.js +7890 -0
- package/dist/chunk-S74EH3KD.js.map +1 -0
- package/dist/chunk-SFTSZ3LC.js +156 -0
- package/dist/chunk-SFTSZ3LC.js.map +1 -0
- package/dist/chunk-SKMJJ3Q6.js +125 -0
- package/dist/chunk-SKMJJ3Q6.js.map +1 -0
- package/dist/chunk-SZGFSCNU.js +3682 -0
- package/dist/chunk-SZGFSCNU.js.map +1 -0
- package/dist/chunk-TTB4OS2D.js +69 -0
- package/dist/chunk-TTB4OS2D.js.map +1 -0
- package/dist/chunk-UP2VWCW5.js +33 -0
- package/dist/{chunk-NSBPE2FW.js.map → chunk-UP2VWCW5.js.map} +1 -1
- package/dist/{chunk-UJUGGLMT.js → chunk-VQZQCHUT.js} +5 -5
- package/dist/{chunk-UJUGGLMT.js.map → chunk-VQZQCHUT.js.map} +1 -1
- package/dist/client.d.ts +5 -4
- package/dist/client.js +11 -10
- package/dist/createAgentAuthorization-ULG47ZJI.js +5 -0
- package/dist/createAgentAuthorization-ULG47ZJI.js.map +1 -0
- package/dist/credentials.js +1 -1
- package/dist/crypto.js +2 -2
- package/dist/errors.js +1 -1
- package/dist/feature-flags-B1g0DCPe.d.ts +1181 -0
- package/dist/generated-EG5USUFG.js +9 -0
- package/dist/{generated-VNLHMR6Y.js.map → generated-EG5USUFG.js.map} +1 -1
- package/dist/{ghostspeak_wasm-SB2RPJ3D.js → ghostspeak_wasm-F227HOSM.js} +3 -3
- package/dist/{ghostspeak_wasm-SB2RPJ3D.js.map → ghostspeak_wasm-F227HOSM.js.map} +1 -1
- package/dist/index.d.ts +1209 -1506
- package/dist/index.js +600 -3532
- package/dist/index.js.map +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/minimal/core-minimal.d.ts +2383 -1264
- package/dist/minimal/core-minimal.js +9 -9
- package/dist/minimal/core-minimal.js.map +1 -1
- package/dist/nacl-fast-W5BJ3KZ2.js +2229 -0
- package/dist/nacl-fast-W5BJ3KZ2.js.map +1 -0
- package/dist/pda-4KP7CURF.js +4 -0
- package/dist/pda-4KP7CURF.js.map +1 -0
- package/dist/pda-Ce7VYg4T.d.ts +25 -0
- package/dist/reputation-types-Yebf0Rm_.d.ts +1071 -0
- package/dist/revokeAuthorization-OK7E7OK3.js +5 -0
- package/dist/revokeAuthorization-OK7E7OK3.js.map +1 -0
- package/dist/signature-verification-DGxR4aYQ.d.ts +448 -0
- package/dist/types.js +1 -1
- package/dist/updateReputationWithAuth-Y4ONEVSP.js +5 -0
- package/dist/updateReputationWithAuth-Y4ONEVSP.js.map +1 -0
- package/dist/utils.d.ts +69 -203
- package/dist/utils.js +15 -153
- package/dist/utils.js.map +1 -1
- package/package.json +24 -31
- package/dist/.tsbuildinfo +0 -1
- package/dist/GhostSpeakClient-D_66Uzsf.d.ts +0 -707
- package/dist/GovernanceModule-DQYYys-H.d.ts +0 -1766
- package/dist/chunk-APCKGD23.js +0 -1328
- package/dist/chunk-APCKGD23.js.map +0 -1
- package/dist/chunk-ASQXX4IT.js +0 -572
- package/dist/chunk-ASQXX4IT.js.map +0 -1
- package/dist/chunk-COGZFWOT.js +0 -19657
- package/dist/chunk-COGZFWOT.js.map +0 -1
- package/dist/chunk-F3DZMBUA.js.map +0 -1
- package/dist/chunk-GMHIUK2R.js +0 -7526
- package/dist/chunk-GMHIUK2R.js.map +0 -1
- package/dist/chunk-IAWBZYPE.js +0 -356
- package/dist/chunk-IAWBZYPE.js.map +0 -1
- package/dist/chunk-NSBPE2FW.js +0 -15
- package/dist/chunk-OWYHJG6H.js +0 -13311
- package/dist/chunk-OWYHJG6H.js.map +0 -1
- package/dist/chunk-RDDPOFR5.js +0 -3
- package/dist/chunk-RDDPOFR5.js.map +0 -1
- package/dist/chunk-RERCHKZP.js +0 -35
- package/dist/chunk-RERCHKZP.js.map +0 -1
- package/dist/chunk-TVVGXYCI.js +0 -2887
- package/dist/chunk-TVVGXYCI.js.map +0 -1
- package/dist/chunk-ZGP5552B.js +0 -377
- package/dist/chunk-ZGP5552B.js.map +0 -1
- package/dist/chunk-ZWOYNHVK.js +0 -196
- package/dist/chunk-ZWOYNHVK.js.map +0 -1
- package/dist/dist/.tsbuildinfo +0 -1
- package/dist/elgamal-VZLWB3XK.js +0 -5
- package/dist/elgamal-VZLWB3XK.js.map +0 -1
- package/dist/feature-flags-V722ZuXO.d.ts +0 -3512
- package/dist/generated-VNLHMR6Y.js +0 -5
- package/dist/ipfs-types-BOt9ZNg4.d.ts +0 -592
- package/dist/multisigConfig-BzEhy6jy.d.ts +0 -58
- package/dist/pda-B_nS8SbD.d.ts +0 -114
- package/dist/pda-S4BFJVGE.js +0 -4
- package/dist/pda-S4BFJVGE.js.map +0 -1
- package/dist/system-addresses-BFNLEbFx.d.ts +0 -857
- package/dist/token-2022-rpc-RALH4RK7.js +0 -593
- package/dist/token-2022-rpc-RALH4RK7.js.map +0 -1
package/dist/browser.js
CHANGED
|
@@ -1,846 +1,19 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import {
|
|
3
|
-
export { AgentModule,
|
|
4
|
-
|
|
5
|
-
export { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, BadgeType, NATIVE_MINT_ADDRESS, REPUTATION_CONSTANTS, ReputationTier, TOKEN_2022_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS } from './chunk-
|
|
6
|
-
import
|
|
7
|
-
import './chunk-
|
|
8
|
-
|
|
9
|
-
import './chunk-
|
|
10
|
-
import './chunk-
|
|
1
|
+
export { GHOSTSPEAK_PROGRAM_ID, NETWORK_CONFIG } from './chunk-TTB4OS2D.js';
|
|
2
|
+
import { init_MultiSourceAggregator } from './chunk-SZGFSCNU.js';
|
|
3
|
+
export { AgentModule, CredentialModule as CredentialsModule, GovernanceModule, MultisigModule, PayAIClient, ReputationModule, StakingModule } from './chunk-SZGFSCNU.js';
|
|
4
|
+
export { deriveAgentPda, deriveUserRegistryPda } from './chunk-BF3IQ35I.js';
|
|
5
|
+
export { ASSOCIATED_TOKEN_PROGRAM_ADDRESS, BadgeType, NATIVE_MINT_ADDRESS, REPUTATION_CONSTANTS, ReputationTier, TOKEN_2022_PROGRAM_ADDRESS, TOKEN_PROGRAM_ADDRESS } from './chunk-C5CDA3WX.js';
|
|
6
|
+
import './chunk-S74EH3KD.js';
|
|
7
|
+
import './chunk-IHVDQ4YI.js';
|
|
8
|
+
import './chunk-SFTSZ3LC.js';
|
|
9
|
+
import './chunk-JV2SWONF.js';
|
|
10
|
+
import './chunk-KB6CKIUK.js';
|
|
11
|
+
import './chunk-AL3HQN73.js';
|
|
11
12
|
import './chunk-SRS2SKFS.js';
|
|
12
|
-
import './chunk-
|
|
13
|
-
import
|
|
13
|
+
import './chunk-UP2VWCW5.js';
|
|
14
|
+
import 'crypto';
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
LockupTier2[LockupTier2["OneMonth"] = 1] = "OneMonth";
|
|
18
|
-
LockupTier2[LockupTier2["ThreeMonths"] = 2] = "ThreeMonths";
|
|
19
|
-
LockupTier2[LockupTier2["SixMonths"] = 3] = "SixMonths";
|
|
20
|
-
LockupTier2[LockupTier2["OneYear"] = 4] = "OneYear";
|
|
21
|
-
LockupTier2[LockupTier2["TwoYears"] = 5] = "TwoYears";
|
|
22
|
-
return LockupTier2;
|
|
23
|
-
})(LockupTier || {});
|
|
24
|
-
var StakingModule = class extends BaseModule {
|
|
25
|
-
/**
|
|
26
|
-
* Derive staking account PDA for a user
|
|
27
|
-
* Seeds: ["staking", owner]
|
|
28
|
-
*/
|
|
29
|
-
async deriveStakingAccountPda(owner) {
|
|
30
|
-
const [pda] = await getProgramDerivedAddress({
|
|
31
|
-
programAddress: this.programId,
|
|
32
|
-
seeds: [
|
|
33
|
-
getBytesEncoder().encode(new TextEncoder().encode("staking")),
|
|
34
|
-
getAddressEncoder().encode(owner)
|
|
35
|
-
]
|
|
36
|
-
});
|
|
37
|
-
return pda;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Derive staking config PDA
|
|
41
|
-
* Seeds: ["staking_config"]
|
|
42
|
-
*/
|
|
43
|
-
async deriveStakingConfigPda() {
|
|
44
|
-
const [pda] = await getProgramDerivedAddress({
|
|
45
|
-
programAddress: this.programId,
|
|
46
|
-
seeds: [
|
|
47
|
-
getBytesEncoder().encode(new TextEncoder().encode("staking_config"))
|
|
48
|
-
]
|
|
49
|
-
});
|
|
50
|
-
return pda;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Initialize staking configuration (admin only)
|
|
54
|
-
*/
|
|
55
|
-
async initializeConfig(params) {
|
|
56
|
-
const instructionGetter = async () => {
|
|
57
|
-
return getInitializeStakingConfigInstructionAsync({
|
|
58
|
-
authority: params.signer,
|
|
59
|
-
ghostTokenMint: params.ghostTokenMint,
|
|
60
|
-
rewardsTreasury: params.rewardsTreasury,
|
|
61
|
-
baseApy: params.baseApy,
|
|
62
|
-
minStakeAmount: params.minStakeAmount,
|
|
63
|
-
maxStakeAmount: params.maxStakeAmount
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
return this.execute("initializeStakingConfig", instructionGetter, [params.signer]);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Create a staking account for a user
|
|
70
|
-
*/
|
|
71
|
-
async createStakingAccount(params) {
|
|
72
|
-
const instructionGetter = async () => {
|
|
73
|
-
return getCreateStakingAccountInstructionAsync({
|
|
74
|
-
owner: params.signer
|
|
75
|
-
});
|
|
76
|
-
};
|
|
77
|
-
return this.execute("createStakingAccount", instructionGetter, [params.signer]);
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Claim staking rewards
|
|
81
|
-
*/
|
|
82
|
-
async claimRewards(params) {
|
|
83
|
-
const instructionGetter = async () => {
|
|
84
|
-
return getClaimStakingRewardsInstructionAsync({
|
|
85
|
-
owner: params.signer,
|
|
86
|
-
ghostMint: params.ghostMint,
|
|
87
|
-
userTokenAccount: params.userTokenAccount,
|
|
88
|
-
rewardsTreasury: params.rewardsTreasury
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
return this.execute("claimStakingRewards", instructionGetter, [params.signer]);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Get staking account for a user
|
|
95
|
-
*/
|
|
96
|
-
async getStakingAccount(owner) {
|
|
97
|
-
const stakingAccountAddress = await this.deriveStakingAccountPda(owner);
|
|
98
|
-
return this.getAccount(stakingAccountAddress, "StakingAccount");
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Get staking account by address
|
|
102
|
-
*/
|
|
103
|
-
async getStakingAccountByAddress(address) {
|
|
104
|
-
return this.getAccount(address, "StakingAccount");
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Get all staking accounts
|
|
108
|
-
*/
|
|
109
|
-
async getAllStakingAccounts() {
|
|
110
|
-
return this.getProgramAccounts("StakingAccount");
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Get staking config
|
|
114
|
-
*/
|
|
115
|
-
async getStakingConfig() {
|
|
116
|
-
const configAddress = await this.deriveStakingConfigPda();
|
|
117
|
-
return this.getAccount(configAddress, "StakingConfig");
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Calculate pending rewards for a staking account
|
|
121
|
-
*/
|
|
122
|
-
calculatePendingRewards(stakingAccount, config) {
|
|
123
|
-
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
124
|
-
const timeSinceLastClaim = now - stakingAccount.lastClaimAt;
|
|
125
|
-
const baseReward = stakingAccount.stakedAmount * BigInt(config.baseApy) * timeSinceLastClaim / BigInt(365 * 24 * 60 * 60 * 1e4);
|
|
126
|
-
const tierBonus = this.getTierBonusApy(stakingAccount.lockupTier, config);
|
|
127
|
-
const bonusReward = stakingAccount.stakedAmount * BigInt(tierBonus) * timeSinceLastClaim / BigInt(365 * 24 * 60 * 60 * 1e4);
|
|
128
|
-
return baseReward + bonusReward + stakingAccount.pendingRewards;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Get tier bonus APY in basis points
|
|
132
|
-
*/
|
|
133
|
-
getTierBonusApy(tier, config) {
|
|
134
|
-
if (config.tierBonusApy && tier < config.tierBonusApy.length) {
|
|
135
|
-
return config.tierBonusApy[tier];
|
|
136
|
-
}
|
|
137
|
-
return 0;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Get lockup duration in seconds for a tier
|
|
141
|
-
*/
|
|
142
|
-
getLockupDuration(tier) {
|
|
143
|
-
const durations = {
|
|
144
|
-
[0 /* None */]: 0,
|
|
145
|
-
[1 /* OneMonth */]: 30 * 24 * 60 * 60,
|
|
146
|
-
[2 /* ThreeMonths */]: 90 * 24 * 60 * 60,
|
|
147
|
-
[3 /* SixMonths */]: 180 * 24 * 60 * 60,
|
|
148
|
-
[4 /* OneYear */]: 365 * 24 * 60 * 60,
|
|
149
|
-
[5 /* TwoYears */]: 730 * 24 * 60 * 60
|
|
150
|
-
};
|
|
151
|
-
return durations[tier] || 0;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Check if a staking account is locked
|
|
155
|
-
*/
|
|
156
|
-
isLocked(stakingAccount) {
|
|
157
|
-
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
158
|
-
return stakingAccount.lockupEndsAt > now;
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Get time remaining on lockup in seconds
|
|
162
|
-
*/
|
|
163
|
-
getLockupTimeRemaining(stakingAccount) {
|
|
164
|
-
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
165
|
-
if (stakingAccount.lockupEndsAt <= now) {
|
|
166
|
-
return 0;
|
|
167
|
-
}
|
|
168
|
-
return Number(stakingAccount.lockupEndsAt - now);
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
var DisputeResolution = /* @__PURE__ */ ((DisputeResolution2) => {
|
|
172
|
-
DisputeResolution2[DisputeResolution2["FavorComplainant"] = 0] = "FavorComplainant";
|
|
173
|
-
DisputeResolution2[DisputeResolution2["FavorRespondent"] = 1] = "FavorRespondent";
|
|
174
|
-
DisputeResolution2[DisputeResolution2["Split"] = 2] = "Split";
|
|
175
|
-
DisputeResolution2[DisputeResolution2["Dismissed"] = 3] = "Dismissed";
|
|
176
|
-
return DisputeResolution2;
|
|
177
|
-
})(DisputeResolution || {});
|
|
178
|
-
var DisputeModule = class extends BaseModule {
|
|
179
|
-
/**
|
|
180
|
-
* Derive dispute case PDA
|
|
181
|
-
* Seeds: ["dispute", transaction_address, complainant, reason]
|
|
182
|
-
*/
|
|
183
|
-
async deriveDisputePda(transactionAddress, complainant, reason) {
|
|
184
|
-
const [pda] = await getProgramDerivedAddress({
|
|
185
|
-
programAddress: this.programId,
|
|
186
|
-
seeds: [
|
|
187
|
-
getBytesEncoder().encode(new TextEncoder().encode("dispute")),
|
|
188
|
-
getAddressEncoder().encode(transactionAddress),
|
|
189
|
-
getAddressEncoder().encode(complainant),
|
|
190
|
-
getUtf8Encoder().encode(reason)
|
|
191
|
-
]
|
|
192
|
-
});
|
|
193
|
-
return pda;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Get dispute case by address
|
|
197
|
-
*/
|
|
198
|
-
async getDisputeCase(address) {
|
|
199
|
-
return this.getAccount(address, "DisputeCase");
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Get all disputes
|
|
203
|
-
*/
|
|
204
|
-
async getAllDisputes() {
|
|
205
|
-
return this.getProgramAccounts("DisputeCase");
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Get disputes by complainant
|
|
209
|
-
*/
|
|
210
|
-
async getDisputesByComplainant(complainant) {
|
|
211
|
-
const allDisputes = await this.getAllDisputes();
|
|
212
|
-
return allDisputes.filter((d) => d.data.complainant === complainant);
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Get disputes by respondent
|
|
216
|
-
*/
|
|
217
|
-
async getDisputesByRespondent(respondent) {
|
|
218
|
-
const allDisputes = await this.getAllDisputes();
|
|
219
|
-
return allDisputes.filter((d) => d.data.respondent === respondent);
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Get pending disputes (awaiting resolution)
|
|
223
|
-
*/
|
|
224
|
-
async getPendingDisputes() {
|
|
225
|
-
const allDisputes = await this.getAllDisputes();
|
|
226
|
-
return allDisputes.filter(
|
|
227
|
-
(d) => !d.data.resolvedAt || d.data.resolvedAt.__option === "None"
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Check if a dispute is resolved
|
|
232
|
-
*/
|
|
233
|
-
isResolved(dispute) {
|
|
234
|
-
return dispute.resolvedAt !== null && dispute.resolvedAt.__option !== "None";
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Get evidence count for a dispute
|
|
238
|
-
*/
|
|
239
|
-
getEvidenceCount(dispute) {
|
|
240
|
-
return dispute.evidence?.length ?? 0;
|
|
241
|
-
}
|
|
242
|
-
/**
|
|
243
|
-
* Get AI confidence score (0-100)
|
|
244
|
-
*/
|
|
245
|
-
getAiConfidence(dispute) {
|
|
246
|
-
return Math.round(dispute.aiScore * 100);
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Check if dispute requires human review
|
|
250
|
-
*/
|
|
251
|
-
requiresHumanReview(dispute) {
|
|
252
|
-
return dispute.humanReview || dispute.aiScore < 0.7;
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
// src/utils/reputation-calculator.ts
|
|
257
|
-
var ReputationCalculator = class {
|
|
258
|
-
fraudPatterns = [];
|
|
259
|
-
constructor() {
|
|
260
|
-
this.initializeFraudPatterns();
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Initialize fraud detection patterns
|
|
264
|
-
*/
|
|
265
|
-
initializeFraudPatterns() {
|
|
266
|
-
this.fraudPatterns = [
|
|
267
|
-
{
|
|
268
|
-
patternId: "sudden_spike",
|
|
269
|
-
description: "Sudden spike in reputation without corresponding activity",
|
|
270
|
-
riskScore: 80,
|
|
271
|
-
detect: (data) => {
|
|
272
|
-
if (data.performanceHistory.length < 2) return false;
|
|
273
|
-
const recent = data.performanceHistory[data.performanceHistory.length - 1];
|
|
274
|
-
const previous = data.performanceHistory[data.performanceHistory.length - 2];
|
|
275
|
-
const spike = recent.score - previous.score;
|
|
276
|
-
return spike > 2e3 && recent.jobsCompleted === previous.jobsCompleted;
|
|
277
|
-
}
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
patternId: "perfect_scores_only",
|
|
281
|
-
description: "All jobs have perfect scores (potential manipulation)",
|
|
282
|
-
riskScore: 60,
|
|
283
|
-
detect: (data) => {
|
|
284
|
-
const recentJobs = data.performanceHistory.slice(-10);
|
|
285
|
-
return recentJobs.length >= 5 && recentJobs.every((job) => job.avgQuality === 100);
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
{
|
|
289
|
-
patternId: "rapid_category_switching",
|
|
290
|
-
description: "Rapid switching between unrelated categories",
|
|
291
|
-
riskScore: 40,
|
|
292
|
-
detect: (data) => {
|
|
293
|
-
if (data.categoryReputations.length < 5) return false;
|
|
294
|
-
const recentCategories = data.categoryReputations.sort((a, b) => b.lastActivity - a.lastActivity).slice(0, 5);
|
|
295
|
-
const daysSinceOldest = (Date.now() - recentCategories[4].lastActivity) / (1e3 * 60 * 60 * 24);
|
|
296
|
-
return daysSinceOldest < 7;
|
|
297
|
-
}
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
patternId: "dispute_pattern",
|
|
301
|
-
description: "High dispute rate with suspicious resolution pattern",
|
|
302
|
-
riskScore: 70,
|
|
303
|
-
detect: (data) => {
|
|
304
|
-
if (data.totalJobsCompleted < 10) return false;
|
|
305
|
-
const disputeRate = data.disputesAgainst / data.totalJobsCompleted;
|
|
306
|
-
const resolutionRate = data.disputesResolved / Math.max(1, data.disputesAgainst);
|
|
307
|
-
return disputeRate > 0.3 && resolutionRate > 0.9;
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
{
|
|
311
|
-
patternId: "time_manipulation",
|
|
312
|
-
description: "Completion times significantly below expected",
|
|
313
|
-
riskScore: 50,
|
|
314
|
-
detect: (data, job) => {
|
|
315
|
-
return job.actualDuration < job.expectedDuration * 0.1;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
];
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Calculate reputation update based on job performance
|
|
322
|
-
*/
|
|
323
|
-
calculateReputation(currentData, jobPerformance) {
|
|
324
|
-
const decayedData = this.applyTimeDecay(currentData);
|
|
325
|
-
const jobScore = this.calculateWeightedScore(decayedData.factors, jobPerformance);
|
|
326
|
-
const categoryUpdate = this.updateCategoryReputation(
|
|
327
|
-
decayedData.categoryReputations,
|
|
328
|
-
jobPerformance,
|
|
329
|
-
jobScore
|
|
330
|
-
);
|
|
331
|
-
const overallScore = this.calculateOverallScore(categoryUpdate.categories);
|
|
332
|
-
const tier = this.getTierFromScore(overallScore);
|
|
333
|
-
const newBadges = this.checkBadgeAchievements(
|
|
334
|
-
decayedData,
|
|
335
|
-
jobPerformance,
|
|
336
|
-
overallScore
|
|
337
|
-
);
|
|
338
|
-
const fraudAnalysis = this.detectFraud(decayedData, jobPerformance);
|
|
339
|
-
return {
|
|
340
|
-
overallScore,
|
|
341
|
-
jobScore,
|
|
342
|
-
categoryScore: categoryUpdate.categoryScore,
|
|
343
|
-
tier,
|
|
344
|
-
newBadges,
|
|
345
|
-
fraudDetected: fraudAnalysis.detected,
|
|
346
|
-
fraudRiskScore: fraudAnalysis.riskScore
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Apply time-based reputation decay
|
|
351
|
-
*/
|
|
352
|
-
applyTimeDecay(data) {
|
|
353
|
-
const currentTime = Date.now() / 1e3;
|
|
354
|
-
const daysSinceUpdate = (currentTime - data.lastUpdated) / 86400;
|
|
355
|
-
if (daysSinceUpdate <= 0) return data;
|
|
356
|
-
const decayFactor = REPUTATION_CONSTANTS.REPUTATION_DECAY_RATE_BPS * daysSinceUpdate;
|
|
357
|
-
const decayMultiplier = Math.max(0, 1e4 - decayFactor) / 1e4;
|
|
358
|
-
const decayedOverallScore = Math.floor(data.overallScore * decayMultiplier);
|
|
359
|
-
const decayedCategories = data.categoryReputations.map((category) => {
|
|
360
|
-
const categoryDaysInactive = (currentTime - category.lastActivity) / 86400;
|
|
361
|
-
const categoryDecay = REPUTATION_CONSTANTS.REPUTATION_DECAY_RATE_BPS * categoryDaysInactive;
|
|
362
|
-
const categoryMultiplier = Math.max(0, 1e4 - categoryDecay) / 1e4;
|
|
363
|
-
return {
|
|
364
|
-
...category,
|
|
365
|
-
score: Math.floor(category.score * categoryMultiplier)
|
|
366
|
-
};
|
|
367
|
-
});
|
|
368
|
-
return {
|
|
369
|
-
...data,
|
|
370
|
-
overallScore: decayedOverallScore,
|
|
371
|
-
categoryReputations: decayedCategories
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
/**
|
|
375
|
-
* Calculate weighted score based on job performance
|
|
376
|
-
*/
|
|
377
|
-
calculateWeightedScore(factors, jobPerformance) {
|
|
378
|
-
const totalWeight = factors.completionWeight + factors.qualityWeight + factors.timelinessWeight + factors.satisfactionWeight + factors.disputeWeight;
|
|
379
|
-
if (totalWeight !== 100) {
|
|
380
|
-
throw new Error("Reputation factors must sum to 100");
|
|
381
|
-
}
|
|
382
|
-
const completionScore = jobPerformance.completed ? REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE : 0;
|
|
383
|
-
const qualityScore = jobPerformance.qualityRating * REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE / 100;
|
|
384
|
-
const timelinessScore = this.calculateTimelinessScore(
|
|
385
|
-
jobPerformance.expectedDuration,
|
|
386
|
-
jobPerformance.actualDuration
|
|
387
|
-
);
|
|
388
|
-
const satisfactionScore = jobPerformance.clientSatisfaction * REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE / 100;
|
|
389
|
-
const disputeScore = this.calculateDisputeScore(jobPerformance);
|
|
390
|
-
const weightedScore = (completionScore * factors.completionWeight + qualityScore * factors.qualityWeight + timelinessScore * factors.timelinessWeight + satisfactionScore * factors.satisfactionWeight + disputeScore * factors.disputeWeight) / 100;
|
|
391
|
-
return Math.min(weightedScore, REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE);
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Calculate timeliness score based on expected vs actual duration
|
|
395
|
-
*/
|
|
396
|
-
calculateTimelinessScore(expectedDuration, actualDuration) {
|
|
397
|
-
if (actualDuration <= expectedDuration) {
|
|
398
|
-
return REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE;
|
|
399
|
-
}
|
|
400
|
-
const delayRatio = (actualDuration - expectedDuration) * 1e4 / expectedDuration;
|
|
401
|
-
if (delayRatio > 5e3) {
|
|
402
|
-
return 0;
|
|
403
|
-
}
|
|
404
|
-
return REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE - REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE * delayRatio / 1e4;
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Calculate dispute score
|
|
408
|
-
*/
|
|
409
|
-
calculateDisputeScore(jobPerformance) {
|
|
410
|
-
if (!jobPerformance.hadDispute) {
|
|
411
|
-
return REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE;
|
|
412
|
-
}
|
|
413
|
-
if (jobPerformance.disputeResolvedFavorably) {
|
|
414
|
-
return REPUTATION_CONSTANTS.MAX_REPUTATION_SCORE / 2;
|
|
415
|
-
}
|
|
416
|
-
return 0;
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Update category-specific reputation
|
|
420
|
-
*/
|
|
421
|
-
updateCategoryReputation(categories, jobPerformance, jobScore) {
|
|
422
|
-
const existingCategoryIndex = categories.findIndex(
|
|
423
|
-
(c) => c.category === jobPerformance.category
|
|
424
|
-
);
|
|
425
|
-
if (existingCategoryIndex !== -1) {
|
|
426
|
-
const category = categories[existingCategoryIndex];
|
|
427
|
-
const updatedCategory = {
|
|
428
|
-
...category,
|
|
429
|
-
completedJobs: category.completedJobs + 1,
|
|
430
|
-
qualitySum: category.qualitySum + jobPerformance.qualityRating,
|
|
431
|
-
qualityCount: category.qualityCount + 1,
|
|
432
|
-
totalEarnings: category.totalEarnings + jobPerformance.paymentAmount,
|
|
433
|
-
lastActivity: Date.now() / 1e3,
|
|
434
|
-
score: Math.floor((category.score * 7 + jobScore * 3) / 10),
|
|
435
|
-
// 70% existing, 30% new
|
|
436
|
-
avgCompletionTime: Math.floor(
|
|
437
|
-
(category.avgCompletionTime * category.completedJobs + jobPerformance.actualDuration) / (category.completedJobs + 1)
|
|
438
|
-
)
|
|
439
|
-
};
|
|
440
|
-
const newCategories = [...categories];
|
|
441
|
-
newCategories[existingCategoryIndex] = updatedCategory;
|
|
442
|
-
return { categories: newCategories, categoryScore: updatedCategory.score };
|
|
443
|
-
} else {
|
|
444
|
-
if (categories.length >= REPUTATION_CONSTANTS.MAX_REPUTATION_CATEGORIES) {
|
|
445
|
-
throw new Error("Maximum reputation categories reached");
|
|
446
|
-
}
|
|
447
|
-
const newCategory = {
|
|
448
|
-
category: jobPerformance.category,
|
|
449
|
-
score: jobScore,
|
|
450
|
-
completedJobs: 1,
|
|
451
|
-
avgCompletionTime: jobPerformance.actualDuration,
|
|
452
|
-
qualitySum: jobPerformance.qualityRating,
|
|
453
|
-
qualityCount: 1,
|
|
454
|
-
lastActivity: Date.now() / 1e3,
|
|
455
|
-
totalEarnings: jobPerformance.paymentAmount
|
|
456
|
-
};
|
|
457
|
-
return {
|
|
458
|
-
categories: [...categories, newCategory],
|
|
459
|
-
categoryScore: jobScore
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
/**
|
|
464
|
-
* Calculate overall score from category reputations
|
|
465
|
-
*/
|
|
466
|
-
calculateOverallScore(categories) {
|
|
467
|
-
if (categories.length === 0) return 5e3;
|
|
468
|
-
let weightedSum = 0;
|
|
469
|
-
let totalWeight = 0;
|
|
470
|
-
for (const category of categories) {
|
|
471
|
-
const weight = category.completedJobs;
|
|
472
|
-
weightedSum += category.score * weight;
|
|
473
|
-
totalWeight += weight;
|
|
474
|
-
}
|
|
475
|
-
return totalWeight > 0 ? Math.floor(weightedSum / totalWeight) : 5e3;
|
|
476
|
-
}
|
|
477
|
-
/**
|
|
478
|
-
* Get reputation tier from score
|
|
479
|
-
*/
|
|
480
|
-
getTierFromScore(score) {
|
|
481
|
-
if (score >= REPUTATION_CONSTANTS.PLATINUM_TIER_THRESHOLD) {
|
|
482
|
-
return "Platinum" /* Platinum */;
|
|
483
|
-
} else if (score >= REPUTATION_CONSTANTS.GOLD_TIER_THRESHOLD) {
|
|
484
|
-
return "Gold" /* Gold */;
|
|
485
|
-
} else if (score >= REPUTATION_CONSTANTS.SILVER_TIER_THRESHOLD) {
|
|
486
|
-
return "Silver" /* Silver */;
|
|
487
|
-
} else if (score >= REPUTATION_CONSTANTS.BRONZE_TIER_THRESHOLD) {
|
|
488
|
-
return "Bronze" /* Bronze */;
|
|
489
|
-
} else {
|
|
490
|
-
return "None" /* None */;
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
/**
|
|
494
|
-
* Check for badge achievements
|
|
495
|
-
*/
|
|
496
|
-
checkBadgeAchievements(data, jobPerformance, newScore) {
|
|
497
|
-
const newBadges = [];
|
|
498
|
-
const existingBadges = new Set(data.badges.map((b) => b.badgeType));
|
|
499
|
-
const newTotalJobs = data.totalJobsCompleted + (jobPerformance.completed ? 1 : 0);
|
|
500
|
-
if (!existingBadges.has("FirstJob" /* FirstJob */) && newTotalJobs >= 1) {
|
|
501
|
-
newBadges.push("FirstJob" /* FirstJob */);
|
|
502
|
-
}
|
|
503
|
-
if (!existingBadges.has("TenJobs" /* TenJobs */) && newTotalJobs >= 10) {
|
|
504
|
-
newBadges.push("TenJobs" /* TenJobs */);
|
|
505
|
-
}
|
|
506
|
-
if (!existingBadges.has("HundredJobs" /* HundredJobs */) && newTotalJobs >= 100) {
|
|
507
|
-
newBadges.push("HundredJobs" /* HundredJobs */);
|
|
508
|
-
}
|
|
509
|
-
if (!existingBadges.has("ThousandJobs" /* ThousandJobs */) && newTotalJobs >= 1e3) {
|
|
510
|
-
newBadges.push("ThousandJobs" /* ThousandJobs */);
|
|
511
|
-
}
|
|
512
|
-
if (!existingBadges.has("PerfectRating" /* PerfectRating */) && newScore >= 9500) {
|
|
513
|
-
newBadges.push("PerfectRating" /* PerfectRating */);
|
|
514
|
-
}
|
|
515
|
-
if (!existingBadges.has("QuickResponder" /* QuickResponder */) && data.avgResponseTime > 0 && data.avgResponseTime < 3600) {
|
|
516
|
-
newBadges.push("QuickResponder" /* QuickResponder */);
|
|
517
|
-
}
|
|
518
|
-
if (!existingBadges.has("DisputeResolver" /* DisputeResolver */) && data.disputesResolved >= 5) {
|
|
519
|
-
newBadges.push("DisputeResolver" /* DisputeResolver */);
|
|
520
|
-
}
|
|
521
|
-
if (!existingBadges.has("CategoryExpert" /* CategoryExpert */)) {
|
|
522
|
-
const hasExpertCategory = data.categoryReputations.some((c) => c.score >= 9e3);
|
|
523
|
-
if (hasExpertCategory) {
|
|
524
|
-
newBadges.push("CategoryExpert" /* CategoryExpert */);
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
if (!existingBadges.has("CrossCategoryMaster" /* CrossCategoryMaster */) && data.categoryReputations.length >= 5) {
|
|
528
|
-
newBadges.push("CrossCategoryMaster" /* CrossCategoryMaster */);
|
|
529
|
-
}
|
|
530
|
-
return newBadges;
|
|
531
|
-
}
|
|
532
|
-
/**
|
|
533
|
-
* Detect potential fraud patterns
|
|
534
|
-
*/
|
|
535
|
-
detectFraud(data, jobPerformance) {
|
|
536
|
-
let totalRiskScore = 0;
|
|
537
|
-
const detectedPatterns = [];
|
|
538
|
-
for (const pattern of this.fraudPatterns) {
|
|
539
|
-
if (pattern.detect(data, jobPerformance)) {
|
|
540
|
-
totalRiskScore += pattern.riskScore;
|
|
541
|
-
detectedPatterns.push(pattern.patternId);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
const normalizedRiskScore = Math.min(100, totalRiskScore);
|
|
545
|
-
return {
|
|
546
|
-
detected: normalizedRiskScore >= 50,
|
|
547
|
-
// Threshold for fraud detection
|
|
548
|
-
riskScore: normalizedRiskScore,
|
|
549
|
-
patterns: detectedPatterns
|
|
550
|
-
};
|
|
551
|
-
}
|
|
552
|
-
/**
|
|
553
|
-
* Create performance snapshot
|
|
554
|
-
*/
|
|
555
|
-
createPerformanceSnapshot(data, newScore) {
|
|
556
|
-
const avgQuality = data.categoryReputations.length > 0 ? data.categoryReputations.reduce((sum, cat) => {
|
|
557
|
-
return sum + (cat.qualityCount > 0 ? cat.qualitySum / cat.qualityCount : 0);
|
|
558
|
-
}, 0) / data.categoryReputations.length : 0;
|
|
559
|
-
return {
|
|
560
|
-
timestamp: Date.now() / 1e3,
|
|
561
|
-
score: newScore,
|
|
562
|
-
jobsCompleted: data.totalJobsCompleted,
|
|
563
|
-
avgQuality: Math.floor(avgQuality)
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Calculate reputation slash amount
|
|
568
|
-
*/
|
|
569
|
-
calculateSlashAmount(currentScore, slashPercentage) {
|
|
570
|
-
if (slashPercentage > 5e3) {
|
|
571
|
-
throw new Error("Slash percentage cannot exceed 50%");
|
|
572
|
-
}
|
|
573
|
-
if (currentScore < REPUTATION_CONSTANTS.MIN_REPUTATION_FOR_SLASH) {
|
|
574
|
-
throw new Error("Reputation too low to slash");
|
|
575
|
-
}
|
|
576
|
-
const slashAmount = Math.floor(currentScore * slashPercentage / 1e4);
|
|
577
|
-
const newScore = Math.max(0, currentScore - slashAmount);
|
|
578
|
-
return { newScore, slashAmount };
|
|
579
|
-
}
|
|
580
|
-
/**
|
|
581
|
-
* Calculate staking bonus
|
|
582
|
-
*/
|
|
583
|
-
calculateStakingBonus(stakeAmount) {
|
|
584
|
-
return Math.min(500, Math.floor(stakeAmount / 1e3));
|
|
585
|
-
}
|
|
586
|
-
};
|
|
587
|
-
|
|
588
|
-
// src/modules/reputation/ReputationModule.ts
|
|
589
|
-
var ReputationModule = class extends BaseModule {
|
|
590
|
-
calculator;
|
|
591
|
-
constructor(config) {
|
|
592
|
-
super(config);
|
|
593
|
-
this.calculator = new ReputationCalculator();
|
|
594
|
-
}
|
|
595
|
-
/**
|
|
596
|
-
* Calculate reputation change for a job
|
|
597
|
-
*/
|
|
598
|
-
calculateReputationChange(currentData, jobPerformance) {
|
|
599
|
-
return this.calculator.calculateReputation(currentData, jobPerformance);
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Get tier name from tier enum
|
|
603
|
-
*/
|
|
604
|
-
getTierName(tier) {
|
|
605
|
-
switch (tier) {
|
|
606
|
-
case "None" /* None */:
|
|
607
|
-
return "Unranked";
|
|
608
|
-
case "Bronze" /* Bronze */:
|
|
609
|
-
return "Bronze";
|
|
610
|
-
case "Silver" /* Silver */:
|
|
611
|
-
return "Silver";
|
|
612
|
-
case "Gold" /* Gold */:
|
|
613
|
-
return "Gold";
|
|
614
|
-
case "Platinum" /* Platinum */:
|
|
615
|
-
return "Platinum";
|
|
616
|
-
default:
|
|
617
|
-
return "Unknown";
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* Get tier from score
|
|
622
|
-
*/
|
|
623
|
-
getTierFromScore(score) {
|
|
624
|
-
if (score >= REPUTATION_CONSTANTS.PLATINUM_TIER_THRESHOLD) {
|
|
625
|
-
return "Platinum" /* Platinum */;
|
|
626
|
-
} else if (score >= REPUTATION_CONSTANTS.GOLD_TIER_THRESHOLD) {
|
|
627
|
-
return "Gold" /* Gold */;
|
|
628
|
-
} else if (score >= REPUTATION_CONSTANTS.SILVER_TIER_THRESHOLD) {
|
|
629
|
-
return "Silver" /* Silver */;
|
|
630
|
-
} else if (score >= REPUTATION_CONSTANTS.BRONZE_TIER_THRESHOLD) {
|
|
631
|
-
return "Bronze" /* Bronze */;
|
|
632
|
-
}
|
|
633
|
-
return "None" /* None */;
|
|
634
|
-
}
|
|
635
|
-
/**
|
|
636
|
-
* Get badge display name
|
|
637
|
-
*/
|
|
638
|
-
getBadgeName(badge) {
|
|
639
|
-
switch (badge) {
|
|
640
|
-
case "FirstJob" /* FirstJob */:
|
|
641
|
-
return "First Job";
|
|
642
|
-
case "TenJobs" /* TenJobs */:
|
|
643
|
-
return "10 Jobs";
|
|
644
|
-
case "HundredJobs" /* HundredJobs */:
|
|
645
|
-
return "100 Jobs";
|
|
646
|
-
case "ThousandJobs" /* ThousandJobs */:
|
|
647
|
-
return "1000 Jobs";
|
|
648
|
-
case "PerfectRating" /* PerfectRating */:
|
|
649
|
-
return "Perfect Rating";
|
|
650
|
-
case "QuickResponder" /* QuickResponder */:
|
|
651
|
-
return "Quick Responder";
|
|
652
|
-
case "DisputeResolver" /* DisputeResolver */:
|
|
653
|
-
return "Dispute Resolver";
|
|
654
|
-
case "CategoryExpert" /* CategoryExpert */:
|
|
655
|
-
return "Category Expert";
|
|
656
|
-
case "CrossCategoryMaster" /* CrossCategoryMaster */:
|
|
657
|
-
return "Cross-Category Master";
|
|
658
|
-
default:
|
|
659
|
-
return "Unknown Badge";
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
/**
|
|
663
|
-
* Calculate estimated APY boost from reputation
|
|
664
|
-
*/
|
|
665
|
-
calculateApyBoost(score) {
|
|
666
|
-
return Math.floor(score / 1e3) * 50;
|
|
667
|
-
}
|
|
668
|
-
/**
|
|
669
|
-
* Get reputation tier color for UI
|
|
670
|
-
*/
|
|
671
|
-
getTierColor(tier) {
|
|
672
|
-
switch (tier) {
|
|
673
|
-
case "Platinum" /* Platinum */:
|
|
674
|
-
return "#E5E4E2";
|
|
675
|
-
// Platinum gray
|
|
676
|
-
case "Gold" /* Gold */:
|
|
677
|
-
return "#FFD700";
|
|
678
|
-
// Gold
|
|
679
|
-
case "Silver" /* Silver */:
|
|
680
|
-
return "#C0C0C0";
|
|
681
|
-
// Silver
|
|
682
|
-
case "Bronze" /* Bronze */:
|
|
683
|
-
return "#CD7F32";
|
|
684
|
-
// Bronze
|
|
685
|
-
default:
|
|
686
|
-
return "#808080";
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Create default reputation data for new agents
|
|
691
|
-
*/
|
|
692
|
-
createDefaultReputationData(agentAddress) {
|
|
693
|
-
return {
|
|
694
|
-
agent: agentAddress,
|
|
695
|
-
overallScore: 5e3,
|
|
696
|
-
// Start at 50%
|
|
697
|
-
totalJobsCompleted: 0,
|
|
698
|
-
totalJobsFailed: 0,
|
|
699
|
-
avgResponseTime: 0,
|
|
700
|
-
disputesAgainst: 0,
|
|
701
|
-
disputesResolved: 0,
|
|
702
|
-
lastUpdated: Math.floor(Date.now() / 1e3),
|
|
703
|
-
categoryReputations: [],
|
|
704
|
-
badges: [],
|
|
705
|
-
performanceHistory: [],
|
|
706
|
-
factors: {
|
|
707
|
-
completionWeight: 25,
|
|
708
|
-
qualityWeight: 25,
|
|
709
|
-
timelinessWeight: 20,
|
|
710
|
-
satisfactionWeight: 20,
|
|
711
|
-
disputeWeight: 10
|
|
712
|
-
}
|
|
713
|
-
};
|
|
714
|
-
}
|
|
715
|
-
/**
|
|
716
|
-
* Check if agent qualifies for a specific tier
|
|
717
|
-
*/
|
|
718
|
-
qualifiesForTier(score, tier) {
|
|
719
|
-
switch (tier) {
|
|
720
|
-
case "Platinum" /* Platinum */:
|
|
721
|
-
return score >= REPUTATION_CONSTANTS.PLATINUM_TIER_THRESHOLD;
|
|
722
|
-
case "Gold" /* Gold */:
|
|
723
|
-
return score >= REPUTATION_CONSTANTS.GOLD_TIER_THRESHOLD;
|
|
724
|
-
case "Silver" /* Silver */:
|
|
725
|
-
return score >= REPUTATION_CONSTANTS.SILVER_TIER_THRESHOLD;
|
|
726
|
-
case "Bronze" /* Bronze */:
|
|
727
|
-
return score >= REPUTATION_CONSTANTS.BRONZE_TIER_THRESHOLD;
|
|
728
|
-
default:
|
|
729
|
-
return true;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Calculate points needed for next tier
|
|
734
|
-
*/
|
|
735
|
-
pointsToNextTier(score) {
|
|
736
|
-
const currentTier = this.getTierFromScore(score);
|
|
737
|
-
switch (currentTier) {
|
|
738
|
-
case "None" /* None */:
|
|
739
|
-
return { nextTier: "Bronze" /* Bronze */, pointsNeeded: REPUTATION_CONSTANTS.BRONZE_TIER_THRESHOLD - score };
|
|
740
|
-
case "Bronze" /* Bronze */:
|
|
741
|
-
return { nextTier: "Silver" /* Silver */, pointsNeeded: REPUTATION_CONSTANTS.SILVER_TIER_THRESHOLD - score };
|
|
742
|
-
case "Silver" /* Silver */:
|
|
743
|
-
return { nextTier: "Gold" /* Gold */, pointsNeeded: REPUTATION_CONSTANTS.GOLD_TIER_THRESHOLD - score };
|
|
744
|
-
case "Gold" /* Gold */:
|
|
745
|
-
return { nextTier: "Platinum" /* Platinum */, pointsNeeded: REPUTATION_CONSTANTS.PLATINUM_TIER_THRESHOLD - score };
|
|
746
|
-
case "Platinum" /* Platinum */:
|
|
747
|
-
return null;
|
|
748
|
-
// Already at max tier
|
|
749
|
-
default:
|
|
750
|
-
return null;
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
};
|
|
754
|
-
var AuctionType = /* @__PURE__ */ ((AuctionType2) => {
|
|
755
|
-
AuctionType2[AuctionType2["English"] = 0] = "English";
|
|
756
|
-
AuctionType2[AuctionType2["Dutch"] = 1] = "Dutch";
|
|
757
|
-
AuctionType2[AuctionType2["SealedBid"] = 2] = "SealedBid";
|
|
758
|
-
return AuctionType2;
|
|
759
|
-
})(AuctionType || {});
|
|
760
|
-
var AuctionModule = class extends BaseModule {
|
|
761
|
-
/**
|
|
762
|
-
* Derive auction PDA
|
|
763
|
-
* Seeds: ["auction", creator, auction_id]
|
|
764
|
-
*/
|
|
765
|
-
async deriveAuctionPda(creator, auctionId) {
|
|
766
|
-
const [pda] = await getProgramDerivedAddress({
|
|
767
|
-
programAddress: this.programId,
|
|
768
|
-
seeds: [
|
|
769
|
-
getBytesEncoder().encode(new TextEncoder().encode("auction")),
|
|
770
|
-
getAddressEncoder().encode(creator),
|
|
771
|
-
getBytesEncoder().encode(new TextEncoder().encode(auctionId))
|
|
772
|
-
]
|
|
773
|
-
});
|
|
774
|
-
return pda;
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Get auction marketplace account
|
|
778
|
-
*/
|
|
779
|
-
async getAuctionMarketplace(address) {
|
|
780
|
-
return this.getAccount(address, "AuctionMarketplace");
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* Get all auction marketplaces
|
|
784
|
-
*/
|
|
785
|
-
async getAllAuctions() {
|
|
786
|
-
return this.getProgramAccounts("AuctionMarketplace");
|
|
787
|
-
}
|
|
788
|
-
/**
|
|
789
|
-
* Get auction by creator and ID
|
|
790
|
-
*/
|
|
791
|
-
async getAuctionByCreatorAndId(creator, auctionId) {
|
|
792
|
-
const auctionAddress = await this.deriveAuctionPda(creator, auctionId);
|
|
793
|
-
return this.getAuctionMarketplace(auctionAddress);
|
|
794
|
-
}
|
|
795
|
-
/**
|
|
796
|
-
* Calculate time remaining in auction
|
|
797
|
-
*/
|
|
798
|
-
getTimeRemaining(auction) {
|
|
799
|
-
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
800
|
-
if (auction.auctionEndTime <= now) {
|
|
801
|
-
return 0;
|
|
802
|
-
}
|
|
803
|
-
return Number(auction.auctionEndTime - now);
|
|
804
|
-
}
|
|
805
|
-
/**
|
|
806
|
-
* Check if auction has ended
|
|
807
|
-
*/
|
|
808
|
-
hasEnded(auction) {
|
|
809
|
-
return this.getTimeRemaining(auction) === 0;
|
|
810
|
-
}
|
|
811
|
-
/**
|
|
812
|
-
* Get total bid count for an auction
|
|
813
|
-
*/
|
|
814
|
-
getTotalBids(auction) {
|
|
815
|
-
return auction.totalBids;
|
|
816
|
-
}
|
|
817
|
-
/**
|
|
818
|
-
* Get auction metadata URI
|
|
819
|
-
*/
|
|
820
|
-
getMetadataUri(auction) {
|
|
821
|
-
return auction.metadataUri;
|
|
822
|
-
}
|
|
823
|
-
/**
|
|
824
|
-
* Check if reserve price was met
|
|
825
|
-
*/
|
|
826
|
-
isReserveMet(auction) {
|
|
827
|
-
return auction.reserveMet;
|
|
828
|
-
}
|
|
829
|
-
/**
|
|
830
|
-
* Get current winning price
|
|
831
|
-
*/
|
|
832
|
-
getCurrentPrice(auction) {
|
|
833
|
-
return auction.currentPrice;
|
|
834
|
-
}
|
|
835
|
-
/**
|
|
836
|
-
* Get auctions by creator
|
|
837
|
-
*/
|
|
838
|
-
async getAuctionsByCreator(creator) {
|
|
839
|
-
const allAuctions = await this.getAllAuctions();
|
|
840
|
-
return allAuctions.filter((a) => a.data.creator === creator);
|
|
841
|
-
}
|
|
842
|
-
};
|
|
843
|
-
|
|
844
|
-
export { AuctionModule, AuctionType, DisputeModule, DisputeResolution, LockupTier, ReputationModule, StakingModule };
|
|
16
|
+
// src/modules/reputation/index.ts
|
|
17
|
+
init_MultiSourceAggregator();
|
|
845
18
|
//# sourceMappingURL=browser.js.map
|
|
846
19
|
//# sourceMappingURL=browser.js.map
|