@antseed/node 0.2.117 → 0.2.119
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 +30 -0
- package/dist/discovery/display-name.d.ts +8 -0
- package/dist/discovery/display-name.d.ts.map +1 -0
- package/dist/discovery/display-name.js +17 -0
- package/dist/discovery/display-name.js.map +1 -0
- package/dist/discovery/domain-verification.d.ts.map +1 -1
- package/dist/discovery/domain-verification.js +2 -1
- package/dist/discovery/domain-verification.js.map +1 -1
- package/dist/discovery/github-verification.d.ts.map +1 -1
- package/dist/discovery/github-verification.js +5 -1
- package/dist/discovery/github-verification.js.map +1 -1
- package/dist/discovery/index.d.ts +1 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/index.js +1 -0
- package/dist/discovery/index.js.map +1 -1
- package/dist/discovery/service-catalog.d.ts +2 -1
- package/dist/discovery/service-catalog.d.ts.map +1 -1
- package/dist/discovery/service-catalog.js +2 -0
- package/dist/discovery/service-catalog.js.map +1 -1
- package/dist/discovery/verifier-capabilities.d.ts +9 -0
- package/dist/discovery/verifier-capabilities.d.ts.map +1 -0
- package/dist/discovery/verifier-capabilities.js +35 -0
- package/dist/discovery/verifier-capabilities.js.map +1 -0
- package/dist/index.d.ts +20 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -1
- package/dist/index.js.map +1 -1
- package/dist/node.d.ts +17 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +117 -82
- package/dist/node.js.map +1 -1
- package/dist/p2p/identity.js +1 -1
- package/dist/p2p/identity.js.map +1 -1
- package/dist/payments/chain-config.d.ts +53 -0
- package/dist/payments/chain-config.d.ts.map +1 -1
- package/dist/payments/chain-config.js +43 -23
- package/dist/payments/chain-config.js.map +1 -1
- package/dist/payments/contract-stack.d.ts +53 -0
- package/dist/payments/contract-stack.d.ts.map +1 -0
- package/dist/payments/contract-stack.js +97 -0
- package/dist/payments/contract-stack.js.map +1 -0
- package/dist/payments/evm/ants-token-client.d.ts +7 -0
- package/dist/payments/evm/ants-token-client.d.ts.map +1 -1
- package/dist/payments/evm/ants-token-client.js +37 -1
- package/dist/payments/evm/ants-token-client.js.map +1 -1
- package/dist/payments/evm/emissions-client.d.ts +3 -0
- package/dist/payments/evm/emissions-client.d.ts.map +1 -1
- package/dist/payments/evm/emissions-client.js +13 -0
- package/dist/payments/evm/emissions-client.js.map +1 -1
- package/dist/payments/evm/emissions-gate-client.d.ts +51 -0
- package/dist/payments/evm/emissions-gate-client.d.ts.map +1 -0
- package/dist/payments/evm/emissions-gate-client.js +55 -0
- package/dist/payments/evm/emissions-gate-client.js.map +1 -0
- package/dist/payments/evm/multicall.d.ts +22 -0
- package/dist/payments/evm/multicall.d.ts.map +1 -0
- package/dist/payments/evm/multicall.js +73 -0
- package/dist/payments/evm/multicall.js.map +1 -0
- package/dist/payments/evm/points-policy-registry-client.d.ts +21 -0
- package/dist/payments/evm/points-policy-registry-client.d.ts.map +1 -0
- package/dist/payments/evm/points-policy-registry-client.js +34 -0
- package/dist/payments/evm/points-policy-registry-client.js.map +1 -0
- package/dist/payments/evm/position-init-client.d.ts +18 -0
- package/dist/payments/evm/position-init-client.d.ts.map +1 -0
- package/dist/payments/evm/position-init-client.js +19 -0
- package/dist/payments/evm/position-init-client.js.map +1 -0
- package/dist/payments/evm/registry-client.d.ts +17 -0
- package/dist/payments/evm/registry-client.d.ts.map +1 -0
- package/dist/payments/evm/registry-client.js +24 -0
- package/dist/payments/evm/registry-client.js.map +1 -0
- package/dist/payments/evm/seller-pools-client.d.ts +95 -0
- package/dist/payments/evm/seller-pools-client.d.ts.map +1 -0
- package/dist/payments/evm/seller-pools-client.js +193 -0
- package/dist/payments/evm/seller-pools-client.js.map +1 -0
- package/dist/payments/evm/seller-pools-rewards-client.d.ts +36 -0
- package/dist/payments/evm/seller-pools-rewards-client.d.ts.map +1 -0
- package/dist/payments/evm/seller-pools-rewards-client.js +126 -0
- package/dist/payments/evm/seller-pools-rewards-client.js.map +1 -0
- package/dist/payments/evm/seller-registry-client.d.ts +28 -0
- package/dist/payments/evm/seller-registry-client.d.ts.map +1 -0
- package/dist/payments/evm/seller-registry-client.js +60 -0
- package/dist/payments/evm/seller-registry-client.js.map +1 -0
- package/dist/payments/evm/seller-rewards-pool-client.d.ts +24 -0
- package/dist/payments/evm/seller-rewards-pool-client.d.ts.map +1 -0
- package/dist/payments/evm/seller-rewards-pool-client.js +27 -0
- package/dist/payments/evm/seller-rewards-pool-client.js.map +1 -0
- package/dist/payments/evm/trust-signals-client.d.ts +54 -0
- package/dist/payments/evm/trust-signals-client.d.ts.map +1 -0
- package/dist/payments/evm/trust-signals-client.js +162 -0
- package/dist/payments/evm/trust-signals-client.js.map +1 -0
- package/dist/payments/evm/usage-accounting-client.d.ts +49 -0
- package/dist/payments/evm/usage-accounting-client.d.ts.map +1 -0
- package/dist/payments/evm/usage-accounting-client.js +82 -0
- package/dist/payments/evm/usage-accounting-client.js.map +1 -0
- package/dist/payments/evm/usage-rewards-client.d.ts +43 -0
- package/dist/payments/evm/usage-rewards-client.d.ts.map +1 -0
- package/dist/payments/evm/usage-rewards-client.js +62 -0
- package/dist/payments/evm/usage-rewards-client.js.map +1 -0
- package/dist/payments/evm/wash-trading-registry-client.d.ts +105 -0
- package/dist/payments/evm/wash-trading-registry-client.d.ts.map +1 -0
- package/dist/payments/evm/wash-trading-registry-client.js +170 -0
- package/dist/payments/evm/wash-trading-registry-client.js.map +1 -0
- package/dist/payments/generated-contract-addresses.d.ts +59 -0
- package/dist/payments/generated-contract-addresses.d.ts.map +1 -0
- package/dist/payments/generated-contract-addresses.js +60 -0
- package/dist/payments/generated-contract-addresses.js.map +1 -0
- package/dist/payments/index.d.ts +28 -0
- package/dist/payments/index.d.ts.map +1 -1
- package/dist/payments/index.js +14 -0
- package/dist/payments/index.js.map +1 -1
- package/dist/payments/reward-claims.d.ts +28 -0
- package/dist/payments/reward-claims.d.ts.map +1 -0
- package/dist/payments/reward-claims.js +67 -0
- package/dist/payments/reward-claims.js.map +1 -0
- package/dist/payments/reward-preview.d.ts +19 -0
- package/dist/payments/reward-preview.d.ts.map +1 -0
- package/dist/payments/reward-preview.js +36 -0
- package/dist/payments/reward-preview.js.map +1 -0
- package/dist/payments/seller-payment-manager.d.ts +9 -0
- package/dist/payments/seller-payment-manager.d.ts.map +1 -1
- package/dist/payments/seller-payment-manager.js +45 -0
- package/dist/payments/seller-payment-manager.js.map +1 -1
- package/dist/reputation/identity-history.d.ts +75 -0
- package/dist/reputation/identity-history.d.ts.map +1 -0
- package/dist/reputation/identity-history.js +258 -0
- package/dist/reputation/identity-history.js.map +1 -0
- package/dist/reputation/model-reputation.d.ts +3 -2
- package/dist/reputation/model-reputation.d.ts.map +1 -1
- package/dist/reputation/model-reputation.js +2 -9
- package/dist/reputation/model-reputation.js.map +1 -1
- package/dist/reputation/public-json.d.ts +9 -0
- package/dist/reputation/public-json.d.ts.map +1 -0
- package/dist/reputation/public-json.js +98 -0
- package/dist/reputation/public-json.js.map +1 -0
- package/dist/reputation/sybil-risk.d.ts +35 -0
- package/dist/reputation/sybil-risk.d.ts.map +1 -0
- package/dist/reputation/sybil-risk.js +136 -0
- package/dist/reputation/sybil-risk.js.map +1 -0
- package/dist/reputation/trust-score.d.ts +83 -0
- package/dist/reputation/trust-score.d.ts.map +1 -0
- package/dist/reputation/trust-score.js +91 -0
- package/dist/reputation/trust-score.js.map +1 -0
- package/dist/routing/default-router.d.ts +0 -1
- package/dist/routing/default-router.d.ts.map +1 -1
- package/dist/routing/default-router.js +2 -12
- package/dist/routing/default-router.js.map +1 -1
- package/dist/routing/model-route-ranking.d.ts +0 -1
- package/dist/routing/model-route-ranking.d.ts.map +1 -1
- package/dist/routing/model-route-ranking.js.map +1 -1
- package/dist/seller-request-handler.d.ts.map +1 -1
- package/dist/seller-request-handler.js +12 -0
- package/dist/seller-request-handler.js.map +1 -1
- package/dist/types/peer.d.ts +27 -18
- package/dist/types/peer.d.ts.map +1 -1
- package/dist/verification/tee-status.d.ts +35 -0
- package/dist/verification/tee-status.d.ts.map +1 -0
- package/dist/verification/tee-status.js +21 -0
- package/dist/verification/tee-status.js.map +1 -0
- package/package.json +14 -6
- package/dist/reputation/on-chain-reputation.d.ts +0 -84
- package/dist/reputation/on-chain-reputation.d.ts.map +0 -1
- package/dist/reputation/on-chain-reputation.js +0 -290
- package/dist/reputation/on-chain-reputation.js.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export declare const MISSING_CACHED_INPUT_PRICE_REPUTATION_MULTIPLIER = 0.5;
|
|
2
2
|
export type ModelReputationSource = {
|
|
3
|
+
/** Buyer-computed trust score (0-100). */
|
|
3
4
|
onChainReputationScore?: number | null;
|
|
4
|
-
|
|
5
|
+
/** Seller-reported score; only used when the buyer has not scored the peer. */
|
|
5
6
|
reputationScore?: number | null;
|
|
6
7
|
};
|
|
7
|
-
/**
|
|
8
|
+
/** The buyer's trust score when available, otherwise the seller-reported score. */
|
|
8
9
|
export declare function normalizedModelReputationScore(source: ModelReputationSource): number | null;
|
|
9
10
|
/**
|
|
10
11
|
* Apply model-specific pricing completeness to a normalized reputation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-reputation.d.ts","sourceRoot":"","sources":["../../src/reputation/model-reputation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-reputation.d.ts","sourceRoot":"","sources":["../../src/reputation/model-reputation.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gDAAgD,MAAM,CAAC;AAEpE,MAAM,MAAM,qBAAqB,GAAG;IAClC,0CAA0C;IAC1C,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,+EAA+E;IAC/E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC,CAAC;AAMF,mFAAmF;AACnF,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAE3F;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,qBAAqB,EAAE,OAAO,EAC9B,0BAA0B,EAAE,OAAO,EACnC,WAAW,UAAQ,GAClB,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,+BAA+B,CAC7C,CAAC,EAAE;IAAE,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC/D,CAAC,EAAE;IAAE,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9D,MAAM,CAGR"}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import { scoreFromTrust } from './on-chain-reputation.js';
|
|
2
1
|
export const MISSING_CACHED_INPUT_PRICE_REPUTATION_MULTIPLIER = 0.5;
|
|
3
2
|
function finiteScore(value) {
|
|
4
3
|
return typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
5
4
|
}
|
|
6
|
-
/**
|
|
5
|
+
/** The buyer's trust score when available, otherwise the seller-reported score. */
|
|
7
6
|
export function normalizedModelReputationScore(source) {
|
|
8
|
-
|
|
9
|
-
if (reputation !== null)
|
|
10
|
-
return reputation;
|
|
11
|
-
const trust = finiteScore(source.onChainTrustScore);
|
|
12
|
-
if (trust !== null)
|
|
13
|
-
return scoreFromTrust(trust);
|
|
14
|
-
return finiteScore(source.reputationScore);
|
|
7
|
+
return finiteScore(source.onChainReputationScore) ?? finiteScore(source.reputationScore);
|
|
15
8
|
}
|
|
16
9
|
/**
|
|
17
10
|
* Apply model-specific pricing completeness to a normalized reputation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-reputation.js","sourceRoot":"","sources":["../../src/reputation/model-reputation.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"model-reputation.js","sourceRoot":"","sources":["../../src/reputation/model-reputation.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gDAAgD,GAAG,GAAG,CAAC;AASpE,SAAS,WAAW,CAAC,KAAgC;IACnD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5E,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,8BAA8B,CAAC,MAA6B;IAC1E,OAAO,WAAW,CAAC,MAAM,CAAC,sBAAsB,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AAC3F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAC3C,UAAyB,EACzB,qBAA8B,EAC9B,0BAAmC,EACnC,WAAW,GAAG,KAAK;IAEnB,IAAI,UAAU,KAAK,IAAI,IAAI,WAAW;QAAE,OAAO,UAAU,CAAC;IAC1D,OAAO,0BAA0B,IAAI,CAAC,qBAAqB;QACzD,CAAC,CAAC,UAAU,GAAG,gDAAgD;QAC/D,CAAC,CAAC,UAAU,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,CAA+D,EAC/D,CAA+D;IAE/D,OAAO,CAAC,CAAC,CAAC,wBAAwB,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,wBAAwB,IAAI,CAAC,CAAC,CAAC;WACzE,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function isPublicIpv4(address: string): boolean;
|
|
2
|
+
export declare function publicHttpsUrl(value: string): URL;
|
|
3
|
+
export declare function fetchPublicJson(value: string, options?: {
|
|
4
|
+
maxBytes?: number;
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
}): Promise<unknown>;
|
|
8
|
+
export declare const fetchPublicProof: typeof fetch;
|
|
9
|
+
//# sourceMappingURL=public-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-json.d.ts","sourceRoot":"","sources":["../../src/reputation/public-json.ts"],"names":[],"mappings":"AAIA,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAOjD;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAoDpJ;AAQD,eAAO,MAAM,gBAAgB,EAAE,OAAO,KAIrC,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { lookup } from 'node:dns/promises';
|
|
2
|
+
import { request } from 'node:https';
|
|
3
|
+
import { isIP } from 'node:net';
|
|
4
|
+
export function isPublicIpv4(address) {
|
|
5
|
+
if (isIP(address) !== 4)
|
|
6
|
+
return false;
|
|
7
|
+
const [first = 0, second = 0] = address.split('.').map(Number);
|
|
8
|
+
return !(first === 0 || first === 10 || first === 127 || first >= 224
|
|
9
|
+
|| (first === 100 && second >= 64 && second <= 127)
|
|
10
|
+
|| (first === 169 && second === 254) || (first === 172 && second >= 16 && second <= 31)
|
|
11
|
+
|| (first === 192 && [0, 2, 168].includes(second))
|
|
12
|
+
|| (first === 198 && [18, 19, 51].includes(second)) || (first === 203 && second === 0));
|
|
13
|
+
}
|
|
14
|
+
export function publicHttpsUrl(value) {
|
|
15
|
+
const url = new URL(value);
|
|
16
|
+
if (url.protocol !== 'https:' || url.username || url.password || url.port || isIP(url.hostname)
|
|
17
|
+
|| !/^[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$/i.test(url.hostname) || !url.hostname.includes('.')) {
|
|
18
|
+
throw new Error('Public HTTPS hostname required');
|
|
19
|
+
}
|
|
20
|
+
return url;
|
|
21
|
+
}
|
|
22
|
+
export async function fetchPublicJson(value, options = {}) {
|
|
23
|
+
const url = publicHttpsUrl(value);
|
|
24
|
+
const controller = new AbortController();
|
|
25
|
+
const abort = () => controller.abort();
|
|
26
|
+
options.signal?.addEventListener('abort', abort, { once: true });
|
|
27
|
+
if (options.signal?.aborted)
|
|
28
|
+
controller.abort();
|
|
29
|
+
const timeout = setTimeout(abort, options.timeoutMs ?? 8_000);
|
|
30
|
+
try {
|
|
31
|
+
return await new Promise((resolve, reject) => {
|
|
32
|
+
if (controller.signal.aborted) {
|
|
33
|
+
reject(new Error('Public data request aborted'));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
controller.signal.addEventListener('abort', () => reject(new Error('Public data request timed out')), { once: true });
|
|
37
|
+
void lookup(url.hostname, { all: true, family: 4 }).then((addresses) => {
|
|
38
|
+
if (controller.signal.aborted)
|
|
39
|
+
return;
|
|
40
|
+
if (!addresses.length || addresses.some(({ address }) => !isPublicIpv4(address))) {
|
|
41
|
+
throw new Error('Non-public DNS address');
|
|
42
|
+
}
|
|
43
|
+
const address = addresses[0].address;
|
|
44
|
+
const req = request(url, {
|
|
45
|
+
signal: controller.signal,
|
|
46
|
+
family: 4,
|
|
47
|
+
headers: { accept: 'application/json', 'user-agent': 'AntSeed-public-history/1', 'accept-encoding': 'identity' },
|
|
48
|
+
lookup: (_hostname, _options, callback) => callback(null, address, 4),
|
|
49
|
+
}, (response) => {
|
|
50
|
+
if (response.statusCode !== 200 || (response.headers['content-encoding'] && response.headers['content-encoding'] !== 'identity')) {
|
|
51
|
+
response.destroy();
|
|
52
|
+
reject(new Error(`Public data HTTP ${response.statusCode}`));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const chunks = [];
|
|
56
|
+
let bytes = 0;
|
|
57
|
+
response.on('data', (chunk) => {
|
|
58
|
+
bytes += chunk.length;
|
|
59
|
+
if (bytes > (options.maxBytes ?? 2_000_000)) {
|
|
60
|
+
response.destroy(new Error('Public data response too large'));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
chunks.push(chunk);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
response.on('error', reject);
|
|
67
|
+
response.on('end', () => {
|
|
68
|
+
try {
|
|
69
|
+
resolve(JSON.parse(Buffer.concat(chunks).toString('utf8')));
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
reject(error);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
req.on('error', reject);
|
|
77
|
+
req.end();
|
|
78
|
+
}).catch(reject);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
clearTimeout(timeout);
|
|
83
|
+
options.signal?.removeEventListener('abort', abort);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function requestUrl(input) {
|
|
87
|
+
if (typeof input === 'string')
|
|
88
|
+
return input;
|
|
89
|
+
if (input instanceof URL)
|
|
90
|
+
return input.href;
|
|
91
|
+
return input.url;
|
|
92
|
+
}
|
|
93
|
+
export const fetchPublicProof = async (input, init) => {
|
|
94
|
+
const url = requestUrl(input);
|
|
95
|
+
const data = await fetchPublicJson(url, { maxBytes: 16_384, signal: init?.signal ?? undefined });
|
|
96
|
+
return new Response(JSON.stringify(data), { headers: { 'content-type': 'application/json' } });
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=public-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-json.js","sourceRoot":"","sources":["../../src/reputation/public-json.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PeerInfo } from '../types/peer.js';
|
|
2
|
+
/**
|
|
3
|
+
* Local wash-trading / sybil heuristic, display-only.
|
|
4
|
+
*
|
|
5
|
+
* Flags peers whose lifetime `AntseedChannels` stats look like self-dealing
|
|
6
|
+
* (many tiny channels, exclusive custom services burned through quickly,
|
|
7
|
+
* very young accounts with high channel counts). The authoritative signal is
|
|
8
|
+
* `AntseedWashTradingRegistry`, which feeds the trust score; this heuristic
|
|
9
|
+
* only surfaces an early warning in the CLI and desktop.
|
|
10
|
+
*/
|
|
11
|
+
export declare const SYBIL_WEIGHT_SUBFLOOR_TICKET = 0.3;
|
|
12
|
+
export declare const SYBIL_WEIGHT_BURN_RATE = 0.25;
|
|
13
|
+
export declare const SYBIL_WEIGHT_NARROW_CUSTOM = 0.25;
|
|
14
|
+
export declare const SYBIL_WEIGHT_YOUNG_HIGH_VOL = 0.2;
|
|
15
|
+
export declare const SYBIL_SUBFLOOR_TICKET_USDC = 1;
|
|
16
|
+
export declare const SYBIL_SUBFLOOR_MIN_CHANNELS = 50;
|
|
17
|
+
export declare const SYBIL_BURN_RATE_THRESHOLD = 30;
|
|
18
|
+
export declare const SYBIL_BURN_RATE_SATURATION = 80;
|
|
19
|
+
export declare const SYBIL_YOUNG_MAX_DAYS = 14;
|
|
20
|
+
export declare const SYBIL_YOUNG_CHANNEL_FLOOR = 100;
|
|
21
|
+
export declare const SYBIL_YOUNG_CHANNEL_SATURATION = 400;
|
|
22
|
+
export declare const SYBIL_ADVERTISED_CHEAP_INPUT_USD_PER_MILLION = 0.1;
|
|
23
|
+
export type SybilFlag = 'subfloor_ticket' | 'burn_rate' | 'narrow_custom' | 'young_high_vol';
|
|
24
|
+
export interface SybilRiskResult {
|
|
25
|
+
risk: number;
|
|
26
|
+
flags: SybilFlag[];
|
|
27
|
+
signals: Record<SybilFlag, number>;
|
|
28
|
+
}
|
|
29
|
+
export interface SybilContext {
|
|
30
|
+
serviceCounts: Map<string, number>;
|
|
31
|
+
}
|
|
32
|
+
export declare function buildSybilContext(peers: ReadonlyArray<PeerInfo>): SybilContext;
|
|
33
|
+
/** Heuristic wash-trading risk in [0, 1]. */
|
|
34
|
+
export declare function computeOnChainSybilRisk(peer: PeerInfo, ctx: SybilContext, nowMs?: number): SybilRiskResult;
|
|
35
|
+
//# sourceMappingURL=sybil-risk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sybil-risk.d.ts","sourceRoot":"","sources":["../../src/reputation/sybil-risk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;;;;;GAQG;AAEH,eAAO,MAAM,4BAA4B,MAAO,CAAC;AACjD,eAAO,MAAM,sBAAsB,OAAa,CAAC;AACjD,eAAO,MAAM,0BAA0B,OAAS,CAAC;AACjD,eAAO,MAAM,2BAA2B,MAAQ,CAAC;AAEjD,eAAO,MAAM,0BAA0B,IAAM,CAAC;AAC9C,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAElD,eAAO,MAAM,4CAA4C,MAAO,CAAC;AAEjE,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,WAAW,GACX,eAAe,GACf,gBAAgB,CAAC;AAErB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAkDD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,YAAY,CAQ9E;AAED,6CAA6C;AAC7C,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,YAAY,EACjB,KAAK,GAAE,MAAmB,GACzB,eAAe,CA6EjB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local wash-trading / sybil heuristic, display-only.
|
|
3
|
+
*
|
|
4
|
+
* Flags peers whose lifetime `AntseedChannels` stats look like self-dealing
|
|
5
|
+
* (many tiny channels, exclusive custom services burned through quickly,
|
|
6
|
+
* very young accounts with high channel counts). The authoritative signal is
|
|
7
|
+
* `AntseedWashTradingRegistry`, which feeds the trust score; this heuristic
|
|
8
|
+
* only surfaces an early warning in the CLI and desktop.
|
|
9
|
+
*/
|
|
10
|
+
export const SYBIL_WEIGHT_SUBFLOOR_TICKET = 0.30;
|
|
11
|
+
export const SYBIL_WEIGHT_BURN_RATE = 0.25;
|
|
12
|
+
export const SYBIL_WEIGHT_NARROW_CUSTOM = 0.25;
|
|
13
|
+
export const SYBIL_WEIGHT_YOUNG_HIGH_VOL = 0.20;
|
|
14
|
+
export const SYBIL_SUBFLOOR_TICKET_USDC = 1.0;
|
|
15
|
+
export const SYBIL_SUBFLOOR_MIN_CHANNELS = 50;
|
|
16
|
+
export const SYBIL_BURN_RATE_THRESHOLD = 30;
|
|
17
|
+
export const SYBIL_BURN_RATE_SATURATION = 80;
|
|
18
|
+
export const SYBIL_YOUNG_MAX_DAYS = 14;
|
|
19
|
+
export const SYBIL_YOUNG_CHANNEL_FLOOR = 100;
|
|
20
|
+
export const SYBIL_YOUNG_CHANNEL_SATURATION = 400;
|
|
21
|
+
export const SYBIL_ADVERTISED_CHEAP_INPUT_USD_PER_MILLION = 0.10;
|
|
22
|
+
function clamp(value, lo, hi) {
|
|
23
|
+
if (!Number.isFinite(value))
|
|
24
|
+
return lo;
|
|
25
|
+
if (value <= lo)
|
|
26
|
+
return lo;
|
|
27
|
+
if (value >= hi)
|
|
28
|
+
return hi;
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
function nonNegativeFinite(value) {
|
|
32
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : null;
|
|
33
|
+
}
|
|
34
|
+
function collectPeerServices(peer) {
|
|
35
|
+
const out = new Set();
|
|
36
|
+
const pricing = peer.providerPricing;
|
|
37
|
+
if (!pricing)
|
|
38
|
+
return [];
|
|
39
|
+
for (const entry of Object.values(pricing)) {
|
|
40
|
+
if (entry.services) {
|
|
41
|
+
for (const name of Object.keys(entry.services)) {
|
|
42
|
+
const trimmed = name.trim();
|
|
43
|
+
if (trimmed.length > 0)
|
|
44
|
+
out.add(trimmed);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return Array.from(out);
|
|
49
|
+
}
|
|
50
|
+
function minAdvertisedInputUsdPerMillion(peer) {
|
|
51
|
+
let best = null;
|
|
52
|
+
const consider = (value) => {
|
|
53
|
+
if (typeof value === 'number' && Number.isFinite(value) && value >= 0) {
|
|
54
|
+
if (best === null || value < best)
|
|
55
|
+
best = value;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const pricing = peer.providerPricing;
|
|
59
|
+
if (pricing) {
|
|
60
|
+
for (const entry of Object.values(pricing)) {
|
|
61
|
+
consider(entry.defaults?.inputUsdPerMillion);
|
|
62
|
+
if (entry.services) {
|
|
63
|
+
for (const s of Object.values(entry.services)) {
|
|
64
|
+
consider(s.inputUsdPerMillion);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
consider(peer.defaultInputUsdPerMillion);
|
|
70
|
+
return best;
|
|
71
|
+
}
|
|
72
|
+
export function buildSybilContext(peers) {
|
|
73
|
+
const serviceCounts = new Map();
|
|
74
|
+
for (const peer of peers) {
|
|
75
|
+
for (const name of collectPeerServices(peer)) {
|
|
76
|
+
serviceCounts.set(name, (serviceCounts.get(name) ?? 0) + 1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { serviceCounts };
|
|
80
|
+
}
|
|
81
|
+
/** Heuristic wash-trading risk in [0, 1]. */
|
|
82
|
+
export function computeOnChainSybilRisk(peer, ctx, nowMs = Date.now()) {
|
|
83
|
+
const channels = nonNegativeFinite(peer.onChainChannelCount) ?? 0;
|
|
84
|
+
const volumeUsdc = (nonNegativeFinite(peer.onChainTotalVolumeUsdcMicros) ?? 0) / 1_000_000;
|
|
85
|
+
const avgChannelUsdc = channels > 0 ? volumeUsdc / channels : 0;
|
|
86
|
+
const stakedAtSec = nonNegativeFinite(peer.onChainStakedAtSec);
|
|
87
|
+
const daysSinceStaked = stakedAtSec && stakedAtSec > 0
|
|
88
|
+
? Math.max(0, (nowMs - stakedAtSec * 1000) / 86_400_000)
|
|
89
|
+
: null;
|
|
90
|
+
const channelsPerDay = daysSinceStaked !== null && daysSinceStaked > 0
|
|
91
|
+
? channels / daysSinceStaked
|
|
92
|
+
: null;
|
|
93
|
+
const services = collectPeerServices(peer);
|
|
94
|
+
const advertisedInput = minAdvertisedInputUsdPerMillion(peer);
|
|
95
|
+
let narrowCustom = 0;
|
|
96
|
+
if (services.length > 0 && services.length <= 2) {
|
|
97
|
+
const allExclusive = services.every((s) => (ctx.serviceCounts.get(s) ?? 0) <= 1);
|
|
98
|
+
if (allExclusive)
|
|
99
|
+
narrowCustom = services.length === 1 ? 1.0 : 0.5;
|
|
100
|
+
}
|
|
101
|
+
let burnRate = 0;
|
|
102
|
+
if (narrowCustom > 0 && channelsPerDay !== null) {
|
|
103
|
+
burnRate = clamp((channelsPerDay - SYBIL_BURN_RATE_THRESHOLD)
|
|
104
|
+
/ (SYBIL_BURN_RATE_SATURATION - SYBIL_BURN_RATE_THRESHOLD), 0, 1);
|
|
105
|
+
}
|
|
106
|
+
let subfloorTicket = 0;
|
|
107
|
+
const advertisedCheap = advertisedInput != null
|
|
108
|
+
&& advertisedInput <= SYBIL_ADVERTISED_CHEAP_INPUT_USD_PER_MILLION;
|
|
109
|
+
if (!advertisedCheap && channels >= SYBIL_SUBFLOOR_MIN_CHANNELS && avgChannelUsdc < SYBIL_SUBFLOOR_TICKET_USDC) {
|
|
110
|
+
subfloorTicket = clamp((SYBIL_SUBFLOOR_TICKET_USDC - avgChannelUsdc) / SYBIL_SUBFLOOR_TICKET_USDC, 0, 1);
|
|
111
|
+
}
|
|
112
|
+
let youngHighVol = 0;
|
|
113
|
+
if (daysSinceStaked !== null
|
|
114
|
+
&& daysSinceStaked < SYBIL_YOUNG_MAX_DAYS
|
|
115
|
+
&& channels > SYBIL_YOUNG_CHANNEL_FLOOR) {
|
|
116
|
+
const ageComponent = clamp((SYBIL_YOUNG_MAX_DAYS - daysSinceStaked) / SYBIL_YOUNG_MAX_DAYS, 0, 1);
|
|
117
|
+
const volComponent = clamp((channels - SYBIL_YOUNG_CHANNEL_FLOOR)
|
|
118
|
+
/ (SYBIL_YOUNG_CHANNEL_SATURATION - SYBIL_YOUNG_CHANNEL_FLOOR), 0, 0.5);
|
|
119
|
+
youngHighVol = Math.min(1, ageComponent + volComponent);
|
|
120
|
+
}
|
|
121
|
+
const signals = {
|
|
122
|
+
subfloor_ticket: subfloorTicket,
|
|
123
|
+
burn_rate: burnRate,
|
|
124
|
+
narrow_custom: narrowCustom,
|
|
125
|
+
young_high_vol: youngHighVol,
|
|
126
|
+
};
|
|
127
|
+
const risk = Math.min(1, SYBIL_WEIGHT_SUBFLOOR_TICKET * subfloorTicket
|
|
128
|
+
+ SYBIL_WEIGHT_BURN_RATE * burnRate
|
|
129
|
+
+ SYBIL_WEIGHT_NARROW_CUSTOM * narrowCustom
|
|
130
|
+
+ SYBIL_WEIGHT_YOUNG_HIGH_VOL * youngHighVol);
|
|
131
|
+
const flags = Object.keys(signals)
|
|
132
|
+
.filter((k) => signals[k] > 0.05)
|
|
133
|
+
.sort((a, b) => signals[b] - signals[a]);
|
|
134
|
+
return { risk, flags, signals };
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=sybil-risk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sybil-risk.js","sourceRoot":"","sources":["../../src/reputation/sybil-risk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { PeerInfo } from '../types/peer.js';
|
|
2
|
+
/**
|
|
3
|
+
* Buyer-side trust score, 0-100: a weighted sum of independent parts.
|
|
4
|
+
*
|
|
5
|
+
* trust = washFlagged ? 0 : history + usage + power + identity
|
|
6
|
+
*
|
|
7
|
+
* Each part is a 0-1 value times its weight from `TRUST_WEIGHTS`:
|
|
8
|
+
*
|
|
9
|
+
* - history (60): settled service history from `AntseedChannels`, combining
|
|
10
|
+
* channel count and USDC volume on bounded log curves.
|
|
11
|
+
* - usage (15): the seller pool's share of all pools' recognized-usage points
|
|
12
|
+
* in the last complete weekly epoch (`AntseedUsageAccounting`).
|
|
13
|
+
* Points only accrue for sellers with a pool and already pass
|
|
14
|
+
* the on-chain points policies.
|
|
15
|
+
* - power (5): the pool's share of all pools' lock-weighted staking power in
|
|
16
|
+
* the current epoch (`AntseedSellerPools`): what a buyer's spend
|
|
17
|
+
* with this seller earns this week.
|
|
18
|
+
* - identity (20): public history of a verified identity (GitHub portfolio or
|
|
19
|
+
* domain registration age, see `identity-history.ts`).
|
|
20
|
+
* - wash: a seller flagged by `AntseedWashTradingRegistry` scores 0.
|
|
21
|
+
*
|
|
22
|
+
* Shares are unitless and self-normalizing, mapped through `shareCurve`, a log
|
|
23
|
+
* curve with a 1000x range (100% → 1, 10% → 0.67, 1% → 0.35). Weights sum to
|
|
24
|
+
* 100; a future model-verification (KBF) part takes its share from this table.
|
|
25
|
+
*
|
|
26
|
+
* Nothing else feeds the number. Failure streaks, cooldowns, price limits and
|
|
27
|
+
* allow/block lists stay separate router rules.
|
|
28
|
+
*/
|
|
29
|
+
/** Maximum contribution of each part; the weights sum to 100. */
|
|
30
|
+
export declare const TRUST_WEIGHTS: {
|
|
31
|
+
readonly history: 60;
|
|
32
|
+
readonly usage: 15;
|
|
33
|
+
readonly power: 5;
|
|
34
|
+
readonly identity: 20;
|
|
35
|
+
};
|
|
36
|
+
/** Settled sessions needed to saturate the channel-count half of service history. */
|
|
37
|
+
export declare const TRUST_HISTORY_CHANNEL_TARGET = 100;
|
|
38
|
+
/** Settled volume needed to saturate the volume half of service history. */
|
|
39
|
+
export declare const TRUST_HISTORY_VOLUME_USDC_MICROS_TARGET = 100000000;
|
|
40
|
+
/** Dynamic range of the share curve: a share of 1/SHARE_CURVE_RANGE maps to ~0. */
|
|
41
|
+
export declare const SHARE_CURVE_RANGE = 1000;
|
|
42
|
+
export interface TrustBreakdown {
|
|
43
|
+
/** Final trust score, 0-100. */
|
|
44
|
+
score: number;
|
|
45
|
+
/** Settled service history, weighted 0-60; `null` when channel stats are unavailable. */
|
|
46
|
+
history: {
|
|
47
|
+
score: number;
|
|
48
|
+
channelCount: number;
|
|
49
|
+
totalVolumeUsdcMicros: number;
|
|
50
|
+
} | null;
|
|
51
|
+
/** Last epoch's usage-points share, weighted 0-15; `null` when usage accounting data is unavailable. */
|
|
52
|
+
usage: {
|
|
53
|
+
score: number;
|
|
54
|
+
shareBps: number;
|
|
55
|
+
epoch: number;
|
|
56
|
+
} | null;
|
|
57
|
+
/** Current epoch's staking-power share, weighted 0-5; `null` when pool data is unavailable. */
|
|
58
|
+
power: {
|
|
59
|
+
score: number;
|
|
60
|
+
shareBps: number;
|
|
61
|
+
epoch: number;
|
|
62
|
+
} | null;
|
|
63
|
+
/** Verified-identity part, weighted 0-20; `null` when no verified identity has usable history. */
|
|
64
|
+
identity: {
|
|
65
|
+
score: number;
|
|
66
|
+
kind: 'github' | 'domain';
|
|
67
|
+
claim: string;
|
|
68
|
+
} | null;
|
|
69
|
+
/** Wash-trading registry verdict; `null` when the registry is unavailable. */
|
|
70
|
+
washFlagged: boolean | null;
|
|
71
|
+
}
|
|
72
|
+
/** `log10(1 + (SHARE_CURVE_RANGE - 1) · share) / log10(SHARE_CURVE_RANGE)` in 0-1, share in basis points. */
|
|
73
|
+
export declare function shareCurve(shareBps: number): number;
|
|
74
|
+
/** Bounded logarithmic progress toward a non-zero service-history target. */
|
|
75
|
+
export declare function historyCurve(value: number, target: number): number;
|
|
76
|
+
/**
|
|
77
|
+
* Compute the trust breakdown, or `null` when nothing about the peer is known
|
|
78
|
+
* (no pool/usage read, no verified identity history, no registry read).
|
|
79
|
+
*/
|
|
80
|
+
export declare function computeTrustScore(peer: PeerInfo, nowMs?: number): TrustBreakdown | null;
|
|
81
|
+
/** Trust score alone, or `null` when the peer is unscored. */
|
|
82
|
+
export declare function trustScore(peer: PeerInfo, nowMs?: number): number | null;
|
|
83
|
+
//# sourceMappingURL=trust-score.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-score.d.ts","sourceRoot":"","sources":["../../src/reputation/trust-score.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,iEAAiE;AACjE,eAAO,MAAM,aAAa;;;;;CAA8D,CAAC;AAEzF,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD,4EAA4E;AAC5E,eAAO,MAAM,uCAAuC,YAAc,CAAC;AAEnE,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,OAAQ,CAAC;AAEvC,MAAM,WAAW,cAAc;IAC7B,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,yFAAyF;IACzF,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,qBAAqB,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACvF,wGAAwG;IACxG,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,+FAA+F;IAC/F,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,kGAAkG;IAClG,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E,8EAA8E;IAC9E,WAAW,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7B;AAMD,6GAA6G;AAC7G,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAGlE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,SAAa,GAAG,cAAc,GAAG,IAAI,CAwC3F;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,SAAa,GAAG,MAAM,GAAG,IAAI,CAE5E"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { IDENTITY_GITHUB_MAX_POINTS as IDENTITY_MAX_POINTS, scoreIdentityHistory } from './identity-history.js';
|
|
2
|
+
/**
|
|
3
|
+
* Buyer-side trust score, 0-100: a weighted sum of independent parts.
|
|
4
|
+
*
|
|
5
|
+
* trust = washFlagged ? 0 : history + usage + power + identity
|
|
6
|
+
*
|
|
7
|
+
* Each part is a 0-1 value times its weight from `TRUST_WEIGHTS`:
|
|
8
|
+
*
|
|
9
|
+
* - history (60): settled service history from `AntseedChannels`, combining
|
|
10
|
+
* channel count and USDC volume on bounded log curves.
|
|
11
|
+
* - usage (15): the seller pool's share of all pools' recognized-usage points
|
|
12
|
+
* in the last complete weekly epoch (`AntseedUsageAccounting`).
|
|
13
|
+
* Points only accrue for sellers with a pool and already pass
|
|
14
|
+
* the on-chain points policies.
|
|
15
|
+
* - power (5): the pool's share of all pools' lock-weighted staking power in
|
|
16
|
+
* the current epoch (`AntseedSellerPools`): what a buyer's spend
|
|
17
|
+
* with this seller earns this week.
|
|
18
|
+
* - identity (20): public history of a verified identity (GitHub portfolio or
|
|
19
|
+
* domain registration age, see `identity-history.ts`).
|
|
20
|
+
* - wash: a seller flagged by `AntseedWashTradingRegistry` scores 0.
|
|
21
|
+
*
|
|
22
|
+
* Shares are unitless and self-normalizing, mapped through `shareCurve`, a log
|
|
23
|
+
* curve with a 1000x range (100% → 1, 10% → 0.67, 1% → 0.35). Weights sum to
|
|
24
|
+
* 100; a future model-verification (KBF) part takes its share from this table.
|
|
25
|
+
*
|
|
26
|
+
* Nothing else feeds the number. Failure streaks, cooldowns, price limits and
|
|
27
|
+
* allow/block lists stay separate router rules.
|
|
28
|
+
*/
|
|
29
|
+
/** Maximum contribution of each part; the weights sum to 100. */
|
|
30
|
+
export const TRUST_WEIGHTS = { history: 60, usage: 15, power: 5, identity: 20 };
|
|
31
|
+
/** Settled sessions needed to saturate the channel-count half of service history. */
|
|
32
|
+
export const TRUST_HISTORY_CHANNEL_TARGET = 100;
|
|
33
|
+
/** Settled volume needed to saturate the volume half of service history. */
|
|
34
|
+
export const TRUST_HISTORY_VOLUME_USDC_MICROS_TARGET = 100_000_000;
|
|
35
|
+
/** Dynamic range of the share curve: a share of 1/SHARE_CURVE_RANGE maps to ~0. */
|
|
36
|
+
export const SHARE_CURVE_RANGE = 1_000;
|
|
37
|
+
function finite(value) {
|
|
38
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : null;
|
|
39
|
+
}
|
|
40
|
+
/** `log10(1 + (SHARE_CURVE_RANGE - 1) · share) / log10(SHARE_CURVE_RANGE)` in 0-1, share in basis points. */
|
|
41
|
+
export function shareCurve(shareBps) {
|
|
42
|
+
if (!Number.isFinite(shareBps) || shareBps <= 0)
|
|
43
|
+
return 0;
|
|
44
|
+
const share = Math.min(1, shareBps / 10_000);
|
|
45
|
+
return Math.log10(1 + (SHARE_CURVE_RANGE - 1) * share) / Math.log10(SHARE_CURVE_RANGE);
|
|
46
|
+
}
|
|
47
|
+
/** Bounded logarithmic progress toward a non-zero service-history target. */
|
|
48
|
+
export function historyCurve(value, target) {
|
|
49
|
+
if (!Number.isFinite(value) || value <= 0 || !Number.isFinite(target) || target <= 0)
|
|
50
|
+
return 0;
|
|
51
|
+
return Math.min(1, Math.log10(1 + value) / Math.log10(1 + target));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Compute the trust breakdown, or `null` when nothing about the peer is known
|
|
55
|
+
* (no pool/usage read, no verified identity history, no registry read).
|
|
56
|
+
*/
|
|
57
|
+
export function computeTrustScore(peer, nowMs = Date.now()) {
|
|
58
|
+
const channelCount = finite(peer.onChainChannelCount);
|
|
59
|
+
const totalVolumeUsdcMicros = finite(peer.onChainTotalVolumeUsdcMicros);
|
|
60
|
+
const history = channelCount !== null && totalVolumeUsdcMicros !== null
|
|
61
|
+
? {
|
|
62
|
+
score: TRUST_WEIGHTS.history * (historyCurve(channelCount, TRUST_HISTORY_CHANNEL_TARGET)
|
|
63
|
+
+ historyCurve(totalVolumeUsdcMicros / 1_000_000, TRUST_HISTORY_VOLUME_USDC_MICROS_TARGET / 1_000_000)) / 2,
|
|
64
|
+
channelCount,
|
|
65
|
+
totalVolumeUsdcMicros,
|
|
66
|
+
}
|
|
67
|
+
: null;
|
|
68
|
+
const epoch = finite(peer.onChainUsageEpoch);
|
|
69
|
+
const usageShare = finite(peer.onChainUsageShareBps);
|
|
70
|
+
const usage = epoch !== null && usageShare !== null && epoch > 0
|
|
71
|
+
? { score: TRUST_WEIGHTS.usage * shareCurve(usageShare), shareBps: usageShare, epoch: epoch - 1 }
|
|
72
|
+
: null;
|
|
73
|
+
const powerShare = finite(peer.onChainPoolPowerShareBps);
|
|
74
|
+
const power = epoch !== null && powerShare !== null
|
|
75
|
+
? { score: TRUST_WEIGHTS.power * shareCurve(powerShare), shareBps: powerShare, epoch }
|
|
76
|
+
: null;
|
|
77
|
+
const identityHistory = scoreIdentityHistory(peer, nowMs);
|
|
78
|
+
const identity = identityHistory
|
|
79
|
+
? { score: TRUST_WEIGHTS.identity * identityHistory.points / IDENTITY_MAX_POINTS, kind: identityHistory.kind, claim: identityHistory.claim }
|
|
80
|
+
: null;
|
|
81
|
+
const washFlagged = typeof peer.onChainWashFlagged === 'boolean' ? peer.onChainWashFlagged : null;
|
|
82
|
+
if (history === null && usage === null && power === null && identity === null && washFlagged === null)
|
|
83
|
+
return null;
|
|
84
|
+
const score = washFlagged ? 0 : Math.min(100, (history?.score ?? 0) + (usage?.score ?? 0) + (power?.score ?? 0) + (identity?.score ?? 0));
|
|
85
|
+
return { score, history, usage, power, identity, washFlagged };
|
|
86
|
+
}
|
|
87
|
+
/** Trust score alone, or `null` when the peer is unscored. */
|
|
88
|
+
export function trustScore(peer, nowMs = Date.now()) {
|
|
89
|
+
return computeTrustScore(peer, nowMs)?.score ?? null;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=trust-score.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-score.js","sourceRoot":"","sources":["../../src/reputation/trust-score.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-router.d.ts","sourceRoot":"","sources":["../../src/routing/default-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG9D,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,aAAc,YAAW,MAAM;IAC1C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAA6B;gBAEpC,MAAM,CAAC,EAAE,mBAAmB;IAIxC,UAAU,CAAC,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,GAAG,IAAI;IAoB3E,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAO/F,OAAO,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"default-router.d.ts","sourceRoot":"","sources":["../../src/routing/default-router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG9D,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,aAAc,YAAW,MAAM;IAC1C,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAA6B;gBAEpC,MAAM,CAAC,EAAE,mBAAmB;IAIxC,UAAU,CAAC,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,GAAG,IAAI;IAoB3E,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAO/F,OAAO,CAAC,oBAAoB;CAG7B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { normalizedModelReputationScore } from '../reputation/model-reputation.js';
|
|
2
2
|
export class DefaultRouter {
|
|
3
3
|
_minReputation;
|
|
4
4
|
_latencyMap = new Map();
|
|
@@ -32,17 +32,7 @@ export class DefaultRouter {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
_effectiveReputation(peer) {
|
|
35
|
-
|
|
36
|
-
if (onChainScore != null) {
|
|
37
|
-
return onChainScore;
|
|
38
|
-
}
|
|
39
|
-
if (this._isFiniteNonNegative(peer.reputationScore)) {
|
|
40
|
-
return peer.reputationScore;
|
|
41
|
-
}
|
|
42
|
-
return 0;
|
|
43
|
-
}
|
|
44
|
-
_isFiniteNonNegative(value) {
|
|
45
|
-
return typeof value === 'number' && Number.isFinite(value) && value >= 0;
|
|
35
|
+
return normalizedModelReputationScore(peer) ?? 0;
|
|
46
36
|
}
|
|
47
37
|
}
|
|
48
38
|
//# sourceMappingURL=default-router.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-router.js","sourceRoot":"","sources":["../../src/routing/default-router.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"default-router.js","sourceRoot":"","sources":["../../src/routing/default-router.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AAMnF,MAAM,OAAO,aAAa;IAChB,cAAc,CAAS;IACvB,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEhD,YAAY,MAA4B;QACtC,IAAI,CAAC,cAAc,GAAG,MAAM,EAAE,aAAa,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,UAAU,CAAC,IAA2B,EAAE,KAAiB;QACvD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC;QAC1F,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEvC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACrB,MAAM,MAAM,GAAG,CAAC,CAAC,yBAAyB,IAAI,QAAQ,CAAC;YACvD,MAAM,MAAM,GAAG,CAAC,CAAC,yBAAyB,IAAI,QAAQ,CAAC;YACvD,IAAI,MAAM,KAAK,MAAM;gBAAE,OAAO,MAAM,GAAG,MAAM,CAAC;YAC9C,+CAA+C;YAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;YACjD,MAAM,WAAW,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;YACjD,IAAI,WAAW,KAAK,WAAW;gBAAE,OAAO,WAAW,GAAG,WAAW,CAAC;YAClE,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC;YACxD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC;YACxD,OAAO,IAAI,GAAG,IAAI,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAC7B,CAAC;IAED,QAAQ,CAAC,IAAc,EAAE,MAA+D;QACtF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC;YACnE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAEO,oBAAoB,CAAC,IAAc;QACzC,OAAO,8BAA8B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC;CACF"}
|
|
@@ -10,7 +10,6 @@ export type ModelRouteCandidate = {
|
|
|
10
10
|
peerId: string;
|
|
11
11
|
effectiveReputationScore?: number | null;
|
|
12
12
|
onChainReputationScore?: number | null;
|
|
13
|
-
onChainTrustScore?: number | null;
|
|
14
13
|
reputationScore?: number | null;
|
|
15
14
|
inputUsdPerMillion?: number | null;
|
|
16
15
|
outputUsdPerMillion?: number | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-route-ranking.d.ts","sourceRoot":"","sources":["../../src/routing/model-route-ranking.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,iCAAiC,EAAE,uBAM/C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,
|
|
1
|
+
{"version":3,"file":"model-route-ranking.d.ts","sourceRoot":"","sources":["../../src/routing/model-route-ranking.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,uBAAuB,GAAG;IACpC,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,iCAAiC,EAAE,uBAM/C,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,mBAAmB,IAAI;IAC5D,KAAK,EAAE,CAAC,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAeF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAInF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAkB9E;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,mBAAmB,EAC1B,GAAG,GAAE,MAAmB,GACvB,OAAO,CAIT;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,uBAAuB,GACnC,OAAO,CAMT;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,mBAAmB,EAC1B,WAAW,EAAE,uBAAuB,GACnC,OAAO,CAKT;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,mBAAmB,EAC3D,KAAK,EAAE,CAAC,EACR,WAAW,EAAE,uBAAuB,EACpC,GAAG,GAAE,MAAmB,GACvB,gBAAgB,CAAC,CAAC,CAAC,CAgDrB;AAgCD,wBAAgB,eAAe,CAAC,CAAC,SAAS,mBAAmB,EAC3D,MAAM,EAAE,CAAC,EAAE,EACX,WAAW,EAAE,uBAAuB,EACpC,GAAG,GAAE,MAAmB,GACvB,CAAC,EAAE,CAKL;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,mBAAmB,EAChE,MAAM,EAAE,CAAC,EAAE,EACX,WAAW,EAAE,uBAAuB,EACpC,GAAG,GAAE,MAAmB,GACvB,CAAC,GAAG,IAAI,CAGV"}
|