@clawdvault/sdk 0.1.2 → 0.1.3

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 CHANGED
@@ -101,6 +101,103 @@ if (graduated) {
101
101
  }
102
102
  ```
103
103
 
104
+ ## Real-Time Streaming
105
+
106
+ Subscribe to live data feeds using Server-Sent Events (SSE):
107
+
108
+ ```typescript
109
+ import { createStreaming } from '@clawdvault/sdk';
110
+
111
+ const streaming = createStreaming('https://clawdvault.com/api');
112
+
113
+ // Quick subscription helpers
114
+ const { unsubscribe, connection } = streaming.onTrades('TOKEN_MINT', (trade) => {
115
+ console.log(`${trade.type.toUpperCase()}: ${trade.sol_amount} SOL`);
116
+ });
117
+
118
+ // Later: cleanup
119
+ unsubscribe();
120
+ connection.disconnect();
121
+ ```
122
+
123
+ ### Streaming Trades
124
+
125
+ ```typescript
126
+ const conn = streaming.streamTrades('TOKEN_MINT');
127
+
128
+ conn.onConnect(() => console.log('Connected!'));
129
+ conn.onDisconnect(() => console.log('Disconnected'));
130
+ conn.onError((err) => console.error(err));
131
+
132
+ conn.on('trade', (trade) => {
133
+ console.log('New trade:', trade.type, trade.sol_amount, 'SOL');
134
+ });
135
+
136
+ conn.connect();
137
+
138
+ // Cleanup
139
+ conn.disconnect();
140
+ ```
141
+
142
+ ### Streaming Token Price Updates
143
+
144
+ ```typescript
145
+ const conn = streaming.streamToken('TOKEN_MINT');
146
+
147
+ conn.on('connected', (data) => {
148
+ console.log(`${data.name} (${data.symbol})`);
149
+ console.log(`Price: ${data.price_sol} SOL`);
150
+ console.log(`Market Cap: ${data.market_cap_sol} SOL`);
151
+ });
152
+
153
+ conn.on('update', (update) => {
154
+ console.log(`New price: ${update.price_sol} SOL`);
155
+ });
156
+
157
+ conn.on('trade', (trade) => {
158
+ console.log(`Price changed from ${trade.type}: ${trade.price_sol}`);
159
+ });
160
+
161
+ conn.connect();
162
+ ```
163
+
164
+ ### Streaming Chat Messages
165
+
166
+ ```typescript
167
+ const conn = streaming.streamChat('TOKEN_MINT');
168
+
169
+ conn.on('message', (msg) => {
170
+ const sender = msg.username || msg.wallet.slice(0, 8);
171
+ console.log(`${sender}: ${msg.message}`);
172
+ });
173
+
174
+ conn.on('reaction_added', (reaction) => {
175
+ console.log(`${reaction.emoji} added to message`);
176
+ });
177
+
178
+ conn.connect();
179
+ ```
180
+
181
+ ### Streaming Options
182
+
183
+ ```typescript
184
+ const streaming = createStreaming('https://clawdvault.com/api', {
185
+ autoReconnect: true, // Auto-reconnect on disconnect (default: true)
186
+ reconnectDelay: 3000, // Initial delay before reconnect (default: 3000ms)
187
+ maxReconnectAttempts: 10, // Max attempts before giving up (default: 10)
188
+ });
189
+ ```
190
+
191
+ ### Disconnect All Streams
192
+
193
+ ```typescript
194
+ // Disconnect everything
195
+ streaming.disconnectAll();
196
+
197
+ // Or disconnect specific stream
198
+ streaming.disconnect('trades', 'TOKEN_MINT');
199
+ ```
200
+
104
201
  ## Configuration
105
202
 
106
203
  ```typescript
package/dist/index.d.mts CHANGED
@@ -600,6 +600,161 @@ declare class ClawdVaultClient {
600
600
  */
601
601
  declare function createClient(config?: ClawdVaultConfig): ClawdVaultClient;
602
602
 
603
+ /**
604
+ * ClawdVault Streaming Client
605
+ * Real-time data feeds via Server-Sent Events
606
+ */
607
+ interface StreamTrade {
608
+ id: string;
609
+ type: 'buy' | 'sell';
610
+ sol_amount: number;
611
+ token_amount: number;
612
+ price_sol: number;
613
+ trader: string;
614
+ signature?: string;
615
+ created_at: string;
616
+ }
617
+ interface StreamTokenUpdate {
618
+ price_sol: number;
619
+ market_cap_sol: number;
620
+ virtual_sol_reserves: number;
621
+ virtual_token_reserves: number;
622
+ real_sol_reserves: number;
623
+ graduated: boolean;
624
+ timestamp: number;
625
+ }
626
+ interface StreamTokenConnected extends StreamTokenUpdate {
627
+ mint: string;
628
+ name: string;
629
+ symbol: string;
630
+ }
631
+ interface StreamChatMessage {
632
+ id: string;
633
+ wallet: string;
634
+ username?: string;
635
+ message: string;
636
+ reply_to?: string;
637
+ created_at: string;
638
+ }
639
+ interface StreamReaction {
640
+ message_id: string;
641
+ emoji: string;
642
+ wallet: string;
643
+ }
644
+ interface StreamingOptions {
645
+ /** Auto-reconnect on connection loss (default: true) */
646
+ autoReconnect?: boolean;
647
+ /** Reconnect delay in ms (default: 3000) */
648
+ reconnectDelay?: number;
649
+ /** Max reconnect attempts (default: 10) */
650
+ maxReconnectAttempts?: number;
651
+ }
652
+ type EventCallback<T> = (data: T) => void;
653
+ type ErrorCallback = (error: Error) => void;
654
+ type ConnectionCallback = () => void;
655
+ declare class StreamConnection {
656
+ private eventSource;
657
+ private url;
658
+ private options;
659
+ private reconnectAttempts;
660
+ private reconnectTimeout;
661
+ private listeners;
662
+ private onConnectCallbacks;
663
+ private onDisconnectCallbacks;
664
+ private onErrorCallbacks;
665
+ private isConnected;
666
+ private isManuallyDisconnected;
667
+ constructor(url: string, options?: StreamingOptions);
668
+ /**
669
+ * Connect to the stream
670
+ */
671
+ connect(): void;
672
+ private handleEvent;
673
+ private scheduleReconnect;
674
+ /**
675
+ * Disconnect from the stream
676
+ */
677
+ disconnect(): void;
678
+ /**
679
+ * Subscribe to an event type
680
+ */
681
+ on<T>(eventType: string, callback: EventCallback<T>): () => void;
682
+ /**
683
+ * One-time event listener
684
+ */
685
+ once<T>(eventType: string, callback: EventCallback<T>): void;
686
+ /**
687
+ * Register connection callback
688
+ */
689
+ onConnect(callback: ConnectionCallback): () => void;
690
+ /**
691
+ * Register disconnection callback
692
+ */
693
+ onDisconnect(callback: ConnectionCallback): () => void;
694
+ /**
695
+ * Register error callback
696
+ */
697
+ onError(callback: ErrorCallback): () => void;
698
+ /**
699
+ * Check if connected
700
+ */
701
+ get connected(): boolean;
702
+ }
703
+ /**
704
+ * Streaming client for ClawdVault
705
+ */
706
+ declare class ClawdVaultStreaming {
707
+ private baseUrl;
708
+ private connections;
709
+ private options;
710
+ constructor(baseUrl?: string, options?: StreamingOptions);
711
+ /**
712
+ * Stream trades for a token
713
+ */
714
+ streamTrades(mint: string): StreamConnection;
715
+ /**
716
+ * Stream token updates (price, market cap)
717
+ */
718
+ streamToken(mint: string): StreamConnection;
719
+ /**
720
+ * Stream chat messages
721
+ */
722
+ streamChat(mint: string): StreamConnection;
723
+ /**
724
+ * Convenience: Subscribe to trades with callback
725
+ */
726
+ onTrades(mint: string, callback: EventCallback<StreamTrade>): {
727
+ unsubscribe: () => void;
728
+ connection: StreamConnection;
729
+ };
730
+ /**
731
+ * Convenience: Subscribe to token price updates
732
+ */
733
+ onPrice(mint: string, callback: EventCallback<StreamTokenUpdate>): {
734
+ unsubscribe: () => void;
735
+ connection: StreamConnection;
736
+ };
737
+ /**
738
+ * Convenience: Subscribe to chat messages
739
+ */
740
+ onChat(mint: string, callback: EventCallback<StreamChatMessage>): {
741
+ unsubscribe: () => void;
742
+ connection: StreamConnection;
743
+ };
744
+ /**
745
+ * Disconnect all streams
746
+ */
747
+ disconnectAll(): void;
748
+ /**
749
+ * Disconnect a specific stream
750
+ */
751
+ disconnect(type: 'trades' | 'token' | 'chat', mint: string): void;
752
+ }
753
+ /**
754
+ * Create streaming client
755
+ */
756
+ declare function createStreaming(baseUrl?: string, options?: StreamingOptions): ClawdVaultStreaming;
757
+
603
758
  /**
604
759
  * ClawdVault SDK
605
760
  * TypeScript client for ClawdVault token launchpad on Solana
@@ -610,4 +765,4 @@ declare function createClient(config?: ClawdVaultConfig): ClawdVaultClient;
610
765
  declare const PROGRAM_ID = "GUyF2TVe32Cid4iGVt2F6wPYDhLSVmTUZBj2974outYM";
611
766
  declare const DEFAULT_BASE_URL = "https://clawdvault.com/api";
612
767
 
613
- export { type BalanceResponse, type CandleData, type CandlesParams, type CandlesResponse, type ChatMessage, type ChatMessagesResponse, type ChatParams, ClawdVaultClient, type ClawdVaultConfig, DEFAULT_BASE_URL, type ExecuteCreateRequest, type ExecuteCreateResponse, type ExecuteTradeRequest, type ExecuteTradeResponse, type GraduationStatusResponse, type HolderInfo, type HoldersResponse, type JupiterExecuteRequest, type JupiterQuoteResponse, type JupiterStatusResponse, type JupiterSwapRequest, KeypairSigner, type NetworkStatusResponse, PROGRAM_ID, PhantomSigner, type PhantomWallet, type PrepareCreateRequest, type PrepareCreateResponse, type PrepareTradeRequest, type PrepareTradeResponse, type QuoteParams, type QuoteResponse, type SendChatRequest, type SessionResponse, type SessionValidateResponse, type SolPriceResponse, type StatsResponse, type Token, type TokenDetailResponse, type TokenListParams, type TokenListResponse, type Trade, type TradeHistoryResponse, type TradesParams, type UpdateProfileRequest, type UploadResponse, type UserProfile, type WalletSigner, createAuthSignature, createClient, signAndSerialize, verifySignature };
768
+ export { type BalanceResponse, type CandleData, type CandlesParams, type CandlesResponse, type ChatMessage, type ChatMessagesResponse, type ChatParams, ClawdVaultClient, type ClawdVaultConfig, ClawdVaultStreaming, DEFAULT_BASE_URL, type ExecuteCreateRequest, type ExecuteCreateResponse, type ExecuteTradeRequest, type ExecuteTradeResponse, type GraduationStatusResponse, type HolderInfo, type HoldersResponse, type JupiterExecuteRequest, type JupiterQuoteResponse, type JupiterStatusResponse, type JupiterSwapRequest, KeypairSigner, type NetworkStatusResponse, PROGRAM_ID, PhantomSigner, type PhantomWallet, type PrepareCreateRequest, type PrepareCreateResponse, type PrepareTradeRequest, type PrepareTradeResponse, type QuoteParams, type QuoteResponse, type SendChatRequest, type SessionResponse, type SessionValidateResponse, type SolPriceResponse, type StatsResponse, type StreamChatMessage, StreamConnection, type StreamReaction, type StreamTokenConnected, type StreamTokenUpdate, type StreamTrade, type StreamingOptions, type Token, type TokenDetailResponse, type TokenListParams, type TokenListResponse, type Trade, type TradeHistoryResponse, type TradesParams, type UpdateProfileRequest, type UploadResponse, type UserProfile, type WalletSigner, createAuthSignature, createClient, createStreaming, signAndSerialize, verifySignature };
package/dist/index.d.ts CHANGED
@@ -600,6 +600,161 @@ declare class ClawdVaultClient {
600
600
  */
601
601
  declare function createClient(config?: ClawdVaultConfig): ClawdVaultClient;
602
602
 
603
+ /**
604
+ * ClawdVault Streaming Client
605
+ * Real-time data feeds via Server-Sent Events
606
+ */
607
+ interface StreamTrade {
608
+ id: string;
609
+ type: 'buy' | 'sell';
610
+ sol_amount: number;
611
+ token_amount: number;
612
+ price_sol: number;
613
+ trader: string;
614
+ signature?: string;
615
+ created_at: string;
616
+ }
617
+ interface StreamTokenUpdate {
618
+ price_sol: number;
619
+ market_cap_sol: number;
620
+ virtual_sol_reserves: number;
621
+ virtual_token_reserves: number;
622
+ real_sol_reserves: number;
623
+ graduated: boolean;
624
+ timestamp: number;
625
+ }
626
+ interface StreamTokenConnected extends StreamTokenUpdate {
627
+ mint: string;
628
+ name: string;
629
+ symbol: string;
630
+ }
631
+ interface StreamChatMessage {
632
+ id: string;
633
+ wallet: string;
634
+ username?: string;
635
+ message: string;
636
+ reply_to?: string;
637
+ created_at: string;
638
+ }
639
+ interface StreamReaction {
640
+ message_id: string;
641
+ emoji: string;
642
+ wallet: string;
643
+ }
644
+ interface StreamingOptions {
645
+ /** Auto-reconnect on connection loss (default: true) */
646
+ autoReconnect?: boolean;
647
+ /** Reconnect delay in ms (default: 3000) */
648
+ reconnectDelay?: number;
649
+ /** Max reconnect attempts (default: 10) */
650
+ maxReconnectAttempts?: number;
651
+ }
652
+ type EventCallback<T> = (data: T) => void;
653
+ type ErrorCallback = (error: Error) => void;
654
+ type ConnectionCallback = () => void;
655
+ declare class StreamConnection {
656
+ private eventSource;
657
+ private url;
658
+ private options;
659
+ private reconnectAttempts;
660
+ private reconnectTimeout;
661
+ private listeners;
662
+ private onConnectCallbacks;
663
+ private onDisconnectCallbacks;
664
+ private onErrorCallbacks;
665
+ private isConnected;
666
+ private isManuallyDisconnected;
667
+ constructor(url: string, options?: StreamingOptions);
668
+ /**
669
+ * Connect to the stream
670
+ */
671
+ connect(): void;
672
+ private handleEvent;
673
+ private scheduleReconnect;
674
+ /**
675
+ * Disconnect from the stream
676
+ */
677
+ disconnect(): void;
678
+ /**
679
+ * Subscribe to an event type
680
+ */
681
+ on<T>(eventType: string, callback: EventCallback<T>): () => void;
682
+ /**
683
+ * One-time event listener
684
+ */
685
+ once<T>(eventType: string, callback: EventCallback<T>): void;
686
+ /**
687
+ * Register connection callback
688
+ */
689
+ onConnect(callback: ConnectionCallback): () => void;
690
+ /**
691
+ * Register disconnection callback
692
+ */
693
+ onDisconnect(callback: ConnectionCallback): () => void;
694
+ /**
695
+ * Register error callback
696
+ */
697
+ onError(callback: ErrorCallback): () => void;
698
+ /**
699
+ * Check if connected
700
+ */
701
+ get connected(): boolean;
702
+ }
703
+ /**
704
+ * Streaming client for ClawdVault
705
+ */
706
+ declare class ClawdVaultStreaming {
707
+ private baseUrl;
708
+ private connections;
709
+ private options;
710
+ constructor(baseUrl?: string, options?: StreamingOptions);
711
+ /**
712
+ * Stream trades for a token
713
+ */
714
+ streamTrades(mint: string): StreamConnection;
715
+ /**
716
+ * Stream token updates (price, market cap)
717
+ */
718
+ streamToken(mint: string): StreamConnection;
719
+ /**
720
+ * Stream chat messages
721
+ */
722
+ streamChat(mint: string): StreamConnection;
723
+ /**
724
+ * Convenience: Subscribe to trades with callback
725
+ */
726
+ onTrades(mint: string, callback: EventCallback<StreamTrade>): {
727
+ unsubscribe: () => void;
728
+ connection: StreamConnection;
729
+ };
730
+ /**
731
+ * Convenience: Subscribe to token price updates
732
+ */
733
+ onPrice(mint: string, callback: EventCallback<StreamTokenUpdate>): {
734
+ unsubscribe: () => void;
735
+ connection: StreamConnection;
736
+ };
737
+ /**
738
+ * Convenience: Subscribe to chat messages
739
+ */
740
+ onChat(mint: string, callback: EventCallback<StreamChatMessage>): {
741
+ unsubscribe: () => void;
742
+ connection: StreamConnection;
743
+ };
744
+ /**
745
+ * Disconnect all streams
746
+ */
747
+ disconnectAll(): void;
748
+ /**
749
+ * Disconnect a specific stream
750
+ */
751
+ disconnect(type: 'trades' | 'token' | 'chat', mint: string): void;
752
+ }
753
+ /**
754
+ * Create streaming client
755
+ */
756
+ declare function createStreaming(baseUrl?: string, options?: StreamingOptions): ClawdVaultStreaming;
757
+
603
758
  /**
604
759
  * ClawdVault SDK
605
760
  * TypeScript client for ClawdVault token launchpad on Solana
@@ -610,4 +765,4 @@ declare function createClient(config?: ClawdVaultConfig): ClawdVaultClient;
610
765
  declare const PROGRAM_ID = "GUyF2TVe32Cid4iGVt2F6wPYDhLSVmTUZBj2974outYM";
611
766
  declare const DEFAULT_BASE_URL = "https://clawdvault.com/api";
612
767
 
613
- export { type BalanceResponse, type CandleData, type CandlesParams, type CandlesResponse, type ChatMessage, type ChatMessagesResponse, type ChatParams, ClawdVaultClient, type ClawdVaultConfig, DEFAULT_BASE_URL, type ExecuteCreateRequest, type ExecuteCreateResponse, type ExecuteTradeRequest, type ExecuteTradeResponse, type GraduationStatusResponse, type HolderInfo, type HoldersResponse, type JupiterExecuteRequest, type JupiterQuoteResponse, type JupiterStatusResponse, type JupiterSwapRequest, KeypairSigner, type NetworkStatusResponse, PROGRAM_ID, PhantomSigner, type PhantomWallet, type PrepareCreateRequest, type PrepareCreateResponse, type PrepareTradeRequest, type PrepareTradeResponse, type QuoteParams, type QuoteResponse, type SendChatRequest, type SessionResponse, type SessionValidateResponse, type SolPriceResponse, type StatsResponse, type Token, type TokenDetailResponse, type TokenListParams, type TokenListResponse, type Trade, type TradeHistoryResponse, type TradesParams, type UpdateProfileRequest, type UploadResponse, type UserProfile, type WalletSigner, createAuthSignature, createClient, signAndSerialize, verifySignature };
768
+ export { type BalanceResponse, type CandleData, type CandlesParams, type CandlesResponse, type ChatMessage, type ChatMessagesResponse, type ChatParams, ClawdVaultClient, type ClawdVaultConfig, ClawdVaultStreaming, DEFAULT_BASE_URL, type ExecuteCreateRequest, type ExecuteCreateResponse, type ExecuteTradeRequest, type ExecuteTradeResponse, type GraduationStatusResponse, type HolderInfo, type HoldersResponse, type JupiterExecuteRequest, type JupiterQuoteResponse, type JupiterStatusResponse, type JupiterSwapRequest, KeypairSigner, type NetworkStatusResponse, PROGRAM_ID, PhantomSigner, type PhantomWallet, type PrepareCreateRequest, type PrepareCreateResponse, type PrepareTradeRequest, type PrepareTradeResponse, type QuoteParams, type QuoteResponse, type SendChatRequest, type SessionResponse, type SessionValidateResponse, type SolPriceResponse, type StatsResponse, type StreamChatMessage, StreamConnection, type StreamReaction, type StreamTokenConnected, type StreamTokenUpdate, type StreamTrade, type StreamingOptions, type Token, type TokenDetailResponse, type TokenListParams, type TokenListResponse, type Trade, type TradeHistoryResponse, type TradesParams, type UpdateProfileRequest, type UploadResponse, type UserProfile, type WalletSigner, createAuthSignature, createClient, createStreaming, signAndSerialize, verifySignature };
package/dist/index.js CHANGED
@@ -31,14 +31,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  ClawdVaultClient: () => ClawdVaultClient,
34
+ ClawdVaultStreaming: () => ClawdVaultStreaming,
34
35
  DEFAULT_BASE_URL: () => DEFAULT_BASE_URL,
35
36
  Keypair: () => import_web32.Keypair,
36
37
  KeypairSigner: () => KeypairSigner,
37
38
  PROGRAM_ID: () => PROGRAM_ID,
38
39
  PhantomSigner: () => PhantomSigner,
39
40
  PublicKey: () => import_web32.PublicKey,
41
+ StreamConnection: () => StreamConnection,
40
42
  createAuthSignature: () => createAuthSignature,
41
43
  createClient: () => createClient,
44
+ createStreaming: () => createStreaming,
42
45
  signAndSerialize: () => signAndSerialize,
43
46
  verifySignature: () => verifySignature
44
47
  });
@@ -611,6 +614,268 @@ function createClient(config) {
611
614
  return new ClawdVaultClient(config);
612
615
  }
613
616
 
617
+ // src/streaming.ts
618
+ var getEventSource = () => {
619
+ if (typeof EventSource !== "undefined") {
620
+ return EventSource;
621
+ }
622
+ return require("eventsource");
623
+ };
624
+ var StreamConnection = class {
625
+ constructor(url, options = {}) {
626
+ this.eventSource = null;
627
+ this.reconnectAttempts = 0;
628
+ this.reconnectTimeout = null;
629
+ this.listeners = /* @__PURE__ */ new Map();
630
+ this.onConnectCallbacks = /* @__PURE__ */ new Set();
631
+ this.onDisconnectCallbacks = /* @__PURE__ */ new Set();
632
+ this.onErrorCallbacks = /* @__PURE__ */ new Set();
633
+ this.isConnected = false;
634
+ this.isManuallyDisconnected = false;
635
+ this.url = url;
636
+ this.options = {
637
+ autoReconnect: options.autoReconnect ?? true,
638
+ reconnectDelay: options.reconnectDelay ?? 3e3,
639
+ maxReconnectAttempts: options.maxReconnectAttempts ?? 10
640
+ };
641
+ }
642
+ /**
643
+ * Connect to the stream
644
+ */
645
+ connect() {
646
+ if (this.eventSource) {
647
+ return;
648
+ }
649
+ this.isManuallyDisconnected = false;
650
+ const EventSourceImpl = getEventSource();
651
+ this.eventSource = new EventSourceImpl(this.url);
652
+ this.eventSource.onopen = () => {
653
+ this.isConnected = true;
654
+ this.reconnectAttempts = 0;
655
+ this.onConnectCallbacks.forEach((cb) => cb());
656
+ };
657
+ this.eventSource.onerror = (event) => {
658
+ const wasConnected = this.isConnected;
659
+ this.isConnected = false;
660
+ if (wasConnected) {
661
+ this.onDisconnectCallbacks.forEach((cb) => cb());
662
+ }
663
+ this.onErrorCallbacks.forEach((cb) => cb(new Error("Stream connection error")));
664
+ if (this.options.autoReconnect && !this.isManuallyDisconnected) {
665
+ this.scheduleReconnect();
666
+ }
667
+ };
668
+ this.eventSource.onmessage = (event) => {
669
+ this.handleEvent("message", event.data);
670
+ };
671
+ for (const eventType of this.listeners.keys()) {
672
+ this.eventSource.addEventListener(eventType, (event) => {
673
+ this.handleEvent(eventType, event.data);
674
+ });
675
+ }
676
+ }
677
+ handleEvent(eventType, data) {
678
+ const callbacks = this.listeners.get(eventType);
679
+ if (!callbacks) return;
680
+ try {
681
+ const parsed = JSON.parse(data);
682
+ callbacks.forEach((cb) => cb(parsed));
683
+ } catch {
684
+ }
685
+ }
686
+ scheduleReconnect() {
687
+ if (this.reconnectTimeout) {
688
+ clearTimeout(this.reconnectTimeout);
689
+ }
690
+ if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
691
+ this.onErrorCallbacks.forEach(
692
+ (cb) => cb(new Error(`Max reconnect attempts (${this.options.maxReconnectAttempts}) reached`))
693
+ );
694
+ return;
695
+ }
696
+ this.reconnectAttempts++;
697
+ const delay = this.options.reconnectDelay * Math.pow(1.5, this.reconnectAttempts - 1);
698
+ this.reconnectTimeout = setTimeout(() => {
699
+ this.eventSource?.close();
700
+ this.eventSource = null;
701
+ this.connect();
702
+ }, delay);
703
+ }
704
+ /**
705
+ * Disconnect from the stream
706
+ */
707
+ disconnect() {
708
+ this.isManuallyDisconnected = true;
709
+ if (this.reconnectTimeout) {
710
+ clearTimeout(this.reconnectTimeout);
711
+ this.reconnectTimeout = null;
712
+ }
713
+ if (this.eventSource) {
714
+ this.eventSource.close();
715
+ this.eventSource = null;
716
+ }
717
+ if (this.isConnected) {
718
+ this.isConnected = false;
719
+ this.onDisconnectCallbacks.forEach((cb) => cb());
720
+ }
721
+ }
722
+ /**
723
+ * Subscribe to an event type
724
+ */
725
+ on(eventType, callback) {
726
+ if (!this.listeners.has(eventType)) {
727
+ this.listeners.set(eventType, /* @__PURE__ */ new Set());
728
+ if (this.eventSource) {
729
+ this.eventSource.addEventListener(eventType, (event) => {
730
+ this.handleEvent(eventType, event.data);
731
+ });
732
+ }
733
+ }
734
+ this.listeners.get(eventType).add(callback);
735
+ return () => {
736
+ const callbacks = this.listeners.get(eventType);
737
+ if (callbacks) {
738
+ callbacks.delete(callback);
739
+ }
740
+ };
741
+ }
742
+ /**
743
+ * One-time event listener
744
+ */
745
+ once(eventType, callback) {
746
+ const unsubscribe = this.on(eventType, (data) => {
747
+ unsubscribe();
748
+ callback(data);
749
+ });
750
+ }
751
+ /**
752
+ * Register connection callback
753
+ */
754
+ onConnect(callback) {
755
+ this.onConnectCallbacks.add(callback);
756
+ return () => this.onConnectCallbacks.delete(callback);
757
+ }
758
+ /**
759
+ * Register disconnection callback
760
+ */
761
+ onDisconnect(callback) {
762
+ this.onDisconnectCallbacks.add(callback);
763
+ return () => this.onDisconnectCallbacks.delete(callback);
764
+ }
765
+ /**
766
+ * Register error callback
767
+ */
768
+ onError(callback) {
769
+ this.onErrorCallbacks.add(callback);
770
+ return () => this.onErrorCallbacks.delete(callback);
771
+ }
772
+ /**
773
+ * Check if connected
774
+ */
775
+ get connected() {
776
+ return this.isConnected;
777
+ }
778
+ };
779
+ var ClawdVaultStreaming = class {
780
+ constructor(baseUrl = "https://clawdvault.com/api", options = {}) {
781
+ this.connections = /* @__PURE__ */ new Map();
782
+ this.baseUrl = baseUrl.replace(/\/$/, "");
783
+ this.options = options;
784
+ }
785
+ /**
786
+ * Stream trades for a token
787
+ */
788
+ streamTrades(mint) {
789
+ const key = `trades:${mint}`;
790
+ if (!this.connections.has(key)) {
791
+ const conn = new StreamConnection(
792
+ `${this.baseUrl}/stream/trades?mint=${mint}`,
793
+ this.options
794
+ );
795
+ this.connections.set(key, conn);
796
+ }
797
+ return this.connections.get(key);
798
+ }
799
+ /**
800
+ * Stream token updates (price, market cap)
801
+ */
802
+ streamToken(mint) {
803
+ const key = `token:${mint}`;
804
+ if (!this.connections.has(key)) {
805
+ const conn = new StreamConnection(
806
+ `${this.baseUrl}/stream/token?mint=${mint}`,
807
+ this.options
808
+ );
809
+ this.connections.set(key, conn);
810
+ }
811
+ return this.connections.get(key);
812
+ }
813
+ /**
814
+ * Stream chat messages
815
+ */
816
+ streamChat(mint) {
817
+ const key = `chat:${mint}`;
818
+ if (!this.connections.has(key)) {
819
+ const conn = new StreamConnection(
820
+ `${this.baseUrl}/stream/chat?mint=${mint}`,
821
+ this.options
822
+ );
823
+ this.connections.set(key, conn);
824
+ }
825
+ return this.connections.get(key);
826
+ }
827
+ /**
828
+ * Convenience: Subscribe to trades with callback
829
+ */
830
+ onTrades(mint, callback) {
831
+ const conn = this.streamTrades(mint);
832
+ const unsubscribe = conn.on("trade", callback);
833
+ conn.connect();
834
+ return { unsubscribe, connection: conn };
835
+ }
836
+ /**
837
+ * Convenience: Subscribe to token price updates
838
+ */
839
+ onPrice(mint, callback) {
840
+ const conn = this.streamToken(mint);
841
+ const unsubscribe = conn.on("update", callback);
842
+ conn.connect();
843
+ return { unsubscribe, connection: conn };
844
+ }
845
+ /**
846
+ * Convenience: Subscribe to chat messages
847
+ */
848
+ onChat(mint, callback) {
849
+ const conn = this.streamChat(mint);
850
+ const unsubscribe = conn.on("message", callback);
851
+ conn.connect();
852
+ return { unsubscribe, connection: conn };
853
+ }
854
+ /**
855
+ * Disconnect all streams
856
+ */
857
+ disconnectAll() {
858
+ for (const conn of this.connections.values()) {
859
+ conn.disconnect();
860
+ }
861
+ this.connections.clear();
862
+ }
863
+ /**
864
+ * Disconnect a specific stream
865
+ */
866
+ disconnect(type, mint) {
867
+ const key = `${type}:${mint}`;
868
+ const conn = this.connections.get(key);
869
+ if (conn) {
870
+ conn.disconnect();
871
+ this.connections.delete(key);
872
+ }
873
+ }
874
+ };
875
+ function createStreaming(baseUrl, options) {
876
+ return new ClawdVaultStreaming(baseUrl, options);
877
+ }
878
+
614
879
  // src/index.ts
615
880
  var import_web32 = require("@solana/web3.js");
616
881
  var PROGRAM_ID = "GUyF2TVe32Cid4iGVt2F6wPYDhLSVmTUZBj2974outYM";
@@ -618,14 +883,17 @@ var DEFAULT_BASE_URL = "https://clawdvault.com/api";
618
883
  // Annotate the CommonJS export names for ESM import in node:
619
884
  0 && (module.exports = {
620
885
  ClawdVaultClient,
886
+ ClawdVaultStreaming,
621
887
  DEFAULT_BASE_URL,
622
888
  Keypair,
623
889
  KeypairSigner,
624
890
  PROGRAM_ID,
625
891
  PhantomSigner,
626
892
  PublicKey,
893
+ StreamConnection,
627
894
  createAuthSignature,
628
895
  createClient,
896
+ createStreaming,
629
897
  signAndSerialize,
630
898
  verifySignature
631
899
  });
package/dist/index.mjs CHANGED
@@ -577,20 +577,285 @@ function createClient(config) {
577
577
  return new ClawdVaultClient(config);
578
578
  }
579
579
 
580
+ // src/streaming.ts
581
+ var getEventSource = () => {
582
+ if (typeof EventSource !== "undefined") {
583
+ return EventSource;
584
+ }
585
+ return __require("eventsource");
586
+ };
587
+ var StreamConnection = class {
588
+ constructor(url, options = {}) {
589
+ this.eventSource = null;
590
+ this.reconnectAttempts = 0;
591
+ this.reconnectTimeout = null;
592
+ this.listeners = /* @__PURE__ */ new Map();
593
+ this.onConnectCallbacks = /* @__PURE__ */ new Set();
594
+ this.onDisconnectCallbacks = /* @__PURE__ */ new Set();
595
+ this.onErrorCallbacks = /* @__PURE__ */ new Set();
596
+ this.isConnected = false;
597
+ this.isManuallyDisconnected = false;
598
+ this.url = url;
599
+ this.options = {
600
+ autoReconnect: options.autoReconnect ?? true,
601
+ reconnectDelay: options.reconnectDelay ?? 3e3,
602
+ maxReconnectAttempts: options.maxReconnectAttempts ?? 10
603
+ };
604
+ }
605
+ /**
606
+ * Connect to the stream
607
+ */
608
+ connect() {
609
+ if (this.eventSource) {
610
+ return;
611
+ }
612
+ this.isManuallyDisconnected = false;
613
+ const EventSourceImpl = getEventSource();
614
+ this.eventSource = new EventSourceImpl(this.url);
615
+ this.eventSource.onopen = () => {
616
+ this.isConnected = true;
617
+ this.reconnectAttempts = 0;
618
+ this.onConnectCallbacks.forEach((cb) => cb());
619
+ };
620
+ this.eventSource.onerror = (event) => {
621
+ const wasConnected = this.isConnected;
622
+ this.isConnected = false;
623
+ if (wasConnected) {
624
+ this.onDisconnectCallbacks.forEach((cb) => cb());
625
+ }
626
+ this.onErrorCallbacks.forEach((cb) => cb(new Error("Stream connection error")));
627
+ if (this.options.autoReconnect && !this.isManuallyDisconnected) {
628
+ this.scheduleReconnect();
629
+ }
630
+ };
631
+ this.eventSource.onmessage = (event) => {
632
+ this.handleEvent("message", event.data);
633
+ };
634
+ for (const eventType of this.listeners.keys()) {
635
+ this.eventSource.addEventListener(eventType, (event) => {
636
+ this.handleEvent(eventType, event.data);
637
+ });
638
+ }
639
+ }
640
+ handleEvent(eventType, data) {
641
+ const callbacks = this.listeners.get(eventType);
642
+ if (!callbacks) return;
643
+ try {
644
+ const parsed = JSON.parse(data);
645
+ callbacks.forEach((cb) => cb(parsed));
646
+ } catch {
647
+ }
648
+ }
649
+ scheduleReconnect() {
650
+ if (this.reconnectTimeout) {
651
+ clearTimeout(this.reconnectTimeout);
652
+ }
653
+ if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
654
+ this.onErrorCallbacks.forEach(
655
+ (cb) => cb(new Error(`Max reconnect attempts (${this.options.maxReconnectAttempts}) reached`))
656
+ );
657
+ return;
658
+ }
659
+ this.reconnectAttempts++;
660
+ const delay = this.options.reconnectDelay * Math.pow(1.5, this.reconnectAttempts - 1);
661
+ this.reconnectTimeout = setTimeout(() => {
662
+ this.eventSource?.close();
663
+ this.eventSource = null;
664
+ this.connect();
665
+ }, delay);
666
+ }
667
+ /**
668
+ * Disconnect from the stream
669
+ */
670
+ disconnect() {
671
+ this.isManuallyDisconnected = true;
672
+ if (this.reconnectTimeout) {
673
+ clearTimeout(this.reconnectTimeout);
674
+ this.reconnectTimeout = null;
675
+ }
676
+ if (this.eventSource) {
677
+ this.eventSource.close();
678
+ this.eventSource = null;
679
+ }
680
+ if (this.isConnected) {
681
+ this.isConnected = false;
682
+ this.onDisconnectCallbacks.forEach((cb) => cb());
683
+ }
684
+ }
685
+ /**
686
+ * Subscribe to an event type
687
+ */
688
+ on(eventType, callback) {
689
+ if (!this.listeners.has(eventType)) {
690
+ this.listeners.set(eventType, /* @__PURE__ */ new Set());
691
+ if (this.eventSource) {
692
+ this.eventSource.addEventListener(eventType, (event) => {
693
+ this.handleEvent(eventType, event.data);
694
+ });
695
+ }
696
+ }
697
+ this.listeners.get(eventType).add(callback);
698
+ return () => {
699
+ const callbacks = this.listeners.get(eventType);
700
+ if (callbacks) {
701
+ callbacks.delete(callback);
702
+ }
703
+ };
704
+ }
705
+ /**
706
+ * One-time event listener
707
+ */
708
+ once(eventType, callback) {
709
+ const unsubscribe = this.on(eventType, (data) => {
710
+ unsubscribe();
711
+ callback(data);
712
+ });
713
+ }
714
+ /**
715
+ * Register connection callback
716
+ */
717
+ onConnect(callback) {
718
+ this.onConnectCallbacks.add(callback);
719
+ return () => this.onConnectCallbacks.delete(callback);
720
+ }
721
+ /**
722
+ * Register disconnection callback
723
+ */
724
+ onDisconnect(callback) {
725
+ this.onDisconnectCallbacks.add(callback);
726
+ return () => this.onDisconnectCallbacks.delete(callback);
727
+ }
728
+ /**
729
+ * Register error callback
730
+ */
731
+ onError(callback) {
732
+ this.onErrorCallbacks.add(callback);
733
+ return () => this.onErrorCallbacks.delete(callback);
734
+ }
735
+ /**
736
+ * Check if connected
737
+ */
738
+ get connected() {
739
+ return this.isConnected;
740
+ }
741
+ };
742
+ var ClawdVaultStreaming = class {
743
+ constructor(baseUrl = "https://clawdvault.com/api", options = {}) {
744
+ this.connections = /* @__PURE__ */ new Map();
745
+ this.baseUrl = baseUrl.replace(/\/$/, "");
746
+ this.options = options;
747
+ }
748
+ /**
749
+ * Stream trades for a token
750
+ */
751
+ streamTrades(mint) {
752
+ const key = `trades:${mint}`;
753
+ if (!this.connections.has(key)) {
754
+ const conn = new StreamConnection(
755
+ `${this.baseUrl}/stream/trades?mint=${mint}`,
756
+ this.options
757
+ );
758
+ this.connections.set(key, conn);
759
+ }
760
+ return this.connections.get(key);
761
+ }
762
+ /**
763
+ * Stream token updates (price, market cap)
764
+ */
765
+ streamToken(mint) {
766
+ const key = `token:${mint}`;
767
+ if (!this.connections.has(key)) {
768
+ const conn = new StreamConnection(
769
+ `${this.baseUrl}/stream/token?mint=${mint}`,
770
+ this.options
771
+ );
772
+ this.connections.set(key, conn);
773
+ }
774
+ return this.connections.get(key);
775
+ }
776
+ /**
777
+ * Stream chat messages
778
+ */
779
+ streamChat(mint) {
780
+ const key = `chat:${mint}`;
781
+ if (!this.connections.has(key)) {
782
+ const conn = new StreamConnection(
783
+ `${this.baseUrl}/stream/chat?mint=${mint}`,
784
+ this.options
785
+ );
786
+ this.connections.set(key, conn);
787
+ }
788
+ return this.connections.get(key);
789
+ }
790
+ /**
791
+ * Convenience: Subscribe to trades with callback
792
+ */
793
+ onTrades(mint, callback) {
794
+ const conn = this.streamTrades(mint);
795
+ const unsubscribe = conn.on("trade", callback);
796
+ conn.connect();
797
+ return { unsubscribe, connection: conn };
798
+ }
799
+ /**
800
+ * Convenience: Subscribe to token price updates
801
+ */
802
+ onPrice(mint, callback) {
803
+ const conn = this.streamToken(mint);
804
+ const unsubscribe = conn.on("update", callback);
805
+ conn.connect();
806
+ return { unsubscribe, connection: conn };
807
+ }
808
+ /**
809
+ * Convenience: Subscribe to chat messages
810
+ */
811
+ onChat(mint, callback) {
812
+ const conn = this.streamChat(mint);
813
+ const unsubscribe = conn.on("message", callback);
814
+ conn.connect();
815
+ return { unsubscribe, connection: conn };
816
+ }
817
+ /**
818
+ * Disconnect all streams
819
+ */
820
+ disconnectAll() {
821
+ for (const conn of this.connections.values()) {
822
+ conn.disconnect();
823
+ }
824
+ this.connections.clear();
825
+ }
826
+ /**
827
+ * Disconnect a specific stream
828
+ */
829
+ disconnect(type, mint) {
830
+ const key = `${type}:${mint}`;
831
+ const conn = this.connections.get(key);
832
+ if (conn) {
833
+ conn.disconnect();
834
+ this.connections.delete(key);
835
+ }
836
+ }
837
+ };
838
+ function createStreaming(baseUrl, options) {
839
+ return new ClawdVaultStreaming(baseUrl, options);
840
+ }
841
+
580
842
  // src/index.ts
581
843
  import { PublicKey as PublicKey2, Keypair as Keypair2 } from "@solana/web3.js";
582
844
  var PROGRAM_ID = "GUyF2TVe32Cid4iGVt2F6wPYDhLSVmTUZBj2974outYM";
583
845
  var DEFAULT_BASE_URL = "https://clawdvault.com/api";
584
846
  export {
585
847
  ClawdVaultClient,
848
+ ClawdVaultStreaming,
586
849
  DEFAULT_BASE_URL,
587
850
  Keypair2 as Keypair,
588
851
  KeypairSigner,
589
852
  PROGRAM_ID,
590
853
  PhantomSigner,
591
854
  PublicKey2 as PublicKey,
855
+ StreamConnection,
592
856
  createAuthSignature,
593
857
  createClient,
858
+ createStreaming,
594
859
  signAndSerialize,
595
860
  verifySignature
596
861
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawdvault/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "TypeScript SDK for ClawdVault - Solana token launchpad",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -25,7 +25,8 @@
25
25
  "@solana/web3.js": "^1.91.0",
26
26
  "@solana/spl-token": "^0.4.0",
27
27
  "bs58": "^5.0.0",
28
- "tweetnacl": "^1.0.3"
28
+ "tweetnacl": "^1.0.3",
29
+ "eventsource": "^2.0.2"
29
30
  },
30
31
  "devDependencies": {
31
32
  "tsup": "^8.0.1",