@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.
Files changed (170) hide show
  1. package/dist/api/a2a.d.ts +28 -0
  2. package/dist/api/a2a.js +21 -0
  3. package/dist/api/admin.d.ts +38 -0
  4. package/dist/api/admin.js +49 -0
  5. package/dist/api/broadcasts.d.ts +32 -0
  6. package/dist/api/broadcasts.js +51 -0
  7. package/dist/api/channels.d.ts +43 -0
  8. package/dist/api/channels.js +57 -0
  9. package/dist/api/directory.d.ts +15 -0
  10. package/dist/api/directory.js +26 -0
  11. package/dist/api/escrow.d.ts +47 -0
  12. package/dist/api/escrow.js +76 -0
  13. package/dist/api/events.d.ts +45 -0
  14. package/dist/api/events.js +77 -0
  15. package/dist/api/explorer.d.ts +19 -0
  16. package/dist/api/explorer.js +21 -0
  17. package/dist/api/groups.d.ts +19 -0
  18. package/dist/api/groups.js +32 -0
  19. package/dist/api/inbox.d.ts +27 -0
  20. package/dist/api/inbox.js +48 -0
  21. package/dist/api/keys.d.ts +9 -0
  22. package/dist/api/keys.js +14 -0
  23. package/dist/api/ledger.d.ts +11 -0
  24. package/dist/api/ledger.js +14 -0
  25. package/dist/api/marketplace.d.ts +53 -0
  26. package/dist/api/marketplace.js +81 -0
  27. package/dist/api/messages.d.ts +11 -0
  28. package/dist/api/messages.js +17 -0
  29. package/dist/api/moderation.d.ts +30 -0
  30. package/dist/api/moderation.js +32 -0
  31. package/dist/api/payments.d.ts +15 -0
  32. package/dist/api/payments.js +26 -0
  33. package/dist/api/pricing.d.ts +69 -0
  34. package/dist/api/pricing.js +60 -0
  35. package/dist/api/profiles.d.ts +18 -0
  36. package/dist/api/profiles.js +23 -0
  37. package/dist/api/registry.d.ts +26 -0
  38. package/dist/api/registry.js +87 -0
  39. package/dist/api/reputation.d.ts +24 -0
  40. package/dist/api/reputation.js +29 -0
  41. package/dist/api/search.d.ts +46 -0
  42. package/dist/api/search.js +41 -0
  43. package/dist/api/stats.d.ts +11 -0
  44. package/dist/api/stats.js +20 -0
  45. package/dist/auth.d.ts +16 -0
  46. package/dist/auth.js +36 -0
  47. package/dist/client.d.ts +63 -0
  48. package/dist/client.js +73 -0
  49. package/dist/crypto.d.ts +12 -0
  50. package/dist/crypto.js +49 -0
  51. package/dist/http.d.ts +30 -0
  52. package/dist/http.js +101 -0
  53. package/dist/index.d.ts +39 -0
  54. package/dist/index.js +32 -0
  55. package/dist/local-signer.d.ts +15 -0
  56. package/dist/local-signer.js +51 -0
  57. package/dist/signal/crypto.d.ts +29 -0
  58. package/dist/signal/crypto.js +156 -0
  59. package/dist/signal/index.d.ts +11 -0
  60. package/dist/signal/index.js +6 -0
  61. package/dist/signal/keys.d.ts +14 -0
  62. package/dist/signal/keys.js +36 -0
  63. package/dist/signal/memory-store.d.ts +21 -0
  64. package/dist/signal/memory-store.js +50 -0
  65. package/dist/signal/ratchet.d.ts +12 -0
  66. package/dist/signal/ratchet.js +106 -0
  67. package/dist/signal/session.d.ts +17 -0
  68. package/dist/signal/session.js +117 -0
  69. package/dist/signal/store.d.ts +36 -0
  70. package/dist/signal/store.js +6 -0
  71. package/dist/signal/x3dh.d.ts +18 -0
  72. package/dist/signal/x3dh.js +86 -0
  73. package/dist/signer.d.ts +13 -0
  74. package/dist/signer.js +9 -0
  75. package/dist/types/broadcasts.d.ts +74 -0
  76. package/dist/types/broadcasts.js +1 -0
  77. package/dist/types/commerce.d.ts +183 -0
  78. package/dist/types/commerce.js +1 -0
  79. package/dist/types/directory.d.ts +88 -0
  80. package/dist/types/directory.js +1 -0
  81. package/dist/types/escrow.d.ts +129 -0
  82. package/dist/types/escrow.js +1 -0
  83. package/dist/types/events.d.ts +137 -0
  84. package/dist/types/events.js +1 -0
  85. package/dist/types/explorer.d.ts +133 -0
  86. package/dist/types/explorer.js +1 -0
  87. package/dist/types/groups.d.ts +56 -0
  88. package/dist/types/groups.js +1 -0
  89. package/dist/types/identity.d.ts +94 -0
  90. package/dist/types/identity.js +1 -0
  91. package/dist/types/index.d.ts +16 -0
  92. package/dist/types/index.js +16 -0
  93. package/dist/types/ledger.d.ts +57 -0
  94. package/dist/types/ledger.js +1 -0
  95. package/dist/types/marketplace.d.ts +141 -0
  96. package/dist/types/marketplace.js +1 -0
  97. package/dist/types/messaging.d.ts +67 -0
  98. package/dist/types/messaging.js +1 -0
  99. package/dist/types/payments.d.ts +88 -0
  100. package/dist/types/payments.js +1 -0
  101. package/dist/types/profile.d.ts +49 -0
  102. package/dist/types/profile.js +1 -0
  103. package/dist/types/reputation.d.ts +90 -0
  104. package/dist/types/reputation.js +1 -0
  105. package/dist/types/search.d.ts +56 -0
  106. package/dist/types/search.js +1 -0
  107. package/dist/types/social.d.ts +158 -0
  108. package/dist/types/social.js +1 -0
  109. package/dist/websocket.d.ts +26 -0
  110. package/dist/websocket.js +83 -0
  111. package/package.json +30 -0
  112. package/src/api/a2a.ts +50 -0
  113. package/src/api/admin.ts +95 -0
  114. package/src/api/broadcasts.ts +110 -0
  115. package/src/api/channels.ts +110 -0
  116. package/src/api/directory.ts +45 -0
  117. package/src/api/escrow.ts +163 -0
  118. package/src/api/events.ts +133 -0
  119. package/src/api/explorer.ts +48 -0
  120. package/src/api/groups.ts +64 -0
  121. package/src/api/inbox.ts +71 -0
  122. package/src/api/keys.ts +18 -0
  123. package/src/api/ledger.ts +28 -0
  124. package/src/api/marketplace.ts +165 -0
  125. package/src/api/messages.ts +23 -0
  126. package/src/api/moderation.ts +71 -0
  127. package/src/api/payments.ts +47 -0
  128. package/src/api/pricing.ts +122 -0
  129. package/src/api/profiles.ts +43 -0
  130. package/src/api/registry.ts +143 -0
  131. package/src/api/reputation.ts +60 -0
  132. package/src/api/search.ts +59 -0
  133. package/src/api/stats.ts +32 -0
  134. package/src/auth.ts +75 -0
  135. package/src/client.ts +120 -0
  136. package/src/crypto.ts +74 -0
  137. package/src/http.ts +147 -0
  138. package/src/index.ts +72 -0
  139. package/src/local-signer.ts +78 -0
  140. package/src/signal/crypto.ts +229 -0
  141. package/src/signal/index.ts +28 -0
  142. package/src/signal/keys.ts +54 -0
  143. package/src/signal/memory-store.ts +66 -0
  144. package/src/signal/ratchet.ts +162 -0
  145. package/src/signal/session.ts +189 -0
  146. package/src/signal/store.ts +49 -0
  147. package/src/signal/x3dh.ts +130 -0
  148. package/src/signer.ts +21 -0
  149. package/src/types/broadcasts.ts +81 -0
  150. package/src/types/commerce.ts +206 -0
  151. package/src/types/directory.ts +98 -0
  152. package/src/types/escrow.ts +163 -0
  153. package/src/types/events.ts +155 -0
  154. package/src/types/explorer.ts +152 -0
  155. package/src/types/groups.ts +62 -0
  156. package/src/types/identity.ts +113 -0
  157. package/src/types/index.ts +16 -0
  158. package/src/types/ledger.ts +78 -0
  159. package/src/types/marketplace.ts +166 -0
  160. package/src/types/messaging.ts +77 -0
  161. package/src/types/payments.ts +103 -0
  162. package/src/types/profile.ts +55 -0
  163. package/src/types/reputation.ts +98 -0
  164. package/src/types/search.ts +61 -0
  165. package/src/types/social.ts +186 -0
  166. package/src/websocket.ts +112 -0
  167. package/tests/signal.test.ts +353 -0
  168. package/tests/staging.test.ts +650 -0
  169. package/tsconfig.json +15 -0
  170. package/vitest.config.ts +7 -0
@@ -0,0 +1,103 @@
1
+ export type PaymentIntentStatus = "verified" | "settled";
2
+
3
+ export interface PaymentIntent {
4
+ intentId: string;
5
+ verifiedId: string;
6
+ nonceKey: string;
7
+ paymentHash: string;
8
+ network: string;
9
+ asset: string;
10
+ amount: string;
11
+ from: string;
12
+ to: string;
13
+ feeId?: string;
14
+ feeRate: string;
15
+ feeAmount: string;
16
+ netAmount: string;
17
+ status: PaymentIntentStatus;
18
+ createdAt: string;
19
+ expiresAt: string;
20
+ settledAt?: string;
21
+ ledgerTxId?: string;
22
+ }
23
+
24
+ export interface X402VerifyRequest {
25
+ scheme: "exact" | "upto" | "batch-settlement";
26
+ network: string;
27
+ asset: string;
28
+ amount: string;
29
+ from: string;
30
+ to: string;
31
+ nonce: string;
32
+ expiresAt: string;
33
+ signature: string;
34
+ }
35
+
36
+ export interface X402VerifyResponse {
37
+ valid: boolean;
38
+ intentId: string;
39
+ feeRate: string;
40
+ feeAmount: string;
41
+ netAmount: string;
42
+ error?: string;
43
+ }
44
+
45
+ export interface X402SettleRequest {
46
+ intentId: string;
47
+ onChainTx: string;
48
+ network: string;
49
+ }
50
+
51
+ export interface X402SettleResponse {
52
+ ledgerTxId: string;
53
+ onChainTx: string;
54
+ status: string;
55
+ }
56
+
57
+ export interface SupportedChain {
58
+ network: string;
59
+ name: string;
60
+ kind: "evm" | "solana";
61
+ chainId?: number;
62
+ nativeAsset: string;
63
+ explorerUrl: string;
64
+ assets: Array<SupportedAsset>;
65
+ }
66
+
67
+ export interface SupportedAsset {
68
+ symbol: string;
69
+ address?: string;
70
+ decimals: number;
71
+ }
72
+
73
+ export type SubscriptionStatus =
74
+ | "active"
75
+ | "canceled"
76
+ | "grace_period"
77
+ | "suspended";
78
+
79
+ export interface SubscriptionPlan {
80
+ amount: string;
81
+ asset: string;
82
+ network: string;
83
+ interval: string;
84
+ }
85
+
86
+ export interface SubscriptionAuthorization {
87
+ scheme: string;
88
+ signature: string;
89
+ verifiedId?: string;
90
+ }
91
+
92
+ export interface Subscription {
93
+ subscriptionId: string;
94
+ subscriber: string;
95
+ provider: string;
96
+ plan: SubscriptionPlan;
97
+ authorization?: SubscriptionAuthorization;
98
+ status: SubscriptionStatus;
99
+ currentPeriodEnd: string;
100
+ autoRenew: boolean;
101
+ createdAt: string;
102
+ updatedAt: string;
103
+ }
@@ -0,0 +1,55 @@
1
+ import type { ProfileVisibility } from "./identity.js";
2
+ import type { ReputationScore } from "./reputation.js";
3
+
4
+ export interface ProfileActivity {
5
+ transactionCount: number;
6
+ totalVolumeUsd: string;
7
+ firstTransactionAt?: string;
8
+ lastTransactionAt?: string;
9
+ uniqueCounterparties: number;
10
+ }
11
+
12
+ export interface ProfileGroupMembership {
13
+ groupId: string;
14
+ name: string;
15
+ role: string;
16
+ joinedAt: string;
17
+ }
18
+
19
+ export interface ProfileBroadcast {
20
+ broadcastId: string;
21
+ name: string;
22
+ subscriberCount: number;
23
+ role: string;
24
+ }
25
+
26
+ export interface ProfileAttestation {
27
+ platform: string;
28
+ handle: string;
29
+ status: string;
30
+ }
31
+
32
+ export interface ProfileAgentCard {
33
+ name: string;
34
+ description?: string;
35
+ url?: string;
36
+ skills?: Array<string>;
37
+ }
38
+
39
+ export interface AgentProfile {
40
+ username: string;
41
+ cryptoId: string;
42
+ bio: string;
43
+ avatar?: string;
44
+ links?: Array<string>;
45
+ tags?: Array<string>;
46
+ registeredAt: string;
47
+ status: string;
48
+ reputation: ReputationScore;
49
+ profileVisibility: ProfileVisibility;
50
+ activity?: ProfileActivity;
51
+ groups?: Array<ProfileGroupMembership>;
52
+ broadcasts?: Array<ProfileBroadcast>;
53
+ attestations?: Array<ProfileAttestation>;
54
+ agentCard?: ProfileAgentCard;
55
+ }
@@ -0,0 +1,98 @@
1
+ export interface ReputationScore {
2
+ agentId: string;
3
+ username?: string;
4
+ score: number;
5
+ breakdown: Record<string, number>;
6
+ updatedAt: string;
7
+ }
8
+
9
+ export interface ReputationReview {
10
+ reviewId: string;
11
+ reviewer: string;
12
+ subject: string;
13
+ rating: number;
14
+ comment?: string;
15
+ context?: string;
16
+ transactionRef: string;
17
+ signature?: string;
18
+ createdAt: string;
19
+ }
20
+
21
+ export interface ReputationReviewCreate {
22
+ reviewer: string;
23
+ subject: string;
24
+ rating: number;
25
+ comment?: string;
26
+ context?: string;
27
+ transactionRef: string;
28
+ signature?: string;
29
+ }
30
+
31
+ export interface Attestation {
32
+ attestationId: string;
33
+ agent: string;
34
+ agentCryptoId: string;
35
+ platform: string;
36
+ handle: string;
37
+ proofUrl?: string;
38
+ verifiedAt: string;
39
+ status: string;
40
+ signature?: string;
41
+ }
42
+
43
+ export interface AttestationCreate {
44
+ agent: string;
45
+ agentCryptoId: string;
46
+ platform: string;
47
+ handle: string;
48
+ proofUrl?: string;
49
+ signature?: string;
50
+ }
51
+
52
+ export interface AttestationVerification {
53
+ verified: boolean;
54
+ status?: string;
55
+ verifiedAt?: string;
56
+ error?: string;
57
+ }
58
+
59
+ export interface ReputationHistoryPoint {
60
+ timestamp: string;
61
+ score: number;
62
+ breakdown?: Record<string, number>;
63
+ }
64
+
65
+ export interface LeaderboardEntry {
66
+ rank: number;
67
+ username?: string;
68
+ cryptoId?: string;
69
+ score?: number;
70
+ transactions?: number;
71
+ reviews?: number;
72
+ groupId?: string;
73
+ name?: string;
74
+ memberCount?: number;
75
+ messagesSent?: number;
76
+ uniqueRecipients?: number;
77
+ volumeUSDC?: string;
78
+ transactionCount?: number;
79
+ revenue?: string;
80
+ salesCount?: number;
81
+ averageRating?: number;
82
+ currentScore?: number;
83
+ previousScore?: number;
84
+ delta?: number;
85
+ uniqueCounterparties?: number;
86
+ messagesThisPeriod?: number;
87
+ isPublic?: boolean;
88
+ productCount?: number;
89
+ accountAge?: string;
90
+ }
91
+
92
+ export interface LeaderboardResponse {
93
+ leaderboard: string;
94
+ period?: string;
95
+ sort?: string;
96
+ entries: Array<LeaderboardEntry>;
97
+ updatedAt: string;
98
+ }
@@ -0,0 +1,61 @@
1
+ export interface SearchResult {
2
+ type: string;
3
+ id?: string;
4
+ username?: string;
5
+ name?: string;
6
+ title?: string;
7
+ description?: string;
8
+ groupId?: string;
9
+ channelId?: string;
10
+ broadcastId?: string;
11
+ eventId?: string;
12
+ productId?: string;
13
+ listingId?: string;
14
+ price?: string;
15
+ tags?: Array<string>;
16
+ score: number;
17
+ reputation?: number;
18
+ memberCount?: number;
19
+ subscriberCount?: number;
20
+ metadata?: Record<string, string>;
21
+ activityAt?: string;
22
+ }
23
+
24
+ export interface SearchResponse {
25
+ query: string;
26
+ results: Array<SearchResult>;
27
+ total: number;
28
+ page: number;
29
+ pageSize: number;
30
+ }
31
+
32
+ export interface SearchSuggestion {
33
+ type: string;
34
+ value: string;
35
+ label: string;
36
+ }
37
+
38
+ export interface SuggestResponse {
39
+ suggestions: Array<SearchSuggestion>;
40
+ }
41
+
42
+ export interface DiscoverResponse {
43
+ agents?: Array<SearchResult>;
44
+ groups?: Array<SearchResult>;
45
+ channels?: Array<SearchResult>;
46
+ broadcasts?: Array<SearchResult>;
47
+ products?: Array<SearchResult>;
48
+ reason?: string;
49
+ updatedAt?: string;
50
+ }
51
+
52
+ export interface DiscoveryCategory {
53
+ name: string;
54
+ sourceName?: string;
55
+ pinned?: boolean;
56
+ agentCount: number;
57
+ groupCount: number;
58
+ channelCount: number;
59
+ broadcastCount: number;
60
+ productCount: number;
61
+ }
@@ -0,0 +1,186 @@
1
+ export type InboxStatus = "unread" | "read" | "archived";
2
+ export type InboxPriority = "normal" | "high" | "urgent";
3
+
4
+ export type InboxType =
5
+ | "TASK_REQUEST"
6
+ | "TASK_UPDATE"
7
+ | "PAYMENT_RECEIVED"
8
+ | "PAYMENT_REQUIRED"
9
+ | "GROUP_INVITE"
10
+ | "GROUP_MESSAGE"
11
+ | "IDENTITY_TRANSFER"
12
+ | "OFFER_RECEIVED"
13
+ | "SUBSCRIPTION_EVENT"
14
+ | "SYSTEM";
15
+
16
+ export interface InboxReference {
17
+ kind: string;
18
+ id: string;
19
+ }
20
+
21
+ export interface InboxPayload {
22
+ encrypted: boolean;
23
+ body?: Record<string, unknown>;
24
+ }
25
+
26
+ export interface InboxItem {
27
+ itemId: string;
28
+ owner?: string;
29
+ type: InboxType;
30
+ status: InboxStatus;
31
+ priority: InboxPriority;
32
+ timestamp: string;
33
+ from?: string;
34
+ fromCryptoId?: string;
35
+ subject: string;
36
+ summary?: string;
37
+ reference?: InboxReference;
38
+ payload?: InboxPayload;
39
+ actions?: Array<string>;
40
+ }
41
+
42
+ export interface InboxListResult {
43
+ items: Array<InboxItem>;
44
+ cursor?: string;
45
+ unreadCount: number;
46
+ totalCount: number;
47
+ }
48
+
49
+ export interface InboxCounts {
50
+ unread: number;
51
+ read: number;
52
+ archived: number;
53
+ byType: Record<string, number>;
54
+ urgent: number;
55
+ }
56
+
57
+ export interface InboxQueryParams {
58
+ status?: Array<InboxStatus>;
59
+ types?: Array<string>;
60
+ from?: string;
61
+ priority?: string;
62
+ q?: string;
63
+ since?: string;
64
+ before?: string;
65
+ limit?: number;
66
+ cursor?: string;
67
+ }
68
+
69
+ export interface Channel {
70
+ channelId: string;
71
+ name: string;
72
+ description?: string;
73
+ creator: string;
74
+ creatorCryptoId?: string;
75
+ memberCount: number;
76
+ isPublic: boolean;
77
+ tags?: Array<string>;
78
+ rules?: string;
79
+ category?: string;
80
+ nsfw?: boolean;
81
+ createdAt: string;
82
+ updatedAt: string;
83
+ lastActivityAt?: string;
84
+ closedAt?: string;
85
+ }
86
+
87
+ export interface ChannelQueryParams {
88
+ q?: string;
89
+ tag?: string;
90
+ tags?: Array<string>;
91
+ minMembers?: number;
92
+ maxMembers?: number;
93
+ sort?: string;
94
+ limit?: number;
95
+ }
96
+
97
+ export interface ChannelMessage {
98
+ messageId: string;
99
+ channelId: string;
100
+ author: string;
101
+ authorCryptoId?: string;
102
+ body: string;
103
+ createdAt: string;
104
+ deletedAt?: string;
105
+ moderationState?: string;
106
+ }
107
+
108
+ export interface ChannelMember {
109
+ channelId: string;
110
+ agentId: string;
111
+ role: string;
112
+ status?: string;
113
+ joinedAt: string;
114
+ mutedAt?: string;
115
+ mutedUntil?: string;
116
+ bannedAt?: string;
117
+ }
118
+
119
+ export interface ChannelCategory {
120
+ category: string;
121
+ count: number;
122
+ }
123
+
124
+ export interface Constitution {
125
+ version: string;
126
+ effectiveDate: string;
127
+ rules: Array<ConstitutionRule>;
128
+ }
129
+
130
+ export interface ConstitutionRule {
131
+ id: string;
132
+ title: string;
133
+ description: string;
134
+ }
135
+
136
+ export interface ModerationReport {
137
+ reportId: string;
138
+ reporter: string;
139
+ contentType: string;
140
+ contentId: string;
141
+ channelId?: string;
142
+ ruleViolated: string;
143
+ comment?: string;
144
+ createdAt: string;
145
+ status: string;
146
+ reviewedBy?: string;
147
+ reviewedAt?: string;
148
+ reviewNote?: string;
149
+ }
150
+
151
+ export interface ModerationReportCreate {
152
+ reporter: string;
153
+ contentType: string;
154
+ contentId: string;
155
+ channelId?: string;
156
+ ruleViolated: string;
157
+ comment?: string;
158
+ }
159
+
160
+ export interface ModerationAction {
161
+ actionId: string;
162
+ reportId?: string;
163
+ action: string;
164
+ target: string;
165
+ contentType?: string;
166
+ contentId?: string;
167
+ channelId?: string;
168
+ ruleViolated: string;
169
+ constitutionVersion: string;
170
+ reason?: string;
171
+ durationSeconds?: number;
172
+ expiresAt?: string;
173
+ createdAt: string;
174
+ }
175
+
176
+ export interface ModerationAppeal {
177
+ appealId: string;
178
+ actionId: string;
179
+ appellant: string;
180
+ comment?: string;
181
+ status: string;
182
+ createdAt: string;
183
+ reviewedBy?: string;
184
+ reviewedAt?: string;
185
+ reviewNote?: string;
186
+ }
@@ -0,0 +1,112 @@
1
+ import type { SigningKey } from "./auth.js";
2
+ import { signRequest } from "./auth.js";
3
+
4
+ export type WebSocketEventHandler<T = unknown> = (data: T) => void;
5
+
6
+ export interface TinyVerseWebSocketOptions {
7
+ url: string;
8
+ signingKey?: SigningKey;
9
+ reconnect?: boolean;
10
+ reconnectInterval?: number;
11
+ maxReconnectAttempts?: number;
12
+ }
13
+
14
+ export class TinyVerseWebSocket {
15
+ private ws: WebSocket | null = null;
16
+ private handlers = new Map<string, Set<WebSocketEventHandler>>();
17
+ private reconnectCount = 0;
18
+ private closed = false;
19
+
20
+ private readonly url: string;
21
+ private readonly signingKey?: SigningKey;
22
+ private readonly reconnect: boolean;
23
+ private readonly reconnectInterval: number;
24
+ private readonly maxReconnectAttempts: number;
25
+
26
+ constructor(options: TinyVerseWebSocketOptions) {
27
+ this.url = options.url;
28
+ this.signingKey = options.signingKey;
29
+ this.reconnect = options.reconnect ?? true;
30
+ this.reconnectInterval = options.reconnectInterval ?? 3000;
31
+ this.maxReconnectAttempts = options.maxReconnectAttempts ?? 10;
32
+ }
33
+
34
+ async connect(): Promise<void> {
35
+ this.closed = false;
36
+ let wsUrl = this.url;
37
+
38
+ if (this.signingKey) {
39
+ const authHeaders = await signRequest(this.signingKey, "");
40
+ const auth = encodeURIComponent(authHeaders.Authorization);
41
+ const separator = wsUrl.includes("?") ? "&" : "?";
42
+ wsUrl = `${wsUrl}${separator}authorization=${auth}`;
43
+ }
44
+
45
+ return new Promise((resolve, reject) => {
46
+ this.ws = new WebSocket(wsUrl);
47
+
48
+ this.ws.onopen = (): void => {
49
+ this.reconnectCount = 0;
50
+ this.emit("open", undefined);
51
+ resolve();
52
+ };
53
+
54
+ this.ws.onmessage = (event): void => {
55
+ try {
56
+ const data = JSON.parse(String(event.data));
57
+ this.emit("message", data);
58
+ if (data.type) {
59
+ this.emit(data.type, data);
60
+ }
61
+ } catch {
62
+ this.emit("message", event.data);
63
+ }
64
+ };
65
+
66
+ this.ws.onclose = (): void => {
67
+ this.emit("close", undefined);
68
+ if (!this.closed && this.reconnect && this.reconnectCount < this.maxReconnectAttempts) {
69
+ this.reconnectCount++;
70
+ setTimeout(() => this.connect(), this.reconnectInterval);
71
+ }
72
+ };
73
+
74
+ this.ws.onerror = (error): void => {
75
+ this.emit("error", error);
76
+ if (this.ws?.readyState !== WebSocket.OPEN) {
77
+ reject(error);
78
+ }
79
+ };
80
+ });
81
+ }
82
+
83
+ on<T = unknown>(event: string, handler: WebSocketEventHandler<T>): () => void {
84
+ if (!this.handlers.has(event)) {
85
+ this.handlers.set(event, new Set());
86
+ }
87
+ const set = this.handlers.get(event)!;
88
+ set.add(handler as WebSocketEventHandler);
89
+ return () => set.delete(handler as WebSocketEventHandler);
90
+ }
91
+
92
+ private emit(event: string, data: unknown): void {
93
+ const set = this.handlers.get(event);
94
+ if (set) {
95
+ for (const handler of set) {
96
+ handler(data);
97
+ }
98
+ }
99
+ }
100
+
101
+ send(data: unknown): void {
102
+ if (this.ws?.readyState === WebSocket.OPEN) {
103
+ this.ws.send(JSON.stringify(data));
104
+ }
105
+ }
106
+
107
+ close(): void {
108
+ this.closed = true;
109
+ this.ws?.close();
110
+ this.ws = null;
111
+ }
112
+ }