@gistplus/indexer 0.1.0
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/analytics.d.ts +12 -0
- package/dist/analytics.js +66 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +28 -0
- package/dist/indexer.d.ts +74 -0
- package/dist/indexer.js +73 -0
- package/dist/reputation.d.ts +11 -0
- package/dist/reputation.js +64 -0
- package/package.json +46 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Analytics Engine
|
|
3
|
+
*/
|
|
4
|
+
import { Receipt, Session } from '@gistplus/core';
|
|
5
|
+
import { MarketAnalytics } from './indexer';
|
|
6
|
+
export declare class AnalyticsEngine {
|
|
7
|
+
private receipts;
|
|
8
|
+
private sessions;
|
|
9
|
+
processReceipt(receipt: Receipt): void;
|
|
10
|
+
processSession(session: Session): void;
|
|
11
|
+
getMarketData(capability: string): MarketAnalytics;
|
|
12
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Analytics Engine
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AnalyticsEngine = void 0;
|
|
7
|
+
class AnalyticsEngine {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.receipts = [];
|
|
10
|
+
this.sessions = [];
|
|
11
|
+
}
|
|
12
|
+
processReceipt(receipt) {
|
|
13
|
+
this.receipts.push(receipt);
|
|
14
|
+
}
|
|
15
|
+
processSession(session) {
|
|
16
|
+
this.sessions.push(session);
|
|
17
|
+
}
|
|
18
|
+
getMarketData(capability) {
|
|
19
|
+
// Filter sessions by capability (would need capability metadata)
|
|
20
|
+
const relevantSessions = this.sessions;
|
|
21
|
+
if (relevantSessions.length === 0) {
|
|
22
|
+
return {
|
|
23
|
+
capability,
|
|
24
|
+
averagePrice: 0,
|
|
25
|
+
priceRange: { min: 0, max: 0 },
|
|
26
|
+
totalVolume: 0,
|
|
27
|
+
providerCount: 0,
|
|
28
|
+
averageSLA: {
|
|
29
|
+
latency: 0,
|
|
30
|
+
uptime: 0,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// Calculate price statistics
|
|
35
|
+
const prices = relevantSessions.map(s => s.pricePerRequest);
|
|
36
|
+
const averagePrice = prices.reduce((a, b) => a + b, 0) / prices.length;
|
|
37
|
+
const priceRange = {
|
|
38
|
+
min: Math.min(...prices),
|
|
39
|
+
max: Math.max(...prices),
|
|
40
|
+
};
|
|
41
|
+
// Calculate volume
|
|
42
|
+
const totalVolume = this.receipts
|
|
43
|
+
.reduce((sum, r) => sum + r.amountCharged, 0);
|
|
44
|
+
// Count unique providers
|
|
45
|
+
const uniqueProviders = new Set(relevantSessions.map(s => s.providerPubkey));
|
|
46
|
+
// Calculate average SLA
|
|
47
|
+
const latencies = relevantSessions
|
|
48
|
+
.map(s => s.sla.maxLatencyMs || 0)
|
|
49
|
+
.filter(l => l > 0);
|
|
50
|
+
const avgLatency = latencies.length > 0
|
|
51
|
+
? latencies.reduce((a, b) => a + b, 0) / latencies.length
|
|
52
|
+
: 0;
|
|
53
|
+
return {
|
|
54
|
+
capability,
|
|
55
|
+
averagePrice,
|
|
56
|
+
priceRange,
|
|
57
|
+
totalVolume,
|
|
58
|
+
providerCount: uniqueProviders.size,
|
|
59
|
+
averageSLA: {
|
|
60
|
+
latency: avgLatency,
|
|
61
|
+
uptime: 99.0, // Would calculate from actual data
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.AnalyticsEngine = AnalyticsEngine;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @gistplus/indexer
|
|
3
|
+
*
|
|
4
|
+
* Indexes and aggregates Gist Plus protocol data:
|
|
5
|
+
* - Receipt aggregation
|
|
6
|
+
* - Provider reputation tracking
|
|
7
|
+
* - SLA compliance analytics
|
|
8
|
+
* - Market data (pricing trends)
|
|
9
|
+
*/
|
|
10
|
+
export * from './indexer';
|
|
11
|
+
export * from './reputation';
|
|
12
|
+
export * from './analytics';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @gistplus/indexer
|
|
4
|
+
*
|
|
5
|
+
* Indexes and aggregates Gist Plus protocol data:
|
|
6
|
+
* - Receipt aggregation
|
|
7
|
+
* - Provider reputation tracking
|
|
8
|
+
* - SLA compliance analytics
|
|
9
|
+
* - Market data (pricing trends)
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
23
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
__exportStar(require("./indexer"), exports);
|
|
27
|
+
__exportStar(require("./reputation"), exports);
|
|
28
|
+
__exportStar(require("./analytics"), exports);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GistIndexer - Main indexer for protocol data
|
|
3
|
+
*/
|
|
4
|
+
import { Connection } from '@solana/web3.js';
|
|
5
|
+
import { Receipt, Session } from '@gistplus/core';
|
|
6
|
+
export interface IndexerConfig {
|
|
7
|
+
connection: Connection;
|
|
8
|
+
startSlot?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* GistIndexer aggregates protocol data for analytics and reputation
|
|
12
|
+
*/
|
|
13
|
+
export declare class GistIndexer {
|
|
14
|
+
private connection;
|
|
15
|
+
private reputation;
|
|
16
|
+
private analytics;
|
|
17
|
+
private receipts;
|
|
18
|
+
private sessions;
|
|
19
|
+
constructor(config: IndexerConfig);
|
|
20
|
+
/**
|
|
21
|
+
* Index a receipt
|
|
22
|
+
*/
|
|
23
|
+
indexReceipt(receipt: Receipt): void;
|
|
24
|
+
/**
|
|
25
|
+
* Index a session
|
|
26
|
+
*/
|
|
27
|
+
indexSession(session: Session): void;
|
|
28
|
+
/**
|
|
29
|
+
* Get provider reputation score
|
|
30
|
+
*/
|
|
31
|
+
getProviderReputation(providerPubkey: string): ProviderReputation;
|
|
32
|
+
/**
|
|
33
|
+
* Get market analytics
|
|
34
|
+
*/
|
|
35
|
+
getMarketAnalytics(capability: string): MarketAnalytics;
|
|
36
|
+
/**
|
|
37
|
+
* Get receipts for a session
|
|
38
|
+
*/
|
|
39
|
+
getSessionReceipts(sessionId: string): Receipt[];
|
|
40
|
+
/**
|
|
41
|
+
* Get provider statistics
|
|
42
|
+
*/
|
|
43
|
+
getProviderStats(providerPubkey: string): ProviderStats;
|
|
44
|
+
}
|
|
45
|
+
export interface ProviderReputation {
|
|
46
|
+
providerPubkey: string;
|
|
47
|
+
score: number;
|
|
48
|
+
totalRequests: number;
|
|
49
|
+
slaComplianceRate: number;
|
|
50
|
+
averageLatency: number;
|
|
51
|
+
disputeRate: number;
|
|
52
|
+
}
|
|
53
|
+
export interface MarketAnalytics {
|
|
54
|
+
capability: string;
|
|
55
|
+
averagePrice: number;
|
|
56
|
+
priceRange: {
|
|
57
|
+
min: number;
|
|
58
|
+
max: number;
|
|
59
|
+
};
|
|
60
|
+
totalVolume: number;
|
|
61
|
+
providerCount: number;
|
|
62
|
+
averageSLA: {
|
|
63
|
+
latency: number;
|
|
64
|
+
uptime: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export interface ProviderStats {
|
|
68
|
+
providerPubkey: string;
|
|
69
|
+
totalRequests: number;
|
|
70
|
+
successfulRequests: number;
|
|
71
|
+
successRate: number;
|
|
72
|
+
averageLatency: number;
|
|
73
|
+
totalRevenue: number;
|
|
74
|
+
}
|
package/dist/indexer.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GistIndexer - Main indexer for protocol data
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.GistIndexer = void 0;
|
|
7
|
+
const reputation_1 = require("./reputation");
|
|
8
|
+
const analytics_1 = require("./analytics");
|
|
9
|
+
/**
|
|
10
|
+
* GistIndexer aggregates protocol data for analytics and reputation
|
|
11
|
+
*/
|
|
12
|
+
class GistIndexer {
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.receipts = new Map();
|
|
15
|
+
this.sessions = new Map();
|
|
16
|
+
this.connection = config.connection;
|
|
17
|
+
this.reputation = new reputation_1.ReputationTracker();
|
|
18
|
+
this.analytics = new analytics_1.AnalyticsEngine();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Index a receipt
|
|
22
|
+
*/
|
|
23
|
+
indexReceipt(receipt) {
|
|
24
|
+
this.receipts.set(receipt.receiptId, receipt);
|
|
25
|
+
this.reputation.recordReceipt(receipt);
|
|
26
|
+
this.analytics.processReceipt(receipt);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Index a session
|
|
30
|
+
*/
|
|
31
|
+
indexSession(session) {
|
|
32
|
+
this.sessions.set(session.sessionId, session);
|
|
33
|
+
this.analytics.processSession(session);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get provider reputation score
|
|
37
|
+
*/
|
|
38
|
+
getProviderReputation(providerPubkey) {
|
|
39
|
+
return this.reputation.getReputation(providerPubkey);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Get market analytics
|
|
43
|
+
*/
|
|
44
|
+
getMarketAnalytics(capability) {
|
|
45
|
+
return this.analytics.getMarketData(capability);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get receipts for a session
|
|
49
|
+
*/
|
|
50
|
+
getSessionReceipts(sessionId) {
|
|
51
|
+
return Array.from(this.receipts.values())
|
|
52
|
+
.filter(r => r.sessionId === sessionId);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get provider statistics
|
|
56
|
+
*/
|
|
57
|
+
getProviderStats(providerPubkey) {
|
|
58
|
+
const receipts = Array.from(this.receipts.values())
|
|
59
|
+
.filter(r => r.providerPubkey === providerPubkey);
|
|
60
|
+
const totalRequests = receipts.length;
|
|
61
|
+
const successfulRequests = receipts.filter(r => r.slaVerification.met).length;
|
|
62
|
+
const avgLatency = receipts.reduce((sum, r) => sum + r.latencyMs, 0) / totalRequests;
|
|
63
|
+
return {
|
|
64
|
+
providerPubkey,
|
|
65
|
+
totalRequests,
|
|
66
|
+
successfulRequests,
|
|
67
|
+
successRate: successfulRequests / totalRequests,
|
|
68
|
+
averageLatency: avgLatency,
|
|
69
|
+
totalRevenue: receipts.reduce((sum, r) => sum + r.amountCharged, 0),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.GistIndexer = GistIndexer;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reputation Tracker
|
|
3
|
+
*/
|
|
4
|
+
import { Receipt } from '@gistplus/core';
|
|
5
|
+
import { ProviderReputation } from './indexer';
|
|
6
|
+
export declare class ReputationTracker {
|
|
7
|
+
private reputationData;
|
|
8
|
+
recordReceipt(receipt: Receipt): void;
|
|
9
|
+
recordDispute(providerPubkey: string): void;
|
|
10
|
+
getReputation(providerPubkey: string): ProviderReputation;
|
|
11
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Reputation Tracker
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ReputationTracker = void 0;
|
|
7
|
+
class ReputationTracker {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.reputationData = new Map();
|
|
10
|
+
}
|
|
11
|
+
recordReceipt(receipt) {
|
|
12
|
+
const provider = receipt.providerPubkey;
|
|
13
|
+
if (!this.reputationData.has(provider)) {
|
|
14
|
+
this.reputationData.set(provider, {
|
|
15
|
+
totalRequests: 0,
|
|
16
|
+
slaMetCount: 0,
|
|
17
|
+
totalLatency: 0,
|
|
18
|
+
disputes: 0,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const data = this.reputationData.get(provider);
|
|
22
|
+
data.totalRequests++;
|
|
23
|
+
data.totalLatency += receipt.latencyMs;
|
|
24
|
+
if (receipt.slaVerification.met) {
|
|
25
|
+
data.slaMetCount++;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
recordDispute(providerPubkey) {
|
|
29
|
+
const data = this.reputationData.get(providerPubkey);
|
|
30
|
+
if (data) {
|
|
31
|
+
data.disputes++;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
getReputation(providerPubkey) {
|
|
35
|
+
const data = this.reputationData.get(providerPubkey);
|
|
36
|
+
if (!data || data.totalRequests === 0) {
|
|
37
|
+
return {
|
|
38
|
+
providerPubkey,
|
|
39
|
+
score: 0,
|
|
40
|
+
totalRequests: 0,
|
|
41
|
+
slaComplianceRate: 0,
|
|
42
|
+
averageLatency: 0,
|
|
43
|
+
disputeRate: 0,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const slaComplianceRate = data.slaMetCount / data.totalRequests;
|
|
47
|
+
const averageLatency = data.totalLatency / data.totalRequests;
|
|
48
|
+
const disputeRate = data.disputes / data.totalRequests;
|
|
49
|
+
// Calculate score (0-100)
|
|
50
|
+
let score = 100;
|
|
51
|
+
score *= slaComplianceRate; // Reduce by SLA compliance
|
|
52
|
+
score *= Math.max(0, 1 - disputeRate * 10); // Reduce by disputes
|
|
53
|
+
score *= Math.max(0, 1 - averageLatency / 10000); // Reduce by latency
|
|
54
|
+
return {
|
|
55
|
+
providerPubkey,
|
|
56
|
+
score: Math.round(score),
|
|
57
|
+
totalRequests: data.totalRequests,
|
|
58
|
+
slaComplianceRate,
|
|
59
|
+
averageLatency,
|
|
60
|
+
disputeRate,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.ReputationTracker = ReputationTracker;
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gistplus/indexer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Indexer for Gist Plus - aggregates receipts, tracks reputation, analyzes SLA compliance",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"clean": "rimraf dist",
|
|
18
|
+
"start": "node dist/server.js"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"gistplus",
|
|
22
|
+
"gist",
|
|
23
|
+
"indexer",
|
|
24
|
+
"analytics",
|
|
25
|
+
"reputation"
|
|
26
|
+
],
|
|
27
|
+
"author": "Gist Plus",
|
|
28
|
+
"license": "Apache-2.0",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/gistplus/gistplus"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/gistplus/gistplus#readme",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/gistplus/gistplus/issues"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@gistplus/core": "^0.1.0",
|
|
39
|
+
"@solana/web3.js": "^1.87.6"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"typescript": "^5.3.3",
|
|
43
|
+
"@types/node": "^20.10.6",
|
|
44
|
+
"rimraf": "^5.0.5"
|
|
45
|
+
}
|
|
46
|
+
}
|