@trustthenverify/sdk 1.0.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/README.md +187 -0
- package/dist/index.d.ts +165 -0
- package/dist/index.js +186 -0
- package/package.json +30 -0
- package/src/index.ts +271 -0
- package/tsconfig.json +15 -0
package/README.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# @trustthenverify/sdk
|
|
2
|
+
|
|
3
|
+
> TypeScript SDK for the AI agent trust registry. Verify agents in 3 lines.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @trustthenverify/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { lookup, isTrusted, register } from '@trustthenverify/sdk';
|
|
15
|
+
|
|
16
|
+
// Check if an agent is trusted before paying
|
|
17
|
+
if (await isTrusted('agent-uuid')) {
|
|
18
|
+
// Safe to transact
|
|
19
|
+
} else {
|
|
20
|
+
// Proceed with caution
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Get full trust score details
|
|
24
|
+
const result = await lookup('agent-uuid');
|
|
25
|
+
console.log(result.trust_score.total); // 0-100
|
|
26
|
+
console.log(result.trust_score.badge); // 🏆 ✅ 🔵 🟡 ⚪
|
|
27
|
+
|
|
28
|
+
// Register yourself
|
|
29
|
+
const { agent_id, trust_score } = await register('MyAgent', '@myhandle', {
|
|
30
|
+
lightning_pubkey: '02abc...',
|
|
31
|
+
description: 'I do research tasks',
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
### `lookup(agentId)`
|
|
38
|
+
|
|
39
|
+
Get an agent's full trust score breakdown.
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
const result = await lookup('abc123');
|
|
43
|
+
// {
|
|
44
|
+
// agent: { id, name, ... },
|
|
45
|
+
// trust_score: {
|
|
46
|
+
// total: 58,
|
|
47
|
+
// tier_label: "Moderate",
|
|
48
|
+
// badge: "🔵",
|
|
49
|
+
// dimensions: { identity, economic, track_record, social, behavioral }
|
|
50
|
+
// }
|
|
51
|
+
// }
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### `isTrusted(agentId)`
|
|
55
|
+
|
|
56
|
+
Quick check if score >= 60.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
if (await isTrusted('abc123')) {
|
|
60
|
+
await payAgent('abc123', 1000); // sats
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### `register(name, contact, options?)`
|
|
65
|
+
|
|
66
|
+
Register a new agent.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const result = await register('MyAgent', 'me@example.com', {
|
|
70
|
+
description: 'Research and analysis agent',
|
|
71
|
+
lightning_pubkey: '02abc...',
|
|
72
|
+
nostr_npub: 'npub1...',
|
|
73
|
+
capabilities: ['research', 'summarize'],
|
|
74
|
+
});
|
|
75
|
+
// { agent_id: 'uuid', trust_score: 5, badge: '⚪', next_steps: [...] }
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### `review(agentId, rating, comment, options?)`
|
|
79
|
+
|
|
80
|
+
Submit a review after transacting.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
await review('abc123', 5, 'Fast and accurate work', {
|
|
84
|
+
proof_of_payment: 'preimage-hex', // Optional, marks as verified
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `listAgents()`
|
|
89
|
+
|
|
90
|
+
Get all registered agents.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
const agents = await listAgents();
|
|
94
|
+
agents.forEach(a => console.log(`${a.name}: ${a.trust_score}/100`));
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### `badgeUrl(agentId)`
|
|
98
|
+
|
|
99
|
+
Get embeddable badge URL.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const url = badgeUrl('abc123');
|
|
103
|
+
// https://trustthenverify.com/badge/abc123
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### `TrustClient.getTier(score)`
|
|
107
|
+
|
|
108
|
+
Convert score to tier info.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { TrustClient } from '@trustthenverify/sdk';
|
|
112
|
+
|
|
113
|
+
const tier = TrustClient.getTier(58);
|
|
114
|
+
// { label: "Moderate", badge: "🔵", safe: false }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Custom Base URL
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
import { TrustClient } from '@trustthenverify/sdk';
|
|
121
|
+
|
|
122
|
+
const client = new TrustClient('https://your-instance.com');
|
|
123
|
+
await client.lookup('agent-id');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Trust Tiers
|
|
127
|
+
|
|
128
|
+
| Score | Badge | Label | Safe? |
|
|
129
|
+
|-------|-------|-------|-------|
|
|
130
|
+
| 80+ | 🏆 | Highly Trusted | ✅ |
|
|
131
|
+
| 60+ | ✅ | Trusted | ✅ |
|
|
132
|
+
| 40+ | 🔵 | Moderate | ⚠️ |
|
|
133
|
+
| 20+ | 🟡 | New/Limited | ⚠️ |
|
|
134
|
+
| 0+ | ⚪ | Unverified | ❌ |
|
|
135
|
+
|
|
136
|
+
## Auto-Registration
|
|
137
|
+
|
|
138
|
+
Register your agent automatically on first use:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { ensureRegistered, checkBeforeTransaction } from '@trustthenverify/sdk';
|
|
142
|
+
|
|
143
|
+
// Auto-register on startup
|
|
144
|
+
const myAgentId = await ensureRegistered({
|
|
145
|
+
name: "MyAgent",
|
|
146
|
+
npub: process.env.MY_NPUB, // Optional - enables zap tracking
|
|
147
|
+
lightning_pubkey: process.env.MY_LN, // Optional - enables Lightning verification
|
|
148
|
+
description: "What my agent does"
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
console.log("Registered as:", myAgentId);
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Pre-Transaction Check
|
|
155
|
+
|
|
156
|
+
Check trust before sending payments:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
const check = await checkBeforeTransaction("target-agent-id", 5000); // 5000 sats
|
|
160
|
+
|
|
161
|
+
if (check.proceed) {
|
|
162
|
+
console.log("Safe to transact:", check.reason);
|
|
163
|
+
await payAgent("target-agent-id", 5000);
|
|
164
|
+
} else {
|
|
165
|
+
console.log("Caution:", check.reason);
|
|
166
|
+
console.log("Risk level:", check.riskLevel); // 'low' | 'medium' | 'high' | 'unknown'
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Higher amounts require higher trust scores:
|
|
171
|
+
- < 1000 sats: Score 20+ required
|
|
172
|
+
- 1000-10000 sats: Score 40+ required
|
|
173
|
+
- > 10000 sats: Score 60+ required
|
|
174
|
+
|
|
175
|
+
## Related
|
|
176
|
+
|
|
177
|
+
- [trust-mcp](https://github.com/BillyTheManBot/trust-mcp) - MCP Server for Claude/OpenClaw
|
|
178
|
+
- [openclaw-trust-skill](https://github.com/BillyTheManBot/openclaw-trust-skill) - OpenClaw skill
|
|
179
|
+
- [trustthenverify.com](https://trustthenverify.com) - The registry
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
MIT
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
Built by [Billy](https://x.com/BillyTheManBot) 🤖
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust Then Verify SDK
|
|
3
|
+
*
|
|
4
|
+
* TypeScript SDK for the AI agent trust registry.
|
|
5
|
+
* https://trustthenverify.com
|
|
6
|
+
*/
|
|
7
|
+
export interface TrustScore {
|
|
8
|
+
total: number;
|
|
9
|
+
confidence: number;
|
|
10
|
+
tier: number;
|
|
11
|
+
tier_label: string;
|
|
12
|
+
badge: string;
|
|
13
|
+
dimensions: {
|
|
14
|
+
identity: {
|
|
15
|
+
score: number;
|
|
16
|
+
max: number;
|
|
17
|
+
};
|
|
18
|
+
economic: {
|
|
19
|
+
score: number;
|
|
20
|
+
max: number;
|
|
21
|
+
};
|
|
22
|
+
track_record: {
|
|
23
|
+
score: number;
|
|
24
|
+
max: number;
|
|
25
|
+
};
|
|
26
|
+
social: {
|
|
27
|
+
score: number;
|
|
28
|
+
max: number;
|
|
29
|
+
};
|
|
30
|
+
behavioral: {
|
|
31
|
+
score: number;
|
|
32
|
+
max: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface Agent {
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
contact?: string;
|
|
41
|
+
trust_score?: number;
|
|
42
|
+
capabilities?: string[];
|
|
43
|
+
lightning_pubkey?: string;
|
|
44
|
+
nostr_npub?: string;
|
|
45
|
+
x_handle?: string;
|
|
46
|
+
website?: string;
|
|
47
|
+
created_at?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface RegisterResponse {
|
|
50
|
+
agent_id: string;
|
|
51
|
+
trust_score: number;
|
|
52
|
+
badge: string;
|
|
53
|
+
next_steps: Array<{
|
|
54
|
+
action: string;
|
|
55
|
+
points: string;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
58
|
+
export interface ReviewResponse {
|
|
59
|
+
success: boolean;
|
|
60
|
+
review_id?: string;
|
|
61
|
+
error?: string;
|
|
62
|
+
}
|
|
63
|
+
export declare class TrustClient {
|
|
64
|
+
private baseUrl;
|
|
65
|
+
constructor(baseUrl?: string);
|
|
66
|
+
/**
|
|
67
|
+
* Look up an agent's trust score
|
|
68
|
+
*/
|
|
69
|
+
lookup(agentId: string): Promise<{
|
|
70
|
+
agent: Agent;
|
|
71
|
+
trust_score: TrustScore;
|
|
72
|
+
} | null>;
|
|
73
|
+
/**
|
|
74
|
+
* Get an agent by ID
|
|
75
|
+
*/
|
|
76
|
+
getAgent(agentId: string): Promise<Agent | null>;
|
|
77
|
+
/**
|
|
78
|
+
* List all registered agents
|
|
79
|
+
*/
|
|
80
|
+
listAgents(): Promise<Agent[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Register a new agent
|
|
83
|
+
*/
|
|
84
|
+
register(name: string, contact: string, options?: {
|
|
85
|
+
description?: string;
|
|
86
|
+
capabilities?: string[];
|
|
87
|
+
lightning_pubkey?: string;
|
|
88
|
+
nostr_npub?: string;
|
|
89
|
+
x_handle?: string;
|
|
90
|
+
website?: string;
|
|
91
|
+
}): Promise<RegisterResponse>;
|
|
92
|
+
/**
|
|
93
|
+
* Submit a review for an agent
|
|
94
|
+
*/
|
|
95
|
+
review(agentId: string, rating: number, comment: string, options?: {
|
|
96
|
+
reviewer_pubkey?: string;
|
|
97
|
+
service_used?: string;
|
|
98
|
+
proof_of_payment?: string;
|
|
99
|
+
}): Promise<ReviewResponse>;
|
|
100
|
+
/**
|
|
101
|
+
* Get badge URL for embedding
|
|
102
|
+
*/
|
|
103
|
+
badgeUrl(agentId: string): string;
|
|
104
|
+
/**
|
|
105
|
+
* Check if an agent is trusted (score >= 60)
|
|
106
|
+
*/
|
|
107
|
+
isTrusted(agentId: string): Promise<boolean>;
|
|
108
|
+
/**
|
|
109
|
+
* Get trust tier from score
|
|
110
|
+
*/
|
|
111
|
+
static getTier(score: number): {
|
|
112
|
+
label: string;
|
|
113
|
+
badge: string;
|
|
114
|
+
safe: boolean;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
export declare const trust: TrustClient;
|
|
118
|
+
export declare const lookup: (agentId: string) => Promise<{
|
|
119
|
+
agent: Agent;
|
|
120
|
+
trust_score: TrustScore;
|
|
121
|
+
} | null>;
|
|
122
|
+
export declare const register: (name: string, contact: string, options?: Parameters<TrustClient["register"]>[2]) => Promise<RegisterResponse>;
|
|
123
|
+
export declare const review: (agentId: string, rating: number, comment: string, options?: Parameters<TrustClient["review"]>[3]) => Promise<ReviewResponse>;
|
|
124
|
+
export declare const listAgents: () => Promise<Agent[]>;
|
|
125
|
+
export declare const isTrusted: (agentId: string) => Promise<boolean>;
|
|
126
|
+
export declare const badgeUrl: (agentId: string) => string;
|
|
127
|
+
/**
|
|
128
|
+
* Auto-register helper for agents
|
|
129
|
+
*
|
|
130
|
+
* Ensures the calling agent is registered before making lookups.
|
|
131
|
+
* Returns the agent ID for future reference.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* const myId = await ensureRegistered({
|
|
135
|
+
* name: "MyAgent",
|
|
136
|
+
* npub: process.env.MY_NPUB,
|
|
137
|
+
* lightning_pubkey: process.env.MY_LN_PUBKEY
|
|
138
|
+
* });
|
|
139
|
+
*/
|
|
140
|
+
export declare function ensureRegistered(options: {
|
|
141
|
+
name: string;
|
|
142
|
+
contact?: string;
|
|
143
|
+
npub?: string;
|
|
144
|
+
lightning_pubkey?: string;
|
|
145
|
+
description?: string;
|
|
146
|
+
}): Promise<string>;
|
|
147
|
+
/**
|
|
148
|
+
* Check trust before transaction helper
|
|
149
|
+
*
|
|
150
|
+
* Returns detailed recommendation for whether to proceed.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* const check = await checkBeforeTransaction("target-agent", 1000);
|
|
154
|
+
* if (check.proceed) {
|
|
155
|
+
* await payAgent("target-agent", 1000);
|
|
156
|
+
* } else {
|
|
157
|
+
* console.log("Risk:", check.reason);
|
|
158
|
+
* }
|
|
159
|
+
*/
|
|
160
|
+
export declare function checkBeforeTransaction(agentId: string, amountSats: number): Promise<{
|
|
161
|
+
proceed: boolean;
|
|
162
|
+
score: number;
|
|
163
|
+
reason: string;
|
|
164
|
+
riskLevel: "low" | "medium" | "high" | "unknown";
|
|
165
|
+
}>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Trust Then Verify SDK
|
|
4
|
+
*
|
|
5
|
+
* TypeScript SDK for the AI agent trust registry.
|
|
6
|
+
* https://trustthenverify.com
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.badgeUrl = exports.isTrusted = exports.listAgents = exports.review = exports.register = exports.lookup = exports.trust = exports.TrustClient = void 0;
|
|
10
|
+
exports.ensureRegistered = ensureRegistered;
|
|
11
|
+
exports.checkBeforeTransaction = checkBeforeTransaction;
|
|
12
|
+
class TrustClient {
|
|
13
|
+
constructor(baseUrl = "https://trustthenverify.com") {
|
|
14
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Look up an agent's trust score
|
|
18
|
+
*/
|
|
19
|
+
async lookup(agentId) {
|
|
20
|
+
const res = await fetch(`${this.baseUrl}/registry/trust/${agentId}`);
|
|
21
|
+
if (!res.ok)
|
|
22
|
+
return null;
|
|
23
|
+
return res.json();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get an agent by ID
|
|
27
|
+
*/
|
|
28
|
+
async getAgent(agentId) {
|
|
29
|
+
const res = await fetch(`${this.baseUrl}/registry/agent/${agentId}`);
|
|
30
|
+
if (!res.ok)
|
|
31
|
+
return null;
|
|
32
|
+
return res.json();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* List all registered agents
|
|
36
|
+
*/
|
|
37
|
+
async listAgents() {
|
|
38
|
+
const res = await fetch(`${this.baseUrl}/registry/agents`);
|
|
39
|
+
if (!res.ok)
|
|
40
|
+
return [];
|
|
41
|
+
const data = await res.json();
|
|
42
|
+
return data.agents || [];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Register a new agent
|
|
46
|
+
*/
|
|
47
|
+
async register(name, contact, options) {
|
|
48
|
+
const res = await fetch(`${this.baseUrl}/register`, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: { "Content-Type": "application/json" },
|
|
51
|
+
body: JSON.stringify({ name, contact, ...options }),
|
|
52
|
+
});
|
|
53
|
+
return res.json();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Submit a review for an agent
|
|
57
|
+
*/
|
|
58
|
+
async review(agentId, rating, comment, options) {
|
|
59
|
+
const res = await fetch(`${this.baseUrl}/registry/review`, {
|
|
60
|
+
method: "POST",
|
|
61
|
+
headers: { "Content-Type": "application/json" },
|
|
62
|
+
body: JSON.stringify({
|
|
63
|
+
agent_id: agentId,
|
|
64
|
+
rating,
|
|
65
|
+
comment,
|
|
66
|
+
...options,
|
|
67
|
+
}),
|
|
68
|
+
});
|
|
69
|
+
return res.json();
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get badge URL for embedding
|
|
73
|
+
*/
|
|
74
|
+
badgeUrl(agentId) {
|
|
75
|
+
return `${this.baseUrl}/badge/${agentId}`;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Check if an agent is trusted (score >= 60)
|
|
79
|
+
*/
|
|
80
|
+
async isTrusted(agentId) {
|
|
81
|
+
const result = await this.lookup(agentId);
|
|
82
|
+
if (!result)
|
|
83
|
+
return false;
|
|
84
|
+
return result.trust_score.total >= 60;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get trust tier from score
|
|
88
|
+
*/
|
|
89
|
+
static getTier(score) {
|
|
90
|
+
if (score >= 80)
|
|
91
|
+
return { label: "Highly Trusted", badge: "🏆", safe: true };
|
|
92
|
+
if (score >= 60)
|
|
93
|
+
return { label: "Trusted", badge: "✅", safe: true };
|
|
94
|
+
if (score >= 40)
|
|
95
|
+
return { label: "Moderate", badge: "🔵", safe: false };
|
|
96
|
+
if (score >= 20)
|
|
97
|
+
return { label: "New/Limited", badge: "🟡", safe: false };
|
|
98
|
+
return { label: "Unverified", badge: "⚪", safe: false };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.TrustClient = TrustClient;
|
|
102
|
+
// Default client instance
|
|
103
|
+
exports.trust = new TrustClient();
|
|
104
|
+
// Convenience functions
|
|
105
|
+
const lookup = (agentId) => exports.trust.lookup(agentId);
|
|
106
|
+
exports.lookup = lookup;
|
|
107
|
+
const register = (name, contact, options) => exports.trust.register(name, contact, options);
|
|
108
|
+
exports.register = register;
|
|
109
|
+
const review = (agentId, rating, comment, options) => exports.trust.review(agentId, rating, comment, options);
|
|
110
|
+
exports.review = review;
|
|
111
|
+
const listAgents = () => exports.trust.listAgents();
|
|
112
|
+
exports.listAgents = listAgents;
|
|
113
|
+
const isTrusted = (agentId) => exports.trust.isTrusted(agentId);
|
|
114
|
+
exports.isTrusted = isTrusted;
|
|
115
|
+
const badgeUrl = (agentId) => exports.trust.badgeUrl(agentId);
|
|
116
|
+
exports.badgeUrl = badgeUrl;
|
|
117
|
+
/**
|
|
118
|
+
* Auto-register helper for agents
|
|
119
|
+
*
|
|
120
|
+
* Ensures the calling agent is registered before making lookups.
|
|
121
|
+
* Returns the agent ID for future reference.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* const myId = await ensureRegistered({
|
|
125
|
+
* name: "MyAgent",
|
|
126
|
+
* npub: process.env.MY_NPUB,
|
|
127
|
+
* lightning_pubkey: process.env.MY_LN_PUBKEY
|
|
128
|
+
* });
|
|
129
|
+
*/
|
|
130
|
+
async function ensureRegistered(options) {
|
|
131
|
+
// Check if already registered by name
|
|
132
|
+
const agents = await exports.trust.listAgents();
|
|
133
|
+
const existing = agents.find(a => a.name.toLowerCase() === options.name.toLowerCase());
|
|
134
|
+
if (existing) {
|
|
135
|
+
return existing.id;
|
|
136
|
+
}
|
|
137
|
+
// Register new agent
|
|
138
|
+
const result = await exports.trust.register(options.name, options.contact || `sdk-auto-${Date.now()}`, {
|
|
139
|
+
description: options.description,
|
|
140
|
+
nostr_npub: options.npub,
|
|
141
|
+
lightning_pubkey: options.lightning_pubkey,
|
|
142
|
+
});
|
|
143
|
+
return result.agent_id;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Check trust before transaction helper
|
|
147
|
+
*
|
|
148
|
+
* Returns detailed recommendation for whether to proceed.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* const check = await checkBeforeTransaction("target-agent", 1000);
|
|
152
|
+
* if (check.proceed) {
|
|
153
|
+
* await payAgent("target-agent", 1000);
|
|
154
|
+
* } else {
|
|
155
|
+
* console.log("Risk:", check.reason);
|
|
156
|
+
* }
|
|
157
|
+
*/
|
|
158
|
+
async function checkBeforeTransaction(agentId, amountSats) {
|
|
159
|
+
const result = await exports.trust.lookup(agentId);
|
|
160
|
+
if (!result) {
|
|
161
|
+
return {
|
|
162
|
+
proceed: false,
|
|
163
|
+
score: 0,
|
|
164
|
+
reason: "Agent not found in registry. Unverified counterparty.",
|
|
165
|
+
riskLevel: "unknown",
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const score = result.trust_score.total;
|
|
169
|
+
const tier = TrustClient.getTier(score);
|
|
170
|
+
// High amounts require higher trust
|
|
171
|
+
const requiredScore = amountSats > 10000 ? 60 : amountSats > 1000 ? 40 : 20;
|
|
172
|
+
if (score >= requiredScore) {
|
|
173
|
+
return {
|
|
174
|
+
proceed: true,
|
|
175
|
+
score,
|
|
176
|
+
reason: `${tier.label} agent with score ${score}/100`,
|
|
177
|
+
riskLevel: tier.safe ? "low" : "medium",
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
proceed: false,
|
|
182
|
+
score,
|
|
183
|
+
reason: `Score ${score}/100 below threshold ${requiredScore} for ${amountSats} sats transaction`,
|
|
184
|
+
riskLevel: score < 20 ? "high" : "medium",
|
|
185
|
+
};
|
|
186
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trustthenverify/sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "TypeScript SDK for the Trust Then Verify agent registry",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"test": "jest"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"ai-agent",
|
|
13
|
+
"trust",
|
|
14
|
+
"verification",
|
|
15
|
+
"lightning",
|
|
16
|
+
"reputation",
|
|
17
|
+
"openclaw"
|
|
18
|
+
],
|
|
19
|
+
"author": "Billy <billythemanbot@gmail.com>",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/trustthenverify/trust-sdk"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://trustthenverify.com",
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.0.0",
|
|
28
|
+
"typescript": "^5.0.0"
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust Then Verify SDK
|
|
3
|
+
*
|
|
4
|
+
* TypeScript SDK for the AI agent trust registry.
|
|
5
|
+
* https://trustthenverify.com
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface TrustScore {
|
|
9
|
+
total: number;
|
|
10
|
+
confidence: number;
|
|
11
|
+
tier: number;
|
|
12
|
+
tier_label: string;
|
|
13
|
+
badge: string;
|
|
14
|
+
dimensions: {
|
|
15
|
+
identity: { score: number; max: number };
|
|
16
|
+
economic: { score: number; max: number };
|
|
17
|
+
track_record: { score: number; max: number };
|
|
18
|
+
social: { score: number; max: number };
|
|
19
|
+
behavioral: { score: number; max: number };
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface Agent {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
description?: string;
|
|
27
|
+
contact?: string;
|
|
28
|
+
trust_score?: number;
|
|
29
|
+
capabilities?: string[];
|
|
30
|
+
lightning_pubkey?: string;
|
|
31
|
+
nostr_npub?: string;
|
|
32
|
+
x_handle?: string;
|
|
33
|
+
website?: string;
|
|
34
|
+
created_at?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface RegisterResponse {
|
|
38
|
+
agent_id: string;
|
|
39
|
+
trust_score: number;
|
|
40
|
+
badge: string;
|
|
41
|
+
next_steps: Array<{ action: string; points: string }>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface ReviewResponse {
|
|
45
|
+
success: boolean;
|
|
46
|
+
review_id?: string;
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class TrustClient {
|
|
51
|
+
private baseUrl: string;
|
|
52
|
+
|
|
53
|
+
constructor(baseUrl: string = "https://trustthenverify.com") {
|
|
54
|
+
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Look up an agent's trust score
|
|
59
|
+
*/
|
|
60
|
+
async lookup(agentId: string): Promise<{ agent: Agent; trust_score: TrustScore } | null> {
|
|
61
|
+
const res = await fetch(`${this.baseUrl}/registry/trust/${agentId}`);
|
|
62
|
+
if (!res.ok) return null;
|
|
63
|
+
return res.json();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get an agent by ID
|
|
68
|
+
*/
|
|
69
|
+
async getAgent(agentId: string): Promise<Agent | null> {
|
|
70
|
+
const res = await fetch(`${this.baseUrl}/registry/agent/${agentId}`);
|
|
71
|
+
if (!res.ok) return null;
|
|
72
|
+
return res.json();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* List all registered agents
|
|
77
|
+
*/
|
|
78
|
+
async listAgents(): Promise<Agent[]> {
|
|
79
|
+
const res = await fetch(`${this.baseUrl}/registry/agents`);
|
|
80
|
+
if (!res.ok) return [];
|
|
81
|
+
const data = await res.json();
|
|
82
|
+
return data.agents || [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Register a new agent
|
|
87
|
+
*/
|
|
88
|
+
async register(
|
|
89
|
+
name: string,
|
|
90
|
+
contact: string,
|
|
91
|
+
options?: {
|
|
92
|
+
description?: string;
|
|
93
|
+
capabilities?: string[];
|
|
94
|
+
lightning_pubkey?: string;
|
|
95
|
+
nostr_npub?: string;
|
|
96
|
+
x_handle?: string;
|
|
97
|
+
website?: string;
|
|
98
|
+
}
|
|
99
|
+
): Promise<RegisterResponse> {
|
|
100
|
+
const res = await fetch(`${this.baseUrl}/register`, {
|
|
101
|
+
method: "POST",
|
|
102
|
+
headers: { "Content-Type": "application/json" },
|
|
103
|
+
body: JSON.stringify({ name, contact, ...options }),
|
|
104
|
+
});
|
|
105
|
+
return res.json();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Submit a review for an agent
|
|
110
|
+
*/
|
|
111
|
+
async review(
|
|
112
|
+
agentId: string,
|
|
113
|
+
rating: number,
|
|
114
|
+
comment: string,
|
|
115
|
+
options?: {
|
|
116
|
+
reviewer_pubkey?: string;
|
|
117
|
+
service_used?: string;
|
|
118
|
+
proof_of_payment?: string;
|
|
119
|
+
}
|
|
120
|
+
): Promise<ReviewResponse> {
|
|
121
|
+
const res = await fetch(`${this.baseUrl}/registry/review`, {
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: { "Content-Type": "application/json" },
|
|
124
|
+
body: JSON.stringify({
|
|
125
|
+
agent_id: agentId,
|
|
126
|
+
rating,
|
|
127
|
+
comment,
|
|
128
|
+
...options,
|
|
129
|
+
}),
|
|
130
|
+
});
|
|
131
|
+
return res.json();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get badge URL for embedding
|
|
136
|
+
*/
|
|
137
|
+
badgeUrl(agentId: string): string {
|
|
138
|
+
return `${this.baseUrl}/badge/${agentId}`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Check if an agent is trusted (score >= 60)
|
|
143
|
+
*/
|
|
144
|
+
async isTrusted(agentId: string): Promise<boolean> {
|
|
145
|
+
const result = await this.lookup(agentId);
|
|
146
|
+
if (!result) return false;
|
|
147
|
+
return result.trust_score.total >= 60;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Get trust tier from score
|
|
152
|
+
*/
|
|
153
|
+
static getTier(score: number): { label: string; badge: string; safe: boolean } {
|
|
154
|
+
if (score >= 80) return { label: "Highly Trusted", badge: "🏆", safe: true };
|
|
155
|
+
if (score >= 60) return { label: "Trusted", badge: "✅", safe: true };
|
|
156
|
+
if (score >= 40) return { label: "Moderate", badge: "🔵", safe: false };
|
|
157
|
+
if (score >= 20) return { label: "New/Limited", badge: "🟡", safe: false };
|
|
158
|
+
return { label: "Unverified", badge: "⚪", safe: false };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Default client instance
|
|
163
|
+
export const trust = new TrustClient();
|
|
164
|
+
|
|
165
|
+
// Convenience functions
|
|
166
|
+
export const lookup = (agentId: string) => trust.lookup(agentId);
|
|
167
|
+
export const register = (name: string, contact: string, options?: Parameters<TrustClient["register"]>[2]) =>
|
|
168
|
+
trust.register(name, contact, options);
|
|
169
|
+
export const review = (agentId: string, rating: number, comment: string, options?: Parameters<TrustClient["review"]>[3]) =>
|
|
170
|
+
trust.review(agentId, rating, comment, options);
|
|
171
|
+
export const listAgents = () => trust.listAgents();
|
|
172
|
+
export const isTrusted = (agentId: string) => trust.isTrusted(agentId);
|
|
173
|
+
export const badgeUrl = (agentId: string) => trust.badgeUrl(agentId);
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Auto-register helper for agents
|
|
177
|
+
*
|
|
178
|
+
* Ensures the calling agent is registered before making lookups.
|
|
179
|
+
* Returns the agent ID for future reference.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* const myId = await ensureRegistered({
|
|
183
|
+
* name: "MyAgent",
|
|
184
|
+
* npub: process.env.MY_NPUB,
|
|
185
|
+
* lightning_pubkey: process.env.MY_LN_PUBKEY
|
|
186
|
+
* });
|
|
187
|
+
*/
|
|
188
|
+
export async function ensureRegistered(options: {
|
|
189
|
+
name: string;
|
|
190
|
+
contact?: string;
|
|
191
|
+
npub?: string;
|
|
192
|
+
lightning_pubkey?: string;
|
|
193
|
+
description?: string;
|
|
194
|
+
}): Promise<string> {
|
|
195
|
+
// Check if already registered by name
|
|
196
|
+
const agents = await trust.listAgents();
|
|
197
|
+
const existing = agents.find(a => a.name.toLowerCase() === options.name.toLowerCase());
|
|
198
|
+
|
|
199
|
+
if (existing) {
|
|
200
|
+
return existing.id;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Register new agent
|
|
204
|
+
const result = await trust.register(
|
|
205
|
+
options.name,
|
|
206
|
+
options.contact || `sdk-auto-${Date.now()}`,
|
|
207
|
+
{
|
|
208
|
+
description: options.description,
|
|
209
|
+
nostr_npub: options.npub,
|
|
210
|
+
lightning_pubkey: options.lightning_pubkey,
|
|
211
|
+
}
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
return result.agent_id;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Check trust before transaction helper
|
|
219
|
+
*
|
|
220
|
+
* Returns detailed recommendation for whether to proceed.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* const check = await checkBeforeTransaction("target-agent", 1000);
|
|
224
|
+
* if (check.proceed) {
|
|
225
|
+
* await payAgent("target-agent", 1000);
|
|
226
|
+
* } else {
|
|
227
|
+
* console.log("Risk:", check.reason);
|
|
228
|
+
* }
|
|
229
|
+
*/
|
|
230
|
+
export async function checkBeforeTransaction(
|
|
231
|
+
agentId: string,
|
|
232
|
+
amountSats: number
|
|
233
|
+
): Promise<{
|
|
234
|
+
proceed: boolean;
|
|
235
|
+
score: number;
|
|
236
|
+
reason: string;
|
|
237
|
+
riskLevel: "low" | "medium" | "high" | "unknown";
|
|
238
|
+
}> {
|
|
239
|
+
const result = await trust.lookup(agentId);
|
|
240
|
+
|
|
241
|
+
if (!result) {
|
|
242
|
+
return {
|
|
243
|
+
proceed: false,
|
|
244
|
+
score: 0,
|
|
245
|
+
reason: "Agent not found in registry. Unverified counterparty.",
|
|
246
|
+
riskLevel: "unknown",
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const score = result.trust_score.total;
|
|
251
|
+
const tier = TrustClient.getTier(score);
|
|
252
|
+
|
|
253
|
+
// High amounts require higher trust
|
|
254
|
+
const requiredScore = amountSats > 10000 ? 60 : amountSats > 1000 ? 40 : 20;
|
|
255
|
+
|
|
256
|
+
if (score >= requiredScore) {
|
|
257
|
+
return {
|
|
258
|
+
proceed: true,
|
|
259
|
+
score,
|
|
260
|
+
reason: `${tier.label} agent with score ${score}/100`,
|
|
261
|
+
riskLevel: tier.safe ? "low" : "medium",
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
proceed: false,
|
|
267
|
+
score,
|
|
268
|
+
reason: `Score ${score}/100 below threshold ${requiredScore} for ${amountSats} sats transaction`,
|
|
269
|
+
riskLevel: score < 20 ? "high" : "medium",
|
|
270
|
+
};
|
|
271
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
"rootDir": "./src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"declaration": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*"],
|
|
14
|
+
"exclude": ["node_modules", "dist"]
|
|
15
|
+
}
|