@rubric-protocol/sdk 1.0.3 → 1.0.4
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 +82 -193
- package/dist/cli.d.ts +30 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +165 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +351 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +426 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +2 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -25
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +283 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +12 -43
- package/dist/background-queue.d.ts +0 -57
- package/dist/background-queue.d.ts.map +0 -1
- package/dist/background-queue.js +0 -164
- package/dist/background-queue.js.map +0 -1
- package/dist/ml-dsa-local.d.ts +0 -35
- package/dist/ml-dsa-local.d.ts.map +0 -1
- package/dist/ml-dsa-local.js +0 -151
- package/dist/ml-dsa-local.js.map +0 -1
- package/dist/plugins/langchain.d.ts +0 -30
- package/dist/plugins/langchain.d.ts.map +0 -1
- package/dist/plugins/langchain.js +0 -85
- package/dist/plugins/langchain.js.map +0 -1
- package/dist/plugins/openai-plugin.d.ts +0 -23
- package/dist/plugins/openai-plugin.d.ts.map +0 -1
- package/dist/plugins/openai-plugin.js +0 -72
- package/dist/plugins/openai-plugin.js.map +0 -1
- package/dist/proof-types.d.ts +0 -48
- package/dist/proof-types.d.ts.map +0 -1
- package/dist/proof-types.js +0 -105
- package/dist/proof-types.js.map +0 -1
- package/dist/proof-upgrade-manager.d.ts +0 -24
- package/dist/proof-upgrade-manager.d.ts.map +0 -1
- package/dist/proof-upgrade-manager.js +0 -103
- package/dist/proof-upgrade-manager.js.map +0 -1
- package/dist/rubric-client.d.ts +0 -46
- package/dist/rubric-client.d.ts.map +0 -1
- package/dist/rubric-client.js +0 -217
- package/dist/rubric-client.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,218 +1,107 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @tempus-protocol/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TypeScript SDK for TEMPUS Protocol — post-quantum attestation infrastructure for AI agents on Hedera.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Quick Start
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
\`\`\`typescript
|
|
8
|
+
import { TempusClient } from '@tempus-protocol/sdk';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
const tempus = new TempusClient({ baseUrl: 'https://api.tempusprotocol.com/v1', apiKey: 'your-key' });
|
|
11
|
+
const task = await tempus.tasks.submit({ type: 'compute', description: 'VWAP for HBAR/USD' });
|
|
12
|
+
const proof = await tempus.proof.get(task.attestation?.hcs_sequence!);
|
|
13
|
+
\`\`\`
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
## Installation
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Rubric anchor (5-10s) → HCS confirmed (~30s)
|
|
17
|
-
```
|
|
17
|
+
\`\`\`bash
|
|
18
|
+
npm install @tempus-protocol/sdk
|
|
19
|
+
\`\`\`
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
## Usage
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
### Submit a task and get attestation
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
npm install @langchain/core # for LangChain plugin
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Quickstart
|
|
39
|
-
|
|
40
|
-
```typescript
|
|
41
|
-
import { createRubricClient } from '@rubric-protocol/sdk';
|
|
42
|
-
|
|
43
|
-
const rubric = createRubricClient({
|
|
44
|
-
apiKey: process.env.RUBRIC_API_KEY!,
|
|
45
|
-
localSigning: true, // sign locally before network
|
|
46
|
-
backgroundQueue: true, // non-blocking flush
|
|
47
|
-
node: 'auto', // route to nearest healthy node
|
|
25
|
+
\`\`\`typescript
|
|
26
|
+
const task = await tempus.tasks.submit({
|
|
27
|
+
type: 'compute',
|
|
28
|
+
description: 'HBAR/USD volume-weighted average',
|
|
29
|
+
priority: 'high',
|
|
30
|
+
capabilities_required: ['price-feed', 'aggregation'],
|
|
31
|
+
parameters: {
|
|
32
|
+
pair: 'HBAR/USD',
|
|
33
|
+
sources: ['binance', 'coinbase', 'kraken'],
|
|
34
|
+
},
|
|
48
35
|
});
|
|
49
36
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
37
|
+
// Poll for completion
|
|
38
|
+
const detail = await tempus.tasks.get(task.id);
|
|
39
|
+
console.log(detail.result);
|
|
40
|
+
console.log(detail.attestation);
|
|
41
|
+
\`\`\`
|
|
56
42
|
|
|
57
|
-
|
|
58
|
-
console.log(proof.stage); // 'local'
|
|
43
|
+
### Register an agent
|
|
59
44
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
45
|
+
\`\`\`typescript
|
|
46
|
+
const agent = await tempus.agents.register({
|
|
47
|
+
name: 'My Price Agent',
|
|
48
|
+
capabilities: ['price-feed', 'aggregation'],
|
|
49
|
+
description: 'Fetches and aggregates crypto prices',
|
|
50
|
+
version: '1.0.0',
|
|
63
51
|
});
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## LangChain
|
|
69
|
-
|
|
70
|
-
Add one handler and every LLM call, agent action, chain, and tool invocation is automatically attested.
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
import { ChatOpenAI } from '@langchain/openai';
|
|
74
|
-
import { AgentExecutor } from 'langchain/agents';
|
|
75
|
-
import { RubricLangChainHandler } from '@rubric-protocol/sdk';
|
|
76
52
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
53
|
+
// Heartbeat loop
|
|
54
|
+
setInterval(() => {
|
|
55
|
+
tempus.agents.heartbeat(agent.id, { status: 'idle', max_concurrent: 3 });
|
|
56
|
+
}, 30000);
|
|
57
|
+
\`\`\`
|
|
58
|
+
|
|
59
|
+
### Verify an attestation
|
|
60
|
+
|
|
61
|
+
\`\`\`typescript
|
|
62
|
+
// Public — no API key required
|
|
63
|
+
const proof = await tempus.proof.get(73);
|
|
64
|
+
console.log(proof.verification.is_valid);
|
|
65
|
+
console.log(proof.verification.hedera_explorer_url);
|
|
66
|
+
\`\`\`
|
|
67
|
+
|
|
68
|
+
### Create a pipeline
|
|
69
|
+
|
|
70
|
+
\`\`\`typescript
|
|
71
|
+
const pipeline = await tempus.pipelines.create({
|
|
72
|
+
name: 'HBAR Price Oracle',
|
|
73
|
+
steps: [
|
|
74
|
+
{ name: 'fetch', type: 'fetch', capabilities_required: ['price-feed'] },
|
|
75
|
+
{ name: 'aggregate', type: 'compute', input_from: 'fetch' },
|
|
76
|
+
{ name: 'attest', type: 'attest', input_from: 'aggregate' },
|
|
77
|
+
],
|
|
83
78
|
});
|
|
79
|
+
await tempus.pipelines.start(pipeline.id);
|
|
80
|
+
\`\`\`
|
|
84
81
|
|
|
85
|
-
|
|
86
|
-
agent,
|
|
87
|
-
tools,
|
|
88
|
-
callbacks: [rubric], // that's it
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
await executor.invoke({ input: 'Analyze this transaction for fraud.' });
|
|
92
|
-
await rubric.shutdown(); // flush remaining queue on exit
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
---
|
|
96
|
-
|
|
97
|
-
## OpenAI
|
|
98
|
-
|
|
99
|
-
Drop-in wrapper — your existing code is unchanged.
|
|
100
|
-
|
|
101
|
-
```typescript
|
|
102
|
-
import OpenAI from 'openai';
|
|
103
|
-
import { withRubric } from '@rubric-protocol/sdk';
|
|
82
|
+
### Browse marketplace
|
|
104
83
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
84
|
+
\`\`\`typescript
|
|
85
|
+
const { agents } = await tempus.marketplace.browse({
|
|
86
|
+
capability: 'price-feed',
|
|
87
|
+
min_reputation: 70,
|
|
88
|
+
sort: 'reputation',
|
|
110
89
|
});
|
|
90
|
+
\`\`\`
|
|
111
91
|
|
|
112
|
-
|
|
113
|
-
const completion = await openai.chat.completions.create({
|
|
114
|
-
model: 'gpt-4o',
|
|
115
|
-
messages: [{ role: 'user', content: 'Should we approve this claim?' }],
|
|
116
|
-
});
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
## High-stakes decisions
|
|
122
|
-
|
|
123
|
-
For decisions requiring immediate confirmation (medical triage, credit denial, hiring rejection), await full HCS anchoring:
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
const confirmed = await rubric.attestAndConfirm({
|
|
127
|
-
agentId: 'triage-agent',
|
|
128
|
-
output: 'Patient flagged for immediate review.',
|
|
129
|
-
leafType: 'AGENT_OUTPUT',
|
|
130
|
-
risk: 'high',
|
|
131
|
-
}, 90_000); // timeout ms
|
|
92
|
+
## All Services
|
|
132
93
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
| Stage | When | What you have |
|
|
144
|
-
|---|---|---|
|
|
145
|
-
| `local` | <1ms | ML-DSA-65 signature + timestamp |
|
|
146
|
-
| `anchored` | 5–10s | Merkle root committed to Rubric |
|
|
147
|
-
| `confirmed` | ~30s | HCS sequence number, HashScan URL |
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
proof.onUpgrade('anchored', (p) => console.log(p.merkleRoot));
|
|
151
|
-
proof.onUpgrade('confirmed', (p) => console.log(p.hashScanUrl));
|
|
152
|
-
proof.onUpgrade('any', (p) => console.log(p.stage)); // fires on each upgrade
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
## Configuration
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
createRubricClient({
|
|
161
|
-
apiKey: string, // required — get one at rubric-protocol.com
|
|
162
|
-
node?: 'us'|'sg'|'jp'|'ca'|'eu'|'auto', // default: 'us'
|
|
163
|
-
localSigning?: boolean, // default: false
|
|
164
|
-
keystorePath?: string, // default: ~/.rubric/sdk-keypair.json
|
|
165
|
-
keystorePassphrase?: string, // AES-256-GCM encrypts the keystore
|
|
166
|
-
backgroundQueue?: boolean, // default: false
|
|
167
|
-
enterprise?: boolean, // uses /v1/tiered-attest (Merkle batching)
|
|
168
|
-
proofUpgrade?: boolean, // auto-poll for stage upgrades
|
|
169
|
-
timeout?: number, // HTTP timeout ms, default: 15000
|
|
170
|
-
})
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
---
|
|
174
|
-
|
|
175
|
-
## Nodes
|
|
176
|
-
|
|
177
|
-
The SDK routes to Rubric's global federation automatically when `node: 'auto'`.
|
|
178
|
-
|
|
179
|
-
| Region | Endpoint |
|
|
180
|
-
|---|---|
|
|
181
|
-
| US East | `https://rubric-protocol.com/verify` |
|
|
182
|
-
| Singapore | `https://sg.rubric-protocol.com/verify` |
|
|
183
|
-
| Japan | `https://jp.rubric-protocol.com/verify` |
|
|
184
|
-
| Canada | `https://ca.rubric-protocol.com/verify` |
|
|
185
|
-
| EU Central | `https://eu.rubric-protocol.com/verify` |
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## Security
|
|
190
|
-
|
|
191
|
-
- **ML-DSA-65** (NIST FIPS 204) — post-quantum signature scheme, same algorithm used server-side
|
|
192
|
-
- Keypairs stored at `~/.rubric/sdk-keypair.json` with optional AES-256-GCM encryption via passphrase
|
|
193
|
-
- Canonical JSON serialization ensures deterministic, tamper-evident signing
|
|
194
|
-
- All attestations anchored to [Hedera Consensus Service](https://hedera.com) — public, immutable, independently verifiable
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
## Requirements
|
|
199
|
-
|
|
200
|
-
- Node.js >= 18.0.0
|
|
201
|
-
- TypeScript >= 5.0 (if using TypeScript)
|
|
202
|
-
|
|
203
|
-
---
|
|
204
|
-
|
|
205
|
-
## Links
|
|
206
|
-
|
|
207
|
-
- [Documentation](https://rubric-protocol.com)
|
|
208
|
-
- [API Reference](https://rubric-protocol.com/docs)
|
|
209
|
-
- [HashScan](https://hashscan.io/testnet/topic/0.0.8207826) — live attestation stream
|
|
210
|
-
- [EU AI Act Article 12](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32024R1689)
|
|
211
|
-
|
|
212
|
-
---
|
|
94
|
+
| Service | Methods |
|
|
95
|
+
|---------|---------|
|
|
96
|
+
| \`tempus.health\` | \`check()\`, \`protocol()\`, \`stats()\` |
|
|
97
|
+
| \`tempus.tasks\` | \`list()\`, \`submit()\`, \`batch()\`, \`get()\`, \`bid()\`, \`assign()\`, \`submitResult()\`, \`cancel()\` |
|
|
98
|
+
| \`tempus.agents\` | \`list()\`, \`register()\`, \`get()\`, \`update()\`, \`delete()\`, \`heartbeat()\`, \`reputation()\` |
|
|
99
|
+
| \`tempus.proof\` | \`get()\` |
|
|
100
|
+
| \`tempus.pipelines\` | \`list()\`, \`create()\`, \`get()\`, \`start()\`, \`submitStepResult()\` |
|
|
101
|
+
| \`tempus.marketplace\` | \`browse()\`, \`getAgent()\`, \`getReviews()\`, \`submitReview()\`, \`upsertProfile()\`, \`categories()\`, \`featured()\`, \`stats()\` |
|
|
102
|
+
| \`tempus.analytics\` | \`get()\`, \`economics()\`, \`events()\`, \`leaderboard()\`, \`dashboard()\` |
|
|
103
|
+
| \`tempus.admin\` | \`listKeys()\`, \`createKey()\`, \`revokeKey()\`, \`retryQueue()\`, \`webhooks()\` |
|
|
213
104
|
|
|
214
105
|
## License
|
|
215
106
|
|
|
216
107
|
MIT — Echelon Intelligence Systems LLC
|
|
217
|
-
|
|
218
|
-
*Patent Pending*
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env npx ts-node --transpile-only
|
|
2
|
+
/**
|
|
3
|
+
* TEMPUS CLI
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* tempus verify <seq> - Verify attestation by sequence number
|
|
7
|
+
* tempus recent [n] - Show last N attestations (default 10)
|
|
8
|
+
* tempus status - Federation status
|
|
9
|
+
* tempus topic - Topic info
|
|
10
|
+
*/
|
|
11
|
+
declare const MIRROR = "https://testnet.mirrornode.hedera.com";
|
|
12
|
+
declare const TOPIC = "0.0.8207826";
|
|
13
|
+
declare const cmd: string, args: string[];
|
|
14
|
+
declare const COLORS: {
|
|
15
|
+
reset: string;
|
|
16
|
+
cyan: string;
|
|
17
|
+
green: string;
|
|
18
|
+
yellow: string;
|
|
19
|
+
red: string;
|
|
20
|
+
purple: string;
|
|
21
|
+
dim: string;
|
|
22
|
+
bold: string;
|
|
23
|
+
};
|
|
24
|
+
declare function c(color: string, text: string): string;
|
|
25
|
+
declare function fetchJSON(url: string): Promise<any>;
|
|
26
|
+
declare function verifyAttestation(seq: string): Promise<void>;
|
|
27
|
+
declare function showRecent(n: number): Promise<void>;
|
|
28
|
+
declare function showStatus(): Promise<void>;
|
|
29
|
+
declare function main(): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AAEH,QAAA,MAAM,MAAM,0CAA0C,CAAC;AACvD,QAAA,MAAM,KAAK,gBAAgB,CAAC;AAE5B,QAAA,MAAU,GAAG,UAAK,IAAI,UAAgB,CAAC;AAEvC,QAAA,MAAM,MAAM;;;;;;;;;CASX,CAAC;AAEF,iBAAS,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,iBAAe,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAIlD;AAED,iBAAe,iBAAiB,CAAC,GAAG,EAAE,MAAM,iBAwC3C;AAED,iBAAe,UAAU,CAAC,CAAC,EAAE,MAAM,iBAqBlC;AAED,iBAAe,UAAU,kBAkCxB;AAED,iBAAe,IAAI,kBAmClB"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env npx ts-node --transpile-only
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* TEMPUS CLI
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* tempus verify <seq> - Verify attestation by sequence number
|
|
8
|
+
* tempus recent [n] - Show last N attestations (default 10)
|
|
9
|
+
* tempus status - Federation status
|
|
10
|
+
* tempus topic - Topic info
|
|
11
|
+
*/
|
|
12
|
+
const MIRROR = 'https://testnet.mirrornode.hedera.com';
|
|
13
|
+
const TOPIC = '0.0.8207826';
|
|
14
|
+
const [, , cmd, ...args] = process.argv;
|
|
15
|
+
const COLORS = {
|
|
16
|
+
reset: '\x1b[0m',
|
|
17
|
+
cyan: '\x1b[36m',
|
|
18
|
+
green: '\x1b[32m',
|
|
19
|
+
yellow: '\x1b[33m',
|
|
20
|
+
red: '\x1b[31m',
|
|
21
|
+
purple: '\x1b[35m',
|
|
22
|
+
dim: '\x1b[2m',
|
|
23
|
+
bold: '\x1b[1m',
|
|
24
|
+
};
|
|
25
|
+
function c(color, text) {
|
|
26
|
+
return `${COLORS[color] || ''}${text}${COLORS.reset}`;
|
|
27
|
+
}
|
|
28
|
+
async function fetchJSON(url) {
|
|
29
|
+
const res = await fetch(url);
|
|
30
|
+
if (!res.ok)
|
|
31
|
+
throw new Error(`HTTP ${res.status}`);
|
|
32
|
+
return res.json();
|
|
33
|
+
}
|
|
34
|
+
async function verifyAttestation(seq) {
|
|
35
|
+
console.log(c('dim', `\nFetching sequence ${seq} from topic ${TOPIC}...\n`));
|
|
36
|
+
const data = await fetchJSON(`${MIRROR}/api/v1/topics/${TOPIC}/messages/${seq}`);
|
|
37
|
+
const payload = JSON.parse(Buffer.from(data.message, 'base64').toString());
|
|
38
|
+
const isFed = payload.type === 'federation_attestation';
|
|
39
|
+
const conf = payload.confidence || 'UNKNOWN';
|
|
40
|
+
const confColor = conf === 'FULL' ? 'green' : conf === 'HIGH' ? 'cyan' : conf === 'QUORUM' ? 'yellow' : 'red';
|
|
41
|
+
console.log(c('bold', ' ╔══════════════════════════════════════════╗'));
|
|
42
|
+
console.log(c('bold', ' ║') + c('green', ' ✓ VERIFIED ATTESTATION ') + c('bold', '║'));
|
|
43
|
+
console.log(c('bold', ' ╚══════════════════════════════════════════╝'));
|
|
44
|
+
console.log('');
|
|
45
|
+
console.log(` ${c('dim', 'Sequence:')} ${c('cyan', '#' + data.sequence_number)}`);
|
|
46
|
+
console.log(` ${c('dim', 'Type:')} ${payload.type || 'unknown'}`);
|
|
47
|
+
console.log(` ${c('dim', 'Epoch:')} ${payload.epoch ?? '-'}`);
|
|
48
|
+
console.log(` ${c('dim', 'View:')} ${payload.view ?? '-'}`);
|
|
49
|
+
console.log(` ${c('dim', 'Confidence:')} ${c(confColor, conf)}`);
|
|
50
|
+
console.log(` ${c('dim', 'Signers:')} ${payload.signer_count ?? '-'}`);
|
|
51
|
+
console.log(` ${c('dim', 'Leader:')} ${payload.leader_id || '-'}`);
|
|
52
|
+
console.log(` ${c('dim', 'Timestamp:')} ${payload.timestamp || '-'}`);
|
|
53
|
+
console.log(` ${c('dim', 'Data Type:')} ${payload.data_type || '-'}`);
|
|
54
|
+
if (payload.signers) {
|
|
55
|
+
console.log(` ${c('dim', 'Signer IDs:')} ${payload.signers.map((s) => c('purple', s)).join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
if (payload.federation_nodes) {
|
|
58
|
+
console.log(` ${c('dim', 'Fed Nodes:')} ${payload.federation_nodes.join(', ')}`);
|
|
59
|
+
}
|
|
60
|
+
if (payload.sources) {
|
|
61
|
+
console.log(` ${c('dim', 'Sources:')}`);
|
|
62
|
+
payload.sources.forEach((s) => {
|
|
63
|
+
console.log(` ${c('dim', '•')} ${s.provider} (weight: ${s.weight})`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
console.log('');
|
|
67
|
+
console.log(` ${c('dim', 'Explorer:')} ${c('cyan', `https://hashscan.io/testnet/topic/${TOPIC}/${data.sequence_number}`)}`);
|
|
68
|
+
console.log('');
|
|
69
|
+
}
|
|
70
|
+
async function showRecent(n) {
|
|
71
|
+
console.log(c('dim', `\nFetching last ${n} attestations from topic ${TOPIC}...\n`));
|
|
72
|
+
const data = await fetchJSON(`${MIRROR}/api/v1/topics/${TOPIC}/messages?order=desc&limit=${n}`);
|
|
73
|
+
console.log(c('bold', ' Seq Type Epoch Signers Confidence'));
|
|
74
|
+
console.log(c('dim', ' ───── ───────────────────────── ───── ─────── ──────────'));
|
|
75
|
+
for (const m of (data.messages || [])) {
|
|
76
|
+
try {
|
|
77
|
+
const p = JSON.parse(Buffer.from(m.message, 'base64').toString());
|
|
78
|
+
const conf = p.confidence || '-';
|
|
79
|
+
const confColor = conf === 'FULL' ? 'green' : conf === 'HIGH' ? 'cyan' : conf === 'QUORUM' ? 'yellow' : 'red';
|
|
80
|
+
const type = (p.type || 'unknown').padEnd(25);
|
|
81
|
+
const epoch = String(p.epoch ?? '-').padEnd(5);
|
|
82
|
+
const signers = String(p.signer_count ?? '-').padEnd(7);
|
|
83
|
+
console.log(` ${c('cyan', '#' + String(m.sequence_number).padEnd(4))} ${type} ${epoch} ${signers} ${c(confColor, conf)}`);
|
|
84
|
+
}
|
|
85
|
+
catch { }
|
|
86
|
+
}
|
|
87
|
+
console.log('');
|
|
88
|
+
}
|
|
89
|
+
async function showStatus() {
|
|
90
|
+
const data = await fetchJSON(`${MIRROR}/api/v1/topics/${TOPIC}/messages?order=desc&limit=50`);
|
|
91
|
+
let fedCount = 0;
|
|
92
|
+
let maxEpoch = 0;
|
|
93
|
+
let latestConf = '';
|
|
94
|
+
const signerSets = new Set();
|
|
95
|
+
const confs = {};
|
|
96
|
+
for (const m of (data.messages || [])) {
|
|
97
|
+
try {
|
|
98
|
+
const p = JSON.parse(Buffer.from(m.message, 'base64').toString());
|
|
99
|
+
if (p.type === 'federation_attestation') {
|
|
100
|
+
fedCount++;
|
|
101
|
+
maxEpoch = Math.max(maxEpoch, p.epoch || 0);
|
|
102
|
+
if (!latestConf)
|
|
103
|
+
latestConf = p.confidence || '';
|
|
104
|
+
(p.signers || []).forEach((s) => signerSets.add(s));
|
|
105
|
+
const c = p.confidence || 'UNKNOWN';
|
|
106
|
+
confs[c] = (confs[c] || 0) + 1;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch { }
|
|
110
|
+
}
|
|
111
|
+
console.log('');
|
|
112
|
+
console.log(c('bold', ' TEMPUS Federation Status'));
|
|
113
|
+
console.log(c('dim', ' ───────────────────────────'));
|
|
114
|
+
console.log(` ${c('dim', 'Topic:')} ${c('cyan', TOPIC)}`);
|
|
115
|
+
console.log(` ${c('dim', 'Network:')} Testnet`);
|
|
116
|
+
console.log(` ${c('dim', 'Total Messages:')} ${data.messages?.length || 0} (last 50)`);
|
|
117
|
+
console.log(` ${c('dim', 'Federation Atts:')} ${c('green', String(fedCount))}`);
|
|
118
|
+
console.log(` ${c('dim', 'Latest Epoch:')} ${c('purple', String(maxEpoch))}`);
|
|
119
|
+
console.log(` ${c('dim', 'Latest Confidence:')} ${latestConf}`);
|
|
120
|
+
console.log(` ${c('dim', 'Known Signers:')} ${Array.from(signerSets).map(s => c('purple', s)).join(', ')}`);
|
|
121
|
+
console.log(` ${c('dim', 'Confidence Dist:')} ${Object.entries(confs).map(([k, v]) => `${k}: ${v}`).join(', ')}`);
|
|
122
|
+
console.log('');
|
|
123
|
+
}
|
|
124
|
+
async function main() {
|
|
125
|
+
try {
|
|
126
|
+
switch (cmd) {
|
|
127
|
+
case 'verify':
|
|
128
|
+
case 'v':
|
|
129
|
+
if (!args[0]) {
|
|
130
|
+
console.log('Usage: tempus verify <seq>');
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
await verifyAttestation(args[0]);
|
|
134
|
+
break;
|
|
135
|
+
case 'recent':
|
|
136
|
+
case 'r':
|
|
137
|
+
await showRecent(parseInt(args[0]) || 10);
|
|
138
|
+
break;
|
|
139
|
+
case 'status':
|
|
140
|
+
case 's':
|
|
141
|
+
await showStatus();
|
|
142
|
+
break;
|
|
143
|
+
case 'topic':
|
|
144
|
+
case 't':
|
|
145
|
+
console.log(`\n Topic: ${c('cyan', TOPIC)}`);
|
|
146
|
+
console.log(` Explorer: ${c('cyan', `https://hashscan.io/testnet/topic/${TOPIC}`)}\n`);
|
|
147
|
+
break;
|
|
148
|
+
default:
|
|
149
|
+
console.log('');
|
|
150
|
+
console.log(c('bold', ' TEMPUS CLI'));
|
|
151
|
+
console.log(c('dim', ' ─────────────────'));
|
|
152
|
+
console.log(` ${c('cyan', 'tempus verify <seq>')} Verify attestation`);
|
|
153
|
+
console.log(` ${c('cyan', 'tempus recent [n]')} Last N attestations`);
|
|
154
|
+
console.log(` ${c('cyan', 'tempus status')} Federation status`);
|
|
155
|
+
console.log(` ${c('cyan', 'tempus topic')} Topic info`);
|
|
156
|
+
console.log('');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
console.error(c('red', `\n Error: ${err.message}\n`));
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
main();
|
|
165
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|