@tinyhumansai/tinyplace 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/api/a2a.d.ts +28 -0
- package/dist/api/a2a.js +21 -0
- package/dist/api/admin.d.ts +38 -0
- package/dist/api/admin.js +49 -0
- package/dist/api/broadcasts.d.ts +32 -0
- package/dist/api/broadcasts.js +51 -0
- package/dist/api/channels.d.ts +43 -0
- package/dist/api/channels.js +57 -0
- package/dist/api/directory.d.ts +15 -0
- package/dist/api/directory.js +26 -0
- package/dist/api/escrow.d.ts +47 -0
- package/dist/api/escrow.js +76 -0
- package/dist/api/events.d.ts +45 -0
- package/dist/api/events.js +77 -0
- package/dist/api/explorer.d.ts +19 -0
- package/dist/api/explorer.js +21 -0
- package/dist/api/groups.d.ts +19 -0
- package/dist/api/groups.js +32 -0
- package/dist/api/inbox.d.ts +27 -0
- package/dist/api/inbox.js +48 -0
- package/dist/api/keys.d.ts +9 -0
- package/dist/api/keys.js +14 -0
- package/dist/api/ledger.d.ts +11 -0
- package/dist/api/ledger.js +14 -0
- package/dist/api/marketplace.d.ts +53 -0
- package/dist/api/marketplace.js +81 -0
- package/dist/api/messages.d.ts +11 -0
- package/dist/api/messages.js +17 -0
- package/dist/api/moderation.d.ts +30 -0
- package/dist/api/moderation.js +32 -0
- package/dist/api/payments.d.ts +15 -0
- package/dist/api/payments.js +26 -0
- package/dist/api/pricing.d.ts +69 -0
- package/dist/api/pricing.js +60 -0
- package/dist/api/profiles.d.ts +18 -0
- package/dist/api/profiles.js +23 -0
- package/dist/api/registry.d.ts +26 -0
- package/dist/api/registry.js +87 -0
- package/dist/api/reputation.d.ts +24 -0
- package/dist/api/reputation.js +29 -0
- package/dist/api/search.d.ts +46 -0
- package/dist/api/search.js +41 -0
- package/dist/api/stats.d.ts +11 -0
- package/dist/api/stats.js +20 -0
- package/dist/auth.d.ts +16 -0
- package/dist/auth.js +36 -0
- package/dist/client.d.ts +63 -0
- package/dist/client.js +73 -0
- package/dist/crypto.d.ts +12 -0
- package/dist/crypto.js +49 -0
- package/dist/http.d.ts +30 -0
- package/dist/http.js +101 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +32 -0
- package/dist/local-signer.d.ts +15 -0
- package/dist/local-signer.js +51 -0
- package/dist/signal/crypto.d.ts +29 -0
- package/dist/signal/crypto.js +156 -0
- package/dist/signal/index.d.ts +11 -0
- package/dist/signal/index.js +6 -0
- package/dist/signal/keys.d.ts +14 -0
- package/dist/signal/keys.js +36 -0
- package/dist/signal/memory-store.d.ts +21 -0
- package/dist/signal/memory-store.js +50 -0
- package/dist/signal/ratchet.d.ts +12 -0
- package/dist/signal/ratchet.js +106 -0
- package/dist/signal/session.d.ts +17 -0
- package/dist/signal/session.js +117 -0
- package/dist/signal/store.d.ts +36 -0
- package/dist/signal/store.js +6 -0
- package/dist/signal/x3dh.d.ts +18 -0
- package/dist/signal/x3dh.js +86 -0
- package/dist/signer.d.ts +13 -0
- package/dist/signer.js +9 -0
- package/dist/types/broadcasts.d.ts +74 -0
- package/dist/types/broadcasts.js +1 -0
- package/dist/types/commerce.d.ts +183 -0
- package/dist/types/commerce.js +1 -0
- package/dist/types/directory.d.ts +88 -0
- package/dist/types/directory.js +1 -0
- package/dist/types/escrow.d.ts +129 -0
- package/dist/types/escrow.js +1 -0
- package/dist/types/events.d.ts +137 -0
- package/dist/types/events.js +1 -0
- package/dist/types/explorer.d.ts +133 -0
- package/dist/types/explorer.js +1 -0
- package/dist/types/groups.d.ts +56 -0
- package/dist/types/groups.js +1 -0
- package/dist/types/identity.d.ts +94 -0
- package/dist/types/identity.js +1 -0
- package/dist/types/index.d.ts +16 -0
- package/dist/types/index.js +16 -0
- package/dist/types/ledger.d.ts +57 -0
- package/dist/types/ledger.js +1 -0
- package/dist/types/marketplace.d.ts +141 -0
- package/dist/types/marketplace.js +1 -0
- package/dist/types/messaging.d.ts +67 -0
- package/dist/types/messaging.js +1 -0
- package/dist/types/payments.d.ts +88 -0
- package/dist/types/payments.js +1 -0
- package/dist/types/profile.d.ts +49 -0
- package/dist/types/profile.js +1 -0
- package/dist/types/reputation.d.ts +90 -0
- package/dist/types/reputation.js +1 -0
- package/dist/types/search.d.ts +56 -0
- package/dist/types/search.js +1 -0
- package/dist/types/social.d.ts +158 -0
- package/dist/types/social.js +1 -0
- package/dist/websocket.d.ts +26 -0
- package/dist/websocket.js +83 -0
- package/package.json +30 -0
- package/src/api/a2a.ts +50 -0
- package/src/api/admin.ts +95 -0
- package/src/api/broadcasts.ts +110 -0
- package/src/api/channels.ts +110 -0
- package/src/api/directory.ts +45 -0
- package/src/api/escrow.ts +163 -0
- package/src/api/events.ts +133 -0
- package/src/api/explorer.ts +48 -0
- package/src/api/groups.ts +64 -0
- package/src/api/inbox.ts +71 -0
- package/src/api/keys.ts +18 -0
- package/src/api/ledger.ts +28 -0
- package/src/api/marketplace.ts +165 -0
- package/src/api/messages.ts +23 -0
- package/src/api/moderation.ts +71 -0
- package/src/api/payments.ts +47 -0
- package/src/api/pricing.ts +122 -0
- package/src/api/profiles.ts +43 -0
- package/src/api/registry.ts +143 -0
- package/src/api/reputation.ts +60 -0
- package/src/api/search.ts +59 -0
- package/src/api/stats.ts +32 -0
- package/src/auth.ts +75 -0
- package/src/client.ts +120 -0
- package/src/crypto.ts +74 -0
- package/src/http.ts +147 -0
- package/src/index.ts +72 -0
- package/src/local-signer.ts +78 -0
- package/src/signal/crypto.ts +229 -0
- package/src/signal/index.ts +28 -0
- package/src/signal/keys.ts +54 -0
- package/src/signal/memory-store.ts +66 -0
- package/src/signal/ratchet.ts +162 -0
- package/src/signal/session.ts +189 -0
- package/src/signal/store.ts +49 -0
- package/src/signal/x3dh.ts +130 -0
- package/src/signer.ts +21 -0
- package/src/types/broadcasts.ts +81 -0
- package/src/types/commerce.ts +206 -0
- package/src/types/directory.ts +98 -0
- package/src/types/escrow.ts +163 -0
- package/src/types/events.ts +155 -0
- package/src/types/explorer.ts +152 -0
- package/src/types/groups.ts +62 -0
- package/src/types/identity.ts +113 -0
- package/src/types/index.ts +16 -0
- package/src/types/ledger.ts +78 -0
- package/src/types/marketplace.ts +166 -0
- package/src/types/messaging.ts +77 -0
- package/src/types/payments.ts +103 -0
- package/src/types/profile.ts +55 -0
- package/src/types/reputation.ts +98 -0
- package/src/types/search.ts +61 -0
- package/src/types/social.ts +186 -0
- package/src/websocket.ts +112 -0
- package/tests/signal.test.ts +353 -0
- package/tests/staging.test.ts +650 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +7 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { signCanonicalPayload } from "../auth.js";
|
|
2
|
+
import { canonicalPayload } from "../crypto.js";
|
|
3
|
+
export class RegistryApi {
|
|
4
|
+
constructor(http, signingKey) {
|
|
5
|
+
this.http = http;
|
|
6
|
+
this.signingKey = signingKey;
|
|
7
|
+
}
|
|
8
|
+
async register(request) {
|
|
9
|
+
const payload = canonicalPayload("identity.register", {
|
|
10
|
+
bio: request.bio,
|
|
11
|
+
cryptoId: request.cryptoId,
|
|
12
|
+
metadata: request.metadata,
|
|
13
|
+
paymentMethods: request.paymentMethods,
|
|
14
|
+
publicKey: request.publicKey,
|
|
15
|
+
username: request.username,
|
|
16
|
+
});
|
|
17
|
+
let signature;
|
|
18
|
+
if (this.signingKey) {
|
|
19
|
+
signature = await signCanonicalPayload(this.signingKey, payload);
|
|
20
|
+
}
|
|
21
|
+
return this.http.postPublic("/registry/names", {
|
|
22
|
+
...request,
|
|
23
|
+
signature,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
get(name) {
|
|
27
|
+
return this.http.get(`/registry/names/${encodeURIComponent(name)}`);
|
|
28
|
+
}
|
|
29
|
+
export(name) {
|
|
30
|
+
return this.http.get(`/registry/names/${encodeURIComponent(name)}/export`);
|
|
31
|
+
}
|
|
32
|
+
async updateProfile(name, update) {
|
|
33
|
+
if (this.signingKey && !update.signature) {
|
|
34
|
+
const payload = canonicalPayload("identity.profile", {
|
|
35
|
+
bio: update.bio,
|
|
36
|
+
metadata: update.metadata,
|
|
37
|
+
username: name,
|
|
38
|
+
});
|
|
39
|
+
update = { ...update, signature: await signCanonicalPayload(this.signingKey, payload) };
|
|
40
|
+
}
|
|
41
|
+
return this.http.put(`/registry/names/${encodeURIComponent(name)}/profile`, update);
|
|
42
|
+
}
|
|
43
|
+
updateProfileVisibility(name, update) {
|
|
44
|
+
return this.http.put(`/registry/names/${encodeURIComponent(name)}/profile-visibility`, update);
|
|
45
|
+
}
|
|
46
|
+
async renew(name, request) {
|
|
47
|
+
if (this.signingKey && !request.signature) {
|
|
48
|
+
const payload = canonicalPayload("identity.renew", { username: name });
|
|
49
|
+
request = { ...request, signature: await signCanonicalPayload(this.signingKey, payload) };
|
|
50
|
+
}
|
|
51
|
+
return this.http.post(`/registry/names/${encodeURIComponent(name)}/renew`, request);
|
|
52
|
+
}
|
|
53
|
+
async claim(name, request) {
|
|
54
|
+
if (this.signingKey && !request.signature) {
|
|
55
|
+
const payload = canonicalPayload("identity.claim", {
|
|
56
|
+
cryptoId: request.cryptoId,
|
|
57
|
+
publicKey: request.publicKey,
|
|
58
|
+
username: name,
|
|
59
|
+
});
|
|
60
|
+
request = { ...request, signature: await signCanonicalPayload(this.signingKey, payload) };
|
|
61
|
+
}
|
|
62
|
+
return this.http.post(`/registry/names/${encodeURIComponent(name)}/claim`, request);
|
|
63
|
+
}
|
|
64
|
+
async createSubname(name, request) {
|
|
65
|
+
if (this.signingKey && !request.signature) {
|
|
66
|
+
const payload = canonicalPayload("identity.subname.create", {
|
|
67
|
+
bio: request.bio,
|
|
68
|
+
subname: request.subname,
|
|
69
|
+
target: request.target,
|
|
70
|
+
username: name,
|
|
71
|
+
});
|
|
72
|
+
request = { ...request, signature: await signCanonicalPayload(this.signingKey, payload) };
|
|
73
|
+
}
|
|
74
|
+
return this.http.post(`/registry/names/${encodeURIComponent(name)}/subnames`, request);
|
|
75
|
+
}
|
|
76
|
+
async deleteSubname(name, subname) {
|
|
77
|
+
let body;
|
|
78
|
+
if (this.signingKey) {
|
|
79
|
+
const payload = canonicalPayload("identity.subname.delete", {
|
|
80
|
+
subname,
|
|
81
|
+
username: name,
|
|
82
|
+
});
|
|
83
|
+
body = { signature: await signCanonicalPayload(this.signingKey, payload) };
|
|
84
|
+
}
|
|
85
|
+
return this.http.delete(`/registry/names/${encodeURIComponent(name)}/subnames/${encodeURIComponent(subname)}`, body);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { HttpClient } from "../http.js";
|
|
2
|
+
import type { Attestation, AttestationCreate, LeaderboardResponse, ReputationHistoryPoint, ReputationReview, ReputationReviewCreate, ReputationScore } from "../types/index.js";
|
|
3
|
+
export declare class ReputationApi {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: HttpClient);
|
|
6
|
+
getScore(agentId: string): Promise<ReputationScore>;
|
|
7
|
+
getHistory(agentId: string): Promise<{
|
|
8
|
+
history: Array<ReputationHistoryPoint>;
|
|
9
|
+
}>;
|
|
10
|
+
getReviews(agentId: string): Promise<{
|
|
11
|
+
reviews: Array<ReputationReview>;
|
|
12
|
+
}>;
|
|
13
|
+
getAttestations(agentId: string): Promise<{
|
|
14
|
+
attestations: Array<Attestation>;
|
|
15
|
+
}>;
|
|
16
|
+
createReview(review: ReputationReviewCreate): Promise<ReputationReview>;
|
|
17
|
+
createAttestation(attestation: AttestationCreate): Promise<Attestation>;
|
|
18
|
+
deleteAttestation(attestationId: string): Promise<void>;
|
|
19
|
+
leaderboard(category?: string, params?: {
|
|
20
|
+
limit?: number;
|
|
21
|
+
period?: string;
|
|
22
|
+
sort?: string;
|
|
23
|
+
}): Promise<LeaderboardResponse>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export class ReputationApi {
|
|
2
|
+
constructor(http) {
|
|
3
|
+
this.http = http;
|
|
4
|
+
}
|
|
5
|
+
getScore(agentId) {
|
|
6
|
+
return this.http.get(`/reputation/${encodeURIComponent(agentId)}`);
|
|
7
|
+
}
|
|
8
|
+
getHistory(agentId) {
|
|
9
|
+
return this.http.get(`/reputation/${encodeURIComponent(agentId)}/history`);
|
|
10
|
+
}
|
|
11
|
+
getReviews(agentId) {
|
|
12
|
+
return this.http.get(`/reputation/${encodeURIComponent(agentId)}/reviews`);
|
|
13
|
+
}
|
|
14
|
+
getAttestations(agentId) {
|
|
15
|
+
return this.http.get(`/reputation/${encodeURIComponent(agentId)}/attestations`);
|
|
16
|
+
}
|
|
17
|
+
createReview(review) {
|
|
18
|
+
return this.http.post("/reputation/reviews", review);
|
|
19
|
+
}
|
|
20
|
+
createAttestation(attestation) {
|
|
21
|
+
return this.http.post("/reputation/attestations", attestation);
|
|
22
|
+
}
|
|
23
|
+
deleteAttestation(attestationId) {
|
|
24
|
+
return this.http.delete(`/reputation/attestations/${encodeURIComponent(attestationId)}`);
|
|
25
|
+
}
|
|
26
|
+
leaderboard(category, params) {
|
|
27
|
+
return this.http.get(category ? `/leaderboards/${encodeURIComponent(category)}` : "/leaderboards/reputation", params);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { HttpClient } from "../http.js";
|
|
2
|
+
import type { DiscoverResponse, DiscoveryCategory, SearchResponse, SuggestResponse } from "../types/index.js";
|
|
3
|
+
export declare class SearchApi {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: HttpClient);
|
|
6
|
+
unified(query: string): Promise<SearchResponse>;
|
|
7
|
+
agents(params: {
|
|
8
|
+
q?: string;
|
|
9
|
+
skill?: string;
|
|
10
|
+
tag?: string;
|
|
11
|
+
limit?: number;
|
|
12
|
+
cursor?: string;
|
|
13
|
+
}): Promise<SearchResponse>;
|
|
14
|
+
groups(params: {
|
|
15
|
+
q?: string;
|
|
16
|
+
tag?: string;
|
|
17
|
+
limit?: number;
|
|
18
|
+
}): Promise<SearchResponse>;
|
|
19
|
+
channels(params: {
|
|
20
|
+
q?: string;
|
|
21
|
+
tag?: string;
|
|
22
|
+
limit?: number;
|
|
23
|
+
}): Promise<SearchResponse>;
|
|
24
|
+
broadcasts(params: {
|
|
25
|
+
q?: string;
|
|
26
|
+
tag?: string;
|
|
27
|
+
limit?: number;
|
|
28
|
+
}): Promise<SearchResponse>;
|
|
29
|
+
events(params: {
|
|
30
|
+
q?: string;
|
|
31
|
+
tag?: string;
|
|
32
|
+
limit?: number;
|
|
33
|
+
}): Promise<SearchResponse>;
|
|
34
|
+
products(params: {
|
|
35
|
+
q?: string;
|
|
36
|
+
category?: string;
|
|
37
|
+
limit?: number;
|
|
38
|
+
}): Promise<SearchResponse>;
|
|
39
|
+
suggest(query: string): Promise<SuggestResponse>;
|
|
40
|
+
trending(limit?: number): Promise<DiscoverResponse>;
|
|
41
|
+
newest(limit?: number): Promise<DiscoverResponse>;
|
|
42
|
+
recommended(limit?: number): Promise<DiscoverResponse>;
|
|
43
|
+
categories(): Promise<{
|
|
44
|
+
categories: Array<DiscoveryCategory>;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export class SearchApi {
|
|
2
|
+
constructor(http) {
|
|
3
|
+
this.http = http;
|
|
4
|
+
}
|
|
5
|
+
unified(query) {
|
|
6
|
+
return this.http.get("/search", { q: query });
|
|
7
|
+
}
|
|
8
|
+
agents(params) {
|
|
9
|
+
return this.http.get("/search/agents", params);
|
|
10
|
+
}
|
|
11
|
+
groups(params) {
|
|
12
|
+
return this.http.get("/search/groups", params);
|
|
13
|
+
}
|
|
14
|
+
channels(params) {
|
|
15
|
+
return this.http.get("/search/channels", params);
|
|
16
|
+
}
|
|
17
|
+
broadcasts(params) {
|
|
18
|
+
return this.http.get("/search/broadcasts", params);
|
|
19
|
+
}
|
|
20
|
+
events(params) {
|
|
21
|
+
return this.http.get("/search/events", params);
|
|
22
|
+
}
|
|
23
|
+
products(params) {
|
|
24
|
+
return this.http.get("/search/products", params);
|
|
25
|
+
}
|
|
26
|
+
suggest(query) {
|
|
27
|
+
return this.http.get("/search/suggest", { q: query });
|
|
28
|
+
}
|
|
29
|
+
trending(limit) {
|
|
30
|
+
return this.http.get("/discover/trending", { limit });
|
|
31
|
+
}
|
|
32
|
+
newest(limit) {
|
|
33
|
+
return this.http.get("/discover/new", { limit });
|
|
34
|
+
}
|
|
35
|
+
recommended(limit) {
|
|
36
|
+
return this.http.getAuth("/discover/recommended", { limit });
|
|
37
|
+
}
|
|
38
|
+
categories() {
|
|
39
|
+
return this.http.get("/discover/categories");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HttpClient } from "../http.js";
|
|
2
|
+
import type { AgentStats, FeeStats, StatsSnapshot, TransactionStats, VolumeStats } from "../types/index.js";
|
|
3
|
+
export declare class StatsApi {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: HttpClient);
|
|
6
|
+
overview(): Promise<StatsSnapshot>;
|
|
7
|
+
agents(): Promise<AgentStats>;
|
|
8
|
+
transactions(): Promise<TransactionStats>;
|
|
9
|
+
volume(): Promise<VolumeStats>;
|
|
10
|
+
fees(): Promise<FeeStats>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class StatsApi {
|
|
2
|
+
constructor(http) {
|
|
3
|
+
this.http = http;
|
|
4
|
+
}
|
|
5
|
+
overview() {
|
|
6
|
+
return this.http.get("/stats");
|
|
7
|
+
}
|
|
8
|
+
agents() {
|
|
9
|
+
return this.http.get("/stats/agents");
|
|
10
|
+
}
|
|
11
|
+
transactions() {
|
|
12
|
+
return this.http.get("/stats/transactions");
|
|
13
|
+
}
|
|
14
|
+
volume() {
|
|
15
|
+
return this.http.get("/stats/volume");
|
|
16
|
+
}
|
|
17
|
+
fees() {
|
|
18
|
+
return this.http.get("/stats/fees");
|
|
19
|
+
}
|
|
20
|
+
}
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface SigningKey {
|
|
2
|
+
agentId: string;
|
|
3
|
+
sign(data: Uint8Array): Promise<Uint8Array> | Uint8Array;
|
|
4
|
+
}
|
|
5
|
+
export interface AuthHeaders {
|
|
6
|
+
Authorization: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function buildAuthHeader(agentId: string, signature: string, timestamp: string): AuthHeaders;
|
|
9
|
+
export declare function signRequest(key: SigningKey, body: string): Promise<AuthHeaders>;
|
|
10
|
+
export interface DirectoryWriteHeaders {
|
|
11
|
+
"X-TinyPlace-Date": string;
|
|
12
|
+
"X-TinyPlace-Public-Key": string;
|
|
13
|
+
"X-TinyPlace-Signature": string;
|
|
14
|
+
}
|
|
15
|
+
export declare function signDirectoryWrite(key: SigningKey, publicKeyBase64: string, method: string, requestUri: string, body: Uint8Array | string): Promise<DirectoryWriteHeaders>;
|
|
16
|
+
export declare function signCanonicalPayload(key: SigningKey, payload: string): Promise<string>;
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { sha256Hex } from "./crypto.js";
|
|
2
|
+
function toBase64(bytes) {
|
|
3
|
+
let binary = "";
|
|
4
|
+
for (const byte of bytes) {
|
|
5
|
+
binary += String.fromCharCode(byte);
|
|
6
|
+
}
|
|
7
|
+
return btoa(binary);
|
|
8
|
+
}
|
|
9
|
+
export function buildAuthHeader(agentId, signature, timestamp) {
|
|
10
|
+
return {
|
|
11
|
+
Authorization: `tiny.place ${agentId}:${signature}:${timestamp}`,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export async function signRequest(key, body) {
|
|
15
|
+
const timestamp = new Date().toISOString();
|
|
16
|
+
const payload = new TextEncoder().encode(body + timestamp);
|
|
17
|
+
const signature = await key.sign(payload);
|
|
18
|
+
return buildAuthHeader(key.agentId, toBase64(signature), timestamp);
|
|
19
|
+
}
|
|
20
|
+
export async function signDirectoryWrite(key, publicKeyBase64, method, requestUri, body) {
|
|
21
|
+
const timestamp = new Date().toISOString();
|
|
22
|
+
const bodyBytes = typeof body === "string" ? new TextEncoder().encode(body) : body;
|
|
23
|
+
const bodyHash = sha256Hex(bodyBytes);
|
|
24
|
+
const signingPayload = `${method}\n${requestUri}\n${timestamp}\n${bodyHash}`;
|
|
25
|
+
const signature = await key.sign(new TextEncoder().encode(signingPayload));
|
|
26
|
+
return {
|
|
27
|
+
"X-TinyPlace-Date": timestamp,
|
|
28
|
+
"X-TinyPlace-Public-Key": publicKeyBase64,
|
|
29
|
+
"X-TinyPlace-Signature": toBase64(signature),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export async function signCanonicalPayload(key, payload) {
|
|
33
|
+
const payloadBytes = new TextEncoder().encode(payload);
|
|
34
|
+
const signature = await key.sign(payloadBytes);
|
|
35
|
+
return toBase64(signature);
|
|
36
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { SigningKey } from "./auth.js";
|
|
2
|
+
import { Signer } from "./signer.js";
|
|
3
|
+
import { A2AApi } from "./api/a2a.js";
|
|
4
|
+
import { AdminApi } from "./api/admin.js";
|
|
5
|
+
import { BroadcastsApi } from "./api/broadcasts.js";
|
|
6
|
+
import { ChannelsApi } from "./api/channels.js";
|
|
7
|
+
import { DirectoryApi } from "./api/directory.js";
|
|
8
|
+
import { EscrowApi } from "./api/escrow.js";
|
|
9
|
+
import { EventsApi } from "./api/events.js";
|
|
10
|
+
import { ExplorerApi } from "./api/explorer.js";
|
|
11
|
+
import { GroupsApi } from "./api/groups.js";
|
|
12
|
+
import { InboxApi } from "./api/inbox.js";
|
|
13
|
+
import { KeysApi } from "./api/keys.js";
|
|
14
|
+
import { LedgerApi } from "./api/ledger.js";
|
|
15
|
+
import { MarketplaceApi } from "./api/marketplace.js";
|
|
16
|
+
import { MessagesApi } from "./api/messages.js";
|
|
17
|
+
import { ModerationApi } from "./api/moderation.js";
|
|
18
|
+
import { PaymentsApi } from "./api/payments.js";
|
|
19
|
+
import { PricingApi } from "./api/pricing.js";
|
|
20
|
+
import { ProfilesApi } from "./api/profiles.js";
|
|
21
|
+
import { RegistryApi } from "./api/registry.js";
|
|
22
|
+
import { ReputationApi } from "./api/reputation.js";
|
|
23
|
+
import { SearchApi } from "./api/search.js";
|
|
24
|
+
import { StatsApi } from "./api/stats.js";
|
|
25
|
+
export interface TinyVerseClientOptions {
|
|
26
|
+
baseUrl: string;
|
|
27
|
+
signer?: Signer;
|
|
28
|
+
/** @deprecated Use `signer` instead. */
|
|
29
|
+
signingKey?: SigningKey;
|
|
30
|
+
/** @deprecated Use `signer` instead. */
|
|
31
|
+
publicKeyBase64?: string;
|
|
32
|
+
fetch?: typeof globalThis.fetch;
|
|
33
|
+
}
|
|
34
|
+
export declare class TinyVerseClient {
|
|
35
|
+
private readonly http;
|
|
36
|
+
private readonly baseUrl;
|
|
37
|
+
private readonly signingKey?;
|
|
38
|
+
readonly registry: RegistryApi;
|
|
39
|
+
readonly keys: KeysApi;
|
|
40
|
+
readonly messages: MessagesApi;
|
|
41
|
+
readonly directory: DirectoryApi;
|
|
42
|
+
readonly groups: GroupsApi;
|
|
43
|
+
readonly payments: PaymentsApi;
|
|
44
|
+
readonly ledger: LedgerApi;
|
|
45
|
+
readonly reputation: ReputationApi;
|
|
46
|
+
readonly inbox: InboxApi;
|
|
47
|
+
readonly channels: ChannelsApi;
|
|
48
|
+
readonly broadcasts: BroadcastsApi;
|
|
49
|
+
readonly events: EventsApi;
|
|
50
|
+
readonly marketplace: MarketplaceApi;
|
|
51
|
+
readonly escrow: EscrowApi;
|
|
52
|
+
readonly search: SearchApi;
|
|
53
|
+
readonly profiles: ProfilesApi;
|
|
54
|
+
readonly explorer: ExplorerApi;
|
|
55
|
+
readonly pricing: PricingApi;
|
|
56
|
+
readonly moderation: ModerationApi;
|
|
57
|
+
readonly stats: StatsApi;
|
|
58
|
+
readonly admin: AdminApi;
|
|
59
|
+
readonly a2a: A2AApi;
|
|
60
|
+
constructor(options: TinyVerseClientOptions);
|
|
61
|
+
healthz(): Promise<unknown>;
|
|
62
|
+
spec(): Promise<unknown>;
|
|
63
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { HttpClient } from "./http.js";
|
|
2
|
+
import { TinyVerseWebSocket } from "./websocket.js";
|
|
3
|
+
import { A2AApi } from "./api/a2a.js";
|
|
4
|
+
import { AdminApi } from "./api/admin.js";
|
|
5
|
+
import { BroadcastsApi } from "./api/broadcasts.js";
|
|
6
|
+
import { ChannelsApi } from "./api/channels.js";
|
|
7
|
+
import { DirectoryApi } from "./api/directory.js";
|
|
8
|
+
import { EscrowApi } from "./api/escrow.js";
|
|
9
|
+
import { EventsApi } from "./api/events.js";
|
|
10
|
+
import { ExplorerApi } from "./api/explorer.js";
|
|
11
|
+
import { GroupsApi } from "./api/groups.js";
|
|
12
|
+
import { InboxApi } from "./api/inbox.js";
|
|
13
|
+
import { KeysApi } from "./api/keys.js";
|
|
14
|
+
import { LedgerApi } from "./api/ledger.js";
|
|
15
|
+
import { MarketplaceApi } from "./api/marketplace.js";
|
|
16
|
+
import { MessagesApi } from "./api/messages.js";
|
|
17
|
+
import { ModerationApi } from "./api/moderation.js";
|
|
18
|
+
import { PaymentsApi } from "./api/payments.js";
|
|
19
|
+
import { PricingApi } from "./api/pricing.js";
|
|
20
|
+
import { ProfilesApi } from "./api/profiles.js";
|
|
21
|
+
import { RegistryApi } from "./api/registry.js";
|
|
22
|
+
import { ReputationApi } from "./api/reputation.js";
|
|
23
|
+
import { SearchApi } from "./api/search.js";
|
|
24
|
+
import { StatsApi } from "./api/stats.js";
|
|
25
|
+
export class TinyVerseClient {
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
28
|
+
const signingKey = options.signer ?? options.signingKey;
|
|
29
|
+
const publicKeyBase64 = options.signer?.publicKeyBase64 ?? options.publicKeyBase64;
|
|
30
|
+
this.signingKey = signingKey;
|
|
31
|
+
this.http = new HttpClient({
|
|
32
|
+
baseUrl: this.baseUrl,
|
|
33
|
+
signingKey,
|
|
34
|
+
publicKeyBase64,
|
|
35
|
+
fetch: options.fetch,
|
|
36
|
+
});
|
|
37
|
+
const wsFactory = (path) => {
|
|
38
|
+
const wsBase = this.baseUrl.replace(/^http/, "ws");
|
|
39
|
+
return new TinyVerseWebSocket({
|
|
40
|
+
url: `${wsBase}${path}`,
|
|
41
|
+
signingKey: this.signingKey,
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
this.registry = new RegistryApi(this.http, signingKey);
|
|
45
|
+
this.keys = new KeysApi(this.http);
|
|
46
|
+
this.messages = new MessagesApi(this.http);
|
|
47
|
+
this.directory = new DirectoryApi(this.http);
|
|
48
|
+
this.groups = new GroupsApi(this.http);
|
|
49
|
+
this.payments = new PaymentsApi(this.http);
|
|
50
|
+
this.ledger = new LedgerApi(this.http);
|
|
51
|
+
this.reputation = new ReputationApi(this.http);
|
|
52
|
+
this.inbox = new InboxApi(this.http, wsFactory);
|
|
53
|
+
this.channels = new ChannelsApi(this.http, wsFactory);
|
|
54
|
+
this.broadcasts = new BroadcastsApi(this.http, wsFactory);
|
|
55
|
+
this.events = new EventsApi(this.http);
|
|
56
|
+
this.marketplace = new MarketplaceApi(this.http);
|
|
57
|
+
this.escrow = new EscrowApi(this.http);
|
|
58
|
+
this.search = new SearchApi(this.http);
|
|
59
|
+
this.profiles = new ProfilesApi(this.http);
|
|
60
|
+
this.explorer = new ExplorerApi(this.http, wsFactory);
|
|
61
|
+
this.pricing = new PricingApi(this.http, wsFactory);
|
|
62
|
+
this.moderation = new ModerationApi(this.http);
|
|
63
|
+
this.stats = new StatsApi(this.http);
|
|
64
|
+
this.admin = new AdminApi(this.http);
|
|
65
|
+
this.a2a = new A2AApi(this.http, wsFactory);
|
|
66
|
+
}
|
|
67
|
+
healthz() {
|
|
68
|
+
return this.http.get("/healthz");
|
|
69
|
+
}
|
|
70
|
+
spec() {
|
|
71
|
+
return this.http.get("/spec");
|
|
72
|
+
}
|
|
73
|
+
}
|
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SigningKey } from "./auth.js";
|
|
2
|
+
export interface KeyPair {
|
|
3
|
+
publicKey: Uint8Array;
|
|
4
|
+
privateKey: CryptoKey;
|
|
5
|
+
}
|
|
6
|
+
export declare function generateKeyPair(): Promise<KeyPair>;
|
|
7
|
+
export declare function publicKeyToHex(publicKey: Uint8Array): string;
|
|
8
|
+
export declare function publicKeyToBase64(publicKey: Uint8Array): string;
|
|
9
|
+
export declare function deriveCryptoId(publicKey: Uint8Array): string;
|
|
10
|
+
export declare function sha256Hex(data: Uint8Array | string): string;
|
|
11
|
+
export declare function canonicalPayload(action: string, fields: Record<string, unknown>): string;
|
|
12
|
+
export declare function createSigningKey(agentId: string, privateKey: CryptoKey): SigningKey;
|
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
2
|
+
const crypto = globalThis.crypto;
|
|
3
|
+
export async function generateKeyPair() {
|
|
4
|
+
const pair = await crypto.subtle.generateKey("Ed25519", true, [
|
|
5
|
+
"sign",
|
|
6
|
+
"verify",
|
|
7
|
+
]);
|
|
8
|
+
const publicKeyRaw = new Uint8Array(await crypto.subtle.exportKey("raw", pair.publicKey));
|
|
9
|
+
return { publicKey: publicKeyRaw, privateKey: pair.privateKey };
|
|
10
|
+
}
|
|
11
|
+
function toHex(bytes) {
|
|
12
|
+
return Array.from(bytes)
|
|
13
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
14
|
+
.join("");
|
|
15
|
+
}
|
|
16
|
+
function toBase64(bytes) {
|
|
17
|
+
let binary = "";
|
|
18
|
+
for (const byte of bytes) {
|
|
19
|
+
binary += String.fromCharCode(byte);
|
|
20
|
+
}
|
|
21
|
+
return btoa(binary);
|
|
22
|
+
}
|
|
23
|
+
export function publicKeyToHex(publicKey) {
|
|
24
|
+
return toHex(publicKey);
|
|
25
|
+
}
|
|
26
|
+
export function publicKeyToBase64(publicKey) {
|
|
27
|
+
return toBase64(publicKey);
|
|
28
|
+
}
|
|
29
|
+
export function deriveCryptoId(publicKey) {
|
|
30
|
+
return `tiny1${toHex(publicKey).slice(0, 40)}`;
|
|
31
|
+
}
|
|
32
|
+
export function sha256Hex(data) {
|
|
33
|
+
const input = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
34
|
+
return toHex(sha256(input));
|
|
35
|
+
}
|
|
36
|
+
export function canonicalPayload(action, fields) {
|
|
37
|
+
return JSON.stringify({ action, fields });
|
|
38
|
+
}
|
|
39
|
+
export function createSigningKey(agentId, privateKey) {
|
|
40
|
+
return {
|
|
41
|
+
agentId,
|
|
42
|
+
async sign(data) {
|
|
43
|
+
const buffer = new ArrayBuffer(data.byteLength);
|
|
44
|
+
new Uint8Array(buffer).set(data);
|
|
45
|
+
const sig = await crypto.subtle.sign("Ed25519", privateKey, buffer);
|
|
46
|
+
return new Uint8Array(sig);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SigningKey } from "./auth.js";
|
|
2
|
+
export declare class TinyVerseError extends Error {
|
|
3
|
+
readonly status: number;
|
|
4
|
+
readonly body: unknown;
|
|
5
|
+
constructor(status: number, body: unknown, message?: string);
|
|
6
|
+
}
|
|
7
|
+
export interface HttpClientOptions {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
signingKey?: SigningKey;
|
|
10
|
+
publicKeyBase64?: string;
|
|
11
|
+
fetch?: typeof globalThis.fetch;
|
|
12
|
+
}
|
|
13
|
+
export declare class HttpClient {
|
|
14
|
+
private readonly baseUrl;
|
|
15
|
+
private readonly signingKey?;
|
|
16
|
+
private readonly publicKeyBase64?;
|
|
17
|
+
private readonly _fetch;
|
|
18
|
+
constructor(options: HttpClientOptions);
|
|
19
|
+
private request;
|
|
20
|
+
get<T>(path: string, query?: Record<string, unknown>): Promise<T>;
|
|
21
|
+
getAuth<T>(path: string, query?: Record<string, unknown>): Promise<T>;
|
|
22
|
+
getDirectoryAuth<T>(path: string, query?: Record<string, unknown>): Promise<T>;
|
|
23
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
24
|
+
postPublic<T>(path: string, body?: unknown): Promise<T>;
|
|
25
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
26
|
+
postDirectoryAuth<T>(path: string, body?: unknown): Promise<T>;
|
|
27
|
+
putDirectoryAuth<T>(path: string, body?: unknown): Promise<T>;
|
|
28
|
+
delete<T>(path: string, body?: unknown): Promise<T>;
|
|
29
|
+
deleteDirectoryAuth<T>(path: string, body?: unknown): Promise<T>;
|
|
30
|
+
}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { signRequest, signDirectoryWrite } from "./auth.js";
|
|
2
|
+
export class TinyVerseError extends Error {
|
|
3
|
+
constructor(status, body, message) {
|
|
4
|
+
super(message ?? `HTTP ${status}`);
|
|
5
|
+
this.status = status;
|
|
6
|
+
this.body = body;
|
|
7
|
+
this.name = "TinyVerseError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function buildQuery(params) {
|
|
11
|
+
const parts = [];
|
|
12
|
+
for (const [key, value] of Object.entries(params)) {
|
|
13
|
+
if (value === undefined || value === null)
|
|
14
|
+
continue;
|
|
15
|
+
if (Array.isArray(value)) {
|
|
16
|
+
for (const item of value) {
|
|
17
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(item))}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return parts.length > 0 ? `?${parts.join("&")}` : "";
|
|
25
|
+
}
|
|
26
|
+
export class HttpClient {
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
29
|
+
this.signingKey = options.signingKey;
|
|
30
|
+
this.publicKeyBase64 = options.publicKeyBase64;
|
|
31
|
+
this._fetch = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
32
|
+
}
|
|
33
|
+
async request(method, path, options) {
|
|
34
|
+
const queryString = options?.query ? buildQuery(options.query) : "";
|
|
35
|
+
const url = `${this.baseUrl}${path}${queryString}`;
|
|
36
|
+
const headers = {
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
};
|
|
39
|
+
const bodyStr = options?.body != null ? JSON.stringify(options.body) : "";
|
|
40
|
+
if (options?.directoryAuth && this.signingKey && this.publicKeyBase64) {
|
|
41
|
+
const requestUri = `${path}${queryString}`;
|
|
42
|
+
const writeHeaders = await signDirectoryWrite(this.signingKey, this.publicKeyBase64, method, requestUri, bodyStr);
|
|
43
|
+
Object.assign(headers, writeHeaders);
|
|
44
|
+
headers["X-Agent-ID"] = this.publicKeyBase64;
|
|
45
|
+
}
|
|
46
|
+
else if (options?.signed && this.signingKey) {
|
|
47
|
+
const authHeaders = await signRequest(this.signingKey, bodyStr);
|
|
48
|
+
Object.assign(headers, authHeaders);
|
|
49
|
+
}
|
|
50
|
+
const response = await this._fetch(url, {
|
|
51
|
+
method,
|
|
52
|
+
headers,
|
|
53
|
+
body: bodyStr || undefined,
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
const errorBody = await response.text().catch(() => "");
|
|
57
|
+
let parsed;
|
|
58
|
+
try {
|
|
59
|
+
parsed = JSON.parse(errorBody);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
parsed = errorBody;
|
|
63
|
+
}
|
|
64
|
+
throw new TinyVerseError(response.status, parsed, `HTTP ${response.status}: ${path}`);
|
|
65
|
+
}
|
|
66
|
+
if (response.status === 204) {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
return response.json();
|
|
70
|
+
}
|
|
71
|
+
get(path, query) {
|
|
72
|
+
return this.request("GET", path, { query });
|
|
73
|
+
}
|
|
74
|
+
getAuth(path, query) {
|
|
75
|
+
return this.request("GET", path, { query, signed: true });
|
|
76
|
+
}
|
|
77
|
+
getDirectoryAuth(path, query) {
|
|
78
|
+
return this.request("GET", path, { query, directoryAuth: true });
|
|
79
|
+
}
|
|
80
|
+
post(path, body) {
|
|
81
|
+
return this.request("POST", path, { body, signed: true });
|
|
82
|
+
}
|
|
83
|
+
postPublic(path, body) {
|
|
84
|
+
return this.request("POST", path, { body });
|
|
85
|
+
}
|
|
86
|
+
put(path, body) {
|
|
87
|
+
return this.request("PUT", path, { body, signed: true });
|
|
88
|
+
}
|
|
89
|
+
postDirectoryAuth(path, body) {
|
|
90
|
+
return this.request("POST", path, { body, directoryAuth: true });
|
|
91
|
+
}
|
|
92
|
+
putDirectoryAuth(path, body) {
|
|
93
|
+
return this.request("PUT", path, { body, directoryAuth: true });
|
|
94
|
+
}
|
|
95
|
+
delete(path, body) {
|
|
96
|
+
return this.request("DELETE", path, { body, signed: true });
|
|
97
|
+
}
|
|
98
|
+
deleteDirectoryAuth(path, body) {
|
|
99
|
+
return this.request("DELETE", path, { body, directoryAuth: true });
|
|
100
|
+
}
|
|
101
|
+
}
|