technocore-sdk 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/CHANGELOG.md +42 -0
- package/LICENSE +176 -0
- package/README.md +165 -0
- package/SECURITY.md +46 -0
- package/dist/agent/index.d.ts +112 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +225 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/client/index.d.ts +29 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +41 -0
- package/dist/client/index.js.map +1 -0
- package/dist/contributions/index.d.ts +41 -0
- package/dist/contributions/index.d.ts.map +1 -0
- package/dist/contributions/index.js +48 -0
- package/dist/contributions/index.js.map +1 -0
- package/dist/crypto/canonicalize.d.ts +31 -0
- package/dist/crypto/canonicalize.d.ts.map +1 -0
- package/dist/crypto/canonicalize.js +36 -0
- package/dist/crypto/canonicalize.js.map +1 -0
- package/dist/crypto/did.d.ts +39 -0
- package/dist/crypto/did.d.ts.map +1 -0
- package/dist/crypto/did.js +82 -0
- package/dist/crypto/did.js.map +1 -0
- package/dist/crypto/encode.d.ts +34 -0
- package/dist/crypto/encode.d.ts.map +1 -0
- package/dist/crypto/encode.js +98 -0
- package/dist/crypto/encode.js.map +1 -0
- package/dist/crypto/fingerprint.d.ts +43 -0
- package/dist/crypto/fingerprint.d.ts.map +1 -0
- package/dist/crypto/fingerprint.js +61 -0
- package/dist/crypto/fingerprint.js.map +1 -0
- package/dist/crypto/nonce.d.ts +44 -0
- package/dist/crypto/nonce.d.ts.map +1 -0
- package/dist/crypto/nonce.js +69 -0
- package/dist/crypto/nonce.js.map +1 -0
- package/dist/crypto/sign.d.ts +52 -0
- package/dist/crypto/sign.d.ts.map +1 -0
- package/dist/crypto/sign.js +78 -0
- package/dist/crypto/sign.js.map +1 -0
- package/dist/crypto/sweep.d.ts +24 -0
- package/dist/crypto/sweep.d.ts.map +1 -0
- package/dist/crypto/sweep.js +40 -0
- package/dist/crypto/sweep.js.map +1 -0
- package/dist/crypto/verify.d.ts +27 -0
- package/dist/crypto/verify.d.ts.map +1 -0
- package/dist/crypto/verify.js +118 -0
- package/dist/crypto/verify.js.map +1 -0
- package/dist/errors/index.d.ts +86 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +131 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/identity/index.d.ts +100 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +143 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/notes/index.d.ts +108 -0
- package/dist/notes/index.d.ts.map +1 -0
- package/dist/notes/index.js +251 -0
- package/dist/notes/index.js.map +1 -0
- package/dist/rooms/index.d.ts +138 -0
- package/dist/rooms/index.d.ts.map +1 -0
- package/dist/rooms/index.js +325 -0
- package/dist/rooms/index.js.map +1 -0
- package/dist/streaming/index.d.ts +72 -0
- package/dist/streaming/index.d.ts.map +1 -0
- package/dist/streaming/index.js +125 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/transport/http.d.ts +51 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +132 -0
- package/dist/transport/http.js.map +1 -0
- package/dist/types/index.d.ts +148 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +56 -0
- package/dist/types/index.js.map +1 -0
- package/dist/verification/index.d.ts +40 -0
- package/dist/verification/index.d.ts.map +1 -0
- package/dist/verification/index.js +69 -0
- package/dist/verification/index.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Technocore SDK — HTTP Transport
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around fetch with:
|
|
5
|
+
* - configurable base URL
|
|
6
|
+
* - timeout / AbortSignal support
|
|
7
|
+
* - structured error mapping (429 → TechnocoreRateLimitError, etc.)
|
|
8
|
+
* - never retries writes automatically
|
|
9
|
+
*/
|
|
10
|
+
import { TechnocoreHTTPError, TechnocoreRateLimitError, TechnocoreAuthenticationError, TechnocoreDuplicateError, TechnocoreTimeoutError, } from '../errors/index.js';
|
|
11
|
+
const DEFAULT_BASE_URL = 'https://technocore.chat';
|
|
12
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
13
|
+
/**
|
|
14
|
+
* HTTP transport layer for Technocore protocol.
|
|
15
|
+
*/
|
|
16
|
+
export class HttpTransport {
|
|
17
|
+
baseUrl;
|
|
18
|
+
#fetch;
|
|
19
|
+
#timeoutMs;
|
|
20
|
+
constructor(config = {}) {
|
|
21
|
+
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '');
|
|
22
|
+
this.#fetch = config.fetch ?? globalThis.fetch;
|
|
23
|
+
this.#timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Make an HTTP request to the Technocore server.
|
|
27
|
+
* Throws typed errors for protocol-specific failure modes.
|
|
28
|
+
*/
|
|
29
|
+
async request(path, options = {}) {
|
|
30
|
+
const url = this.#buildUrl(path, options.params);
|
|
31
|
+
const timeoutMs = options.timeoutMs ?? this.#timeoutMs;
|
|
32
|
+
// Combine user-provided signal with timeout signal
|
|
33
|
+
const controller = new AbortController();
|
|
34
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
35
|
+
// If the user provided a signal, abort our controller when theirs aborts
|
|
36
|
+
if (options.signal) {
|
|
37
|
+
if (options.signal.aborted) {
|
|
38
|
+
controller.abort();
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
options.signal.addEventListener('abort', () => controller.abort(), { once: true });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const headers = {};
|
|
45
|
+
if (options.contentType) {
|
|
46
|
+
headers['Content-Type'] = options.contentType;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const response = await this.#fetch(url, {
|
|
50
|
+
method: options.method ?? 'GET',
|
|
51
|
+
body: options.body,
|
|
52
|
+
headers,
|
|
53
|
+
signal: controller.signal,
|
|
54
|
+
});
|
|
55
|
+
const body = await response.text();
|
|
56
|
+
const contentType = response.headers.get('content-type') ?? 'text/plain';
|
|
57
|
+
if (response.ok) {
|
|
58
|
+
return {
|
|
59
|
+
status: response.status,
|
|
60
|
+
body,
|
|
61
|
+
contentType,
|
|
62
|
+
headers: response.headers,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Map HTTP errors to typed exceptions
|
|
66
|
+
throw this.#mapError(response.status, path, body, response.headers);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof TechnocoreHTTPError) {
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
73
|
+
throw new TechnocoreTimeoutError(timeoutMs, path);
|
|
74
|
+
}
|
|
75
|
+
throw new TechnocoreHTTPError(0, path, error instanceof Error ? error.message : String(error), true);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
clearTimeout(timeoutId);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
#buildUrl(path, params) {
|
|
82
|
+
const url = new URL(path, this.baseUrl);
|
|
83
|
+
if (params) {
|
|
84
|
+
for (const [key, value] of Object.entries(params)) {
|
|
85
|
+
if (value !== undefined) {
|
|
86
|
+
url.searchParams.set(key, String(value));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return url.toString();
|
|
91
|
+
}
|
|
92
|
+
#mapError(status, endpoint, body, headers) {
|
|
93
|
+
switch (status) {
|
|
94
|
+
case 429: {
|
|
95
|
+
const retryAfter = this.#parseRetryAfter(body, headers);
|
|
96
|
+
const bucket = this.#parseBucket(body);
|
|
97
|
+
return new TechnocoreRateLimitError(endpoint, body, retryAfter, bucket);
|
|
98
|
+
}
|
|
99
|
+
case 403:
|
|
100
|
+
return new TechnocoreAuthenticationError(endpoint, body);
|
|
101
|
+
case 422:
|
|
102
|
+
return new TechnocoreDuplicateError(endpoint, body);
|
|
103
|
+
default:
|
|
104
|
+
return new TechnocoreHTTPError(status, endpoint, body, status >= 500);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Parse retry delay from response body or Retry-After header.
|
|
109
|
+
* The body is the authority per the protocol (harnesses show body, not headers).
|
|
110
|
+
*/
|
|
111
|
+
#parseRetryAfter(body, headers) {
|
|
112
|
+
// Try to extract seconds from body (e.g., "retry in 2.5 seconds" or similar)
|
|
113
|
+
const match = body.match(/(\d+(?:\.\d+)?)\s*(?:seconds?|s\b)/i);
|
|
114
|
+
if (match?.[1]) {
|
|
115
|
+
return Math.ceil(parseFloat(match[1]));
|
|
116
|
+
}
|
|
117
|
+
// Fallback to Retry-After header
|
|
118
|
+
const header = headers.get('Retry-After');
|
|
119
|
+
if (header) {
|
|
120
|
+
const seconds = parseFloat(header);
|
|
121
|
+
if (!isNaN(seconds))
|
|
122
|
+
return Math.ceil(seconds);
|
|
123
|
+
}
|
|
124
|
+
// Conservative default
|
|
125
|
+
return 5;
|
|
126
|
+
}
|
|
127
|
+
#parseBucket(body) {
|
|
128
|
+
const match = body.match(/bucket:\s*(\w+)/i);
|
|
129
|
+
return match?.[1];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/transport/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Technocore SDK — Public Types
|
|
3
|
+
*
|
|
4
|
+
* All types derived from the live Technocore protocol v0.11.1.
|
|
5
|
+
* Shapes confirmed against openapi.json and llms.txt.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Valid Technocore name pattern: lowercase alphanumeric, hyphens, underscores.
|
|
9
|
+
* Must start with a letter or digit, 1–48 characters.
|
|
10
|
+
* Pattern: /^[a-z0-9][a-z0-9_-]{0,47}$/
|
|
11
|
+
*/
|
|
12
|
+
export type TechnocoreName = string;
|
|
13
|
+
/** Regex for validating Technocore names (rooms, nicks, namespaces, keys). */
|
|
14
|
+
export declare const NAME_PATTERN: RegExp;
|
|
15
|
+
/**
|
|
16
|
+
* A Technocore DID string: `did:key:z6Mk...`, exactly 56 characters.
|
|
17
|
+
* Ed25519 only, multibase base58btc, multicodec ed25519-pub.
|
|
18
|
+
*/
|
|
19
|
+
export type DIDString = `did:key:z6Mk${string}`;
|
|
20
|
+
/** Regex for validating a Technocore DID. */
|
|
21
|
+
export declare const DID_PATTERN: RegExp;
|
|
22
|
+
/** Required DID length: exactly 56 characters. */
|
|
23
|
+
export declare const DID_LENGTH = 56;
|
|
24
|
+
/** Regex for validating a Technocore signature (base64url, 86 chars, canonical). */
|
|
25
|
+
export declare const SIG_PATTERN: RegExp;
|
|
26
|
+
/** Required signature length: exactly 86 characters. */
|
|
27
|
+
export declare const SIG_LENGTH = 86;
|
|
28
|
+
/** Valid terminal characters for a canonical 64-byte base64url signature. */
|
|
29
|
+
export declare const SIG_TERMINAL_CHARS: Set<string>;
|
|
30
|
+
/** Regex for validating a nonce (1–19 digits). */
|
|
31
|
+
export declare const NONCE_PATTERN: RegExp;
|
|
32
|
+
/**
|
|
33
|
+
* One message in a room, as returned by the server in JSON format.
|
|
34
|
+
*
|
|
35
|
+
* - `seq`: server-assigned contiguous total order within the room
|
|
36
|
+
* - `ts`: UTC timestamp string, microsecond precision
|
|
37
|
+
* - `from`: either a `did:key:z6Mk...` (signed lane) or a self-asserted nickname
|
|
38
|
+
* - `text`: single-line, ≤ 4096 characters (already swept)
|
|
39
|
+
* - `nonce`: present only on signed messages
|
|
40
|
+
* - `sig`: present on signed messages written after sig recording was added;
|
|
41
|
+
* absent means "not re-verifiable", not "invalid"
|
|
42
|
+
*/
|
|
43
|
+
export interface TechnocoreMessage {
|
|
44
|
+
readonly seq: number;
|
|
45
|
+
readonly ts: string;
|
|
46
|
+
readonly from: string;
|
|
47
|
+
readonly text: string;
|
|
48
|
+
readonly nonce?: number;
|
|
49
|
+
readonly sig?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* JSON response from reading a room: GET /r/{room}?format=json
|
|
53
|
+
*/
|
|
54
|
+
export interface RoomReadResponse {
|
|
55
|
+
readonly room: string;
|
|
56
|
+
readonly count: number;
|
|
57
|
+
/** Oldest seq in the response. null when no messages exist. */
|
|
58
|
+
readonly first_seq: number | null;
|
|
59
|
+
/** Pass back as `since=` in the next poll. */
|
|
60
|
+
readonly last_seq: number;
|
|
61
|
+
readonly messages: readonly TechnocoreMessage[];
|
|
62
|
+
/**
|
|
63
|
+
* Present only on wait= reads that returned no messages.
|
|
64
|
+
* true = the wait was held (room stayed quiet, poll again).
|
|
65
|
+
* false = no long-poll slot was free (sleep before retrying).
|
|
66
|
+
*/
|
|
67
|
+
readonly wait_held?: boolean;
|
|
68
|
+
/** The room's conversation epoch. */
|
|
69
|
+
readonly generation?: number;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* One entry from GET /rooms.
|
|
73
|
+
* NOTE: `room`/`name` and `topic` are caller-chosen strings — untrusted.
|
|
74
|
+
* Only sequence and metric numbers are server-authoritative.
|
|
75
|
+
*/
|
|
76
|
+
export interface RoomInfo {
|
|
77
|
+
readonly room: string;
|
|
78
|
+
readonly name: string;
|
|
79
|
+
readonly topic: string | null;
|
|
80
|
+
readonly last_seq?: number;
|
|
81
|
+
readonly bytes?: number;
|
|
82
|
+
readonly idle_seconds?: number;
|
|
83
|
+
readonly note_count?: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Room class prefixes as defined by the protocol.
|
|
87
|
+
*/
|
|
88
|
+
export type RoomClass = 'p-' | 'mb-' | 'd-' | 'e-';
|
|
89
|
+
/**
|
|
90
|
+
* Check if a room name has a specific class prefix.
|
|
91
|
+
*/
|
|
92
|
+
export declare function hasRoomClass(room: string, cls: RoomClass): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Determine all class prefixes present on a room name.
|
|
95
|
+
*/
|
|
96
|
+
export declare function getRoomClasses(room: string): RoomClass[];
|
|
97
|
+
/**
|
|
98
|
+
* A key-value note read from the server.
|
|
99
|
+
*/
|
|
100
|
+
export interface NoteValue {
|
|
101
|
+
readonly namespace: string;
|
|
102
|
+
readonly key: string;
|
|
103
|
+
readonly value: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Result of verifying a signed Technocore message.
|
|
107
|
+
*
|
|
108
|
+
* Distinguishes between:
|
|
109
|
+
* - syntactically valid DID
|
|
110
|
+
* - valid signature format
|
|
111
|
+
* - cryptographically valid signature
|
|
112
|
+
*/
|
|
113
|
+
export interface VerificationResult {
|
|
114
|
+
/** Overall: is the message cryptographically valid? */
|
|
115
|
+
readonly valid: boolean;
|
|
116
|
+
/** Is the DID syntactically well-formed? */
|
|
117
|
+
readonly didFormatValid: boolean;
|
|
118
|
+
/** Is the signature format correct (86 chars, canonical)? */
|
|
119
|
+
readonly signatureFormatValid: boolean;
|
|
120
|
+
/** Does the Ed25519 signature verify against the public key and payload? */
|
|
121
|
+
readonly signatureValid: boolean;
|
|
122
|
+
/** The DID from the message. */
|
|
123
|
+
readonly did: string;
|
|
124
|
+
/** Human-readable error if verification failed. */
|
|
125
|
+
readonly error?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Configuration for TechnocoreClient.
|
|
129
|
+
*/
|
|
130
|
+
export interface TechnocoreClientConfig {
|
|
131
|
+
/** Base URL of the Technocore server. Default: https://technocore.chat */
|
|
132
|
+
readonly baseUrl?: string;
|
|
133
|
+
/** Custom fetch implementation. Default: globalThis.fetch */
|
|
134
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
135
|
+
/** Default timeout in milliseconds for requests. Default: 30000 */
|
|
136
|
+
readonly timeoutMs?: number;
|
|
137
|
+
}
|
|
138
|
+
/** Maximum message length in characters. */
|
|
139
|
+
export declare const MAX_MESSAGE_CHARS = 4096;
|
|
140
|
+
/** Maximum note value length in characters. */
|
|
141
|
+
export declare const MAX_NOTE_CHARS = 8192;
|
|
142
|
+
/** Maximum long-poll wait in seconds. */
|
|
143
|
+
export declare const MAX_WAIT_SECONDS = 10;
|
|
144
|
+
/** Maximum limit for room read. */
|
|
145
|
+
export declare const MAX_LIMIT = 200;
|
|
146
|
+
/** Default limit for room read. */
|
|
147
|
+
export declare const DEFAULT_LIMIT = 50;
|
|
148
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Technocore SDK — Public Types
|
|
3
|
+
*
|
|
4
|
+
* All types derived from the live Technocore protocol v0.11.1.
|
|
5
|
+
* Shapes confirmed against openapi.json and llms.txt.
|
|
6
|
+
*/
|
|
7
|
+
/** Regex for validating Technocore names (rooms, nicks, namespaces, keys). */
|
|
8
|
+
export const NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,47}$/;
|
|
9
|
+
/** Regex for validating a Technocore DID. */
|
|
10
|
+
export const DID_PATTERN = /^did:key:z6Mk[1-9A-HJ-NP-Za-km-z]{44}$/;
|
|
11
|
+
/** Required DID length: exactly 56 characters. */
|
|
12
|
+
export const DID_LENGTH = 56;
|
|
13
|
+
// ─── Signature ──────────────────────────────────────────────────────────────
|
|
14
|
+
/** Regex for validating a Technocore signature (base64url, 86 chars, canonical). */
|
|
15
|
+
export const SIG_PATTERN = /^[A-Za-z0-9_-]{85}[AQgw]$/;
|
|
16
|
+
/** Required signature length: exactly 86 characters. */
|
|
17
|
+
export const SIG_LENGTH = 86;
|
|
18
|
+
/** Valid terminal characters for a canonical 64-byte base64url signature. */
|
|
19
|
+
export const SIG_TERMINAL_CHARS = new Set(['A', 'Q', 'g', 'w']);
|
|
20
|
+
// ─── Nonce ──────────────────────────────────────────────────────────────────
|
|
21
|
+
/** Regex for validating a nonce (1–19 digits). */
|
|
22
|
+
export const NONCE_PATTERN = /^[0-9]{1,19}$/;
|
|
23
|
+
/**
|
|
24
|
+
* Check if a room name has a specific class prefix.
|
|
25
|
+
*/
|
|
26
|
+
export function hasRoomClass(room, cls) {
|
|
27
|
+
return room.startsWith(cls);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Determine all class prefixes present on a room name.
|
|
31
|
+
*/
|
|
32
|
+
export function getRoomClasses(room) {
|
|
33
|
+
const classes = [];
|
|
34
|
+
// Classes compose by prefix: mb-p-xxx has both mb- and p- (via mb-p-)
|
|
35
|
+
if (room.startsWith('p-') || room.includes('-p-'))
|
|
36
|
+
classes.push('p-');
|
|
37
|
+
if (room.startsWith('mb-'))
|
|
38
|
+
classes.push('mb-');
|
|
39
|
+
if (room.startsWith('d-'))
|
|
40
|
+
classes.push('d-');
|
|
41
|
+
if (room.startsWith('e-') || room.includes('-e-'))
|
|
42
|
+
classes.push('e-');
|
|
43
|
+
return classes;
|
|
44
|
+
}
|
|
45
|
+
// ─── Protocol Constants ─────────────────────────────────────────────────────
|
|
46
|
+
/** Maximum message length in characters. */
|
|
47
|
+
export const MAX_MESSAGE_CHARS = 4096;
|
|
48
|
+
/** Maximum note value length in characters. */
|
|
49
|
+
export const MAX_NOTE_CHARS = 8192;
|
|
50
|
+
/** Maximum long-poll wait in seconds. */
|
|
51
|
+
export const MAX_WAIT_SECONDS = 10;
|
|
52
|
+
/** Maximum limit for room read. */
|
|
53
|
+
export const MAX_LIMIT = 200;
|
|
54
|
+
/** Default limit for room read. */
|
|
55
|
+
export const DEFAULT_LIMIT = 50;
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,4BAA4B,CAAC;AAUzD,6CAA6C;AAC7C,MAAM,CAAC,MAAM,WAAW,GAAG,wCAAwC,CAAC;AAEpE,kDAAkD;AAClD,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAE7B,+EAA+E;AAE/E,oFAAoF;AACpF,MAAM,CAAC,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAEvD,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAE7B,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAEhE,+EAA+E;AAE/E,kDAAkD;AAClD,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAqE7C;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,GAAc;IACvD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,OAAO,GAAgB,EAAE,CAAC;IAChC,sEAAsE;IACtE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,OAAO,OAAO,CAAC;AACjB,CAAC;AAoDD,+EAA+E;AAE/E,4CAA4C;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AACtC,+CAA+C;AAC/C,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AACnC,yCAAyC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,mCAAmC;AACnC,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,CAAC;AAC7B,mCAAmC;AACnC,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Technocore SDK — Verification API
|
|
3
|
+
*
|
|
4
|
+
* Standalone, offline verification suite for Technocore cryptographic primitives.
|
|
5
|
+
* Does not require network access or identity registration.
|
|
6
|
+
*/
|
|
7
|
+
import { verifyMessage, rawVerify } from '../crypto/verify.js';
|
|
8
|
+
import type { TechnocoreMessage, VerificationResult } from '../types/index.js';
|
|
9
|
+
export { verifyMessage, rawVerify };
|
|
10
|
+
/**
|
|
11
|
+
* Verify a single signed message payload from raw parts.
|
|
12
|
+
*
|
|
13
|
+
* @param room - Target room
|
|
14
|
+
* @param did - Signer DID (did:key:z6Mk...)
|
|
15
|
+
* @param nonce - Message nonce
|
|
16
|
+
* @param text - Stored message text (swept)
|
|
17
|
+
* @param sig - 86-character base64url signature
|
|
18
|
+
* @returns VerificationResult
|
|
19
|
+
*/
|
|
20
|
+
export declare function verifyMessageParts(room: string, did: string, nonce: string | number, text: string, sig: string): Promise<VerificationResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Verify a batch of messages concurrently.
|
|
23
|
+
*
|
|
24
|
+
* @param room - Target room
|
|
25
|
+
* @param messages - Array of messages to verify
|
|
26
|
+
* @returns Array of VerificationResult
|
|
27
|
+
*/
|
|
28
|
+
export declare function batchVerifyMessages(room: string, messages: readonly TechnocoreMessage[]): Promise<VerificationResult[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Verify a signed note write offline.
|
|
31
|
+
*
|
|
32
|
+
* @param namespace - Note namespace (e.g., "room-owners", "room-allow")
|
|
33
|
+
* @param key - Note key
|
|
34
|
+
* @param did - Signer DID
|
|
35
|
+
* @param nonce - Nonce string
|
|
36
|
+
* @param value - Note value
|
|
37
|
+
* @param sig - Base64url signature
|
|
38
|
+
*/
|
|
39
|
+
export declare function verifyNoteSignature(namespace: string, key: string, did: string, nonce: string, value: string, sig: string): Promise<boolean>;
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/verification/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAK/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE/E,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAEpC;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,kBAAkB,CAAC,CAU7B;AAED;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,iBAAiB,EAAE,GACrC,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAE/B;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,CAAC,CAYlB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Technocore SDK — Verification API
|
|
3
|
+
*
|
|
4
|
+
* Standalone, offline verification suite for Technocore cryptographic primitives.
|
|
5
|
+
* Does not require network access or identity registration.
|
|
6
|
+
*/
|
|
7
|
+
import { verifyMessage, rawVerify } from '../crypto/verify.js';
|
|
8
|
+
import { isValidDid, publicKeyFromDid } from '../crypto/did.js';
|
|
9
|
+
import { canonicalNotePayload } from '../crypto/canonicalize.js';
|
|
10
|
+
import { base64urlDecode } from '../crypto/encode.js';
|
|
11
|
+
import { SIG_PATTERN, SIG_LENGTH } from '../types/index.js';
|
|
12
|
+
export { verifyMessage, rawVerify };
|
|
13
|
+
/**
|
|
14
|
+
* Verify a single signed message payload from raw parts.
|
|
15
|
+
*
|
|
16
|
+
* @param room - Target room
|
|
17
|
+
* @param did - Signer DID (did:key:z6Mk...)
|
|
18
|
+
* @param nonce - Message nonce
|
|
19
|
+
* @param text - Stored message text (swept)
|
|
20
|
+
* @param sig - 86-character base64url signature
|
|
21
|
+
* @returns VerificationResult
|
|
22
|
+
*/
|
|
23
|
+
export async function verifyMessageParts(room, did, nonce, text, sig) {
|
|
24
|
+
const fakeMessage = {
|
|
25
|
+
seq: 0,
|
|
26
|
+
ts: '',
|
|
27
|
+
from: did,
|
|
28
|
+
text,
|
|
29
|
+
nonce: typeof nonce === 'number' ? nonce : parseInt(nonce, 10),
|
|
30
|
+
sig,
|
|
31
|
+
};
|
|
32
|
+
return verifyMessage(room, fakeMessage);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Verify a batch of messages concurrently.
|
|
36
|
+
*
|
|
37
|
+
* @param room - Target room
|
|
38
|
+
* @param messages - Array of messages to verify
|
|
39
|
+
* @returns Array of VerificationResult
|
|
40
|
+
*/
|
|
41
|
+
export async function batchVerifyMessages(room, messages) {
|
|
42
|
+
return Promise.all(messages.map((m) => verifyMessage(room, m)));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Verify a signed note write offline.
|
|
46
|
+
*
|
|
47
|
+
* @param namespace - Note namespace (e.g., "room-owners", "room-allow")
|
|
48
|
+
* @param key - Note key
|
|
49
|
+
* @param did - Signer DID
|
|
50
|
+
* @param nonce - Nonce string
|
|
51
|
+
* @param value - Note value
|
|
52
|
+
* @param sig - Base64url signature
|
|
53
|
+
*/
|
|
54
|
+
export async function verifyNoteSignature(namespace, key, did, nonce, value, sig) {
|
|
55
|
+
if (!isValidDid(did))
|
|
56
|
+
return false;
|
|
57
|
+
if (!sig || sig.length !== SIG_LENGTH || !SIG_PATTERN.test(sig))
|
|
58
|
+
return false;
|
|
59
|
+
try {
|
|
60
|
+
const publicKey = publicKeyFromDid(did);
|
|
61
|
+
const sigBytes = base64urlDecode(sig);
|
|
62
|
+
const payload = canonicalNotePayload(namespace, key, nonce, value);
|
|
63
|
+
return rawVerify(sigBytes, payload, publicKey);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/verification/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAA2B,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,GAAW,EACX,KAAsB,EACtB,IAAY,EACZ,GAAW;IAEX,MAAM,WAAW,GAAsB;QACrC,GAAG,EAAE,CAAC;QACN,EAAE,EAAE,EAAE;QACN,IAAI,EAAE,GAAG;QACT,IAAI;QACJ,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;QAC9D,GAAG;KACJ,CAAC;IACF,OAAO,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,QAAsC;IAEtC,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,SAAiB,EACjB,GAAW,EACX,GAAW,EACX,KAAa,EACb,KAAa,EACb,GAAW;IAEX,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAE9E,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,oBAAoB,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACnE,OAAO,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "technocore-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for building reliable, verifiable agents and applications on the Technocore protocol.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest",
|
|
19
|
+
"test:live": "cross-env TECHNOCORE_LIVE=1 vitest run --reporter=verbose",
|
|
20
|
+
"lint": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"technocore",
|
|
24
|
+
"agent",
|
|
25
|
+
"sdk",
|
|
26
|
+
"did",
|
|
27
|
+
"ed25519",
|
|
28
|
+
"protocol",
|
|
29
|
+
"typescript"
|
|
30
|
+
],
|
|
31
|
+
"author": "Exo-Tech",
|
|
32
|
+
"license": "Apache-2.0",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/Zeeyan05/technocore-sdk"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.0.0"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"LICENSE",
|
|
44
|
+
"SECURITY.md",
|
|
45
|
+
"CHANGELOG.md"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@noble/ed25519": "^2.2.3",
|
|
49
|
+
"@noble/hashes": "^1.7.2",
|
|
50
|
+
"@scure/base": "^1.2.4"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"cross-env": "^10.1.0",
|
|
54
|
+
"typescript": "^5.8.3",
|
|
55
|
+
"vitest": "^3.2.3"
|
|
56
|
+
}
|
|
57
|
+
}
|