sol-trade-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +390 -0
  2. package/dist/chunk-MMQAMIKR.mjs +3735 -0
  3. package/dist/chunk-NEZDFAYA.mjs +7744 -0
  4. package/dist/clients-VITWK7B6.mjs +1370 -0
  5. package/dist/index-1BK_FXsW.d.mts +2327 -0
  6. package/dist/index-1BK_FXsW.d.ts +2327 -0
  7. package/dist/index.d.mts +2659 -0
  8. package/dist/index.d.ts +2659 -0
  9. package/dist/index.js +13265 -0
  10. package/dist/index.mjs +562 -0
  11. package/dist/perf/index.d.mts +2 -0
  12. package/dist/perf/index.d.ts +2 -0
  13. package/dist/perf/index.js +3742 -0
  14. package/dist/perf/index.mjs +214 -0
  15. package/package.json +101 -0
  16. package/src/__tests__/complete_sdk.test.ts +354 -0
  17. package/src/__tests__/hotpath.test.ts +486 -0
  18. package/src/__tests__/nonce.test.ts +45 -0
  19. package/src/__tests__/sdk.test.ts +425 -0
  20. package/src/address-lookup/index.ts +197 -0
  21. package/src/cache/cache.ts +308 -0
  22. package/src/calc/index.ts +1058 -0
  23. package/src/calc/pumpfun.ts +124 -0
  24. package/src/common/bonding_curve.ts +272 -0
  25. package/src/common/compute-budget.ts +148 -0
  26. package/src/common/confirm-any-signature.ts +184 -0
  27. package/src/common/fast-timing.ts +481 -0
  28. package/src/common/fast_fn.ts +150 -0
  29. package/src/common/gas-fee-strategy.ts +253 -0
  30. package/src/common/map-pool.ts +23 -0
  31. package/src/common/nonce.ts +40 -0
  32. package/src/common/sdk-log.ts +460 -0
  33. package/src/common/seed.ts +381 -0
  34. package/src/common/spl-token.ts +578 -0
  35. package/src/common/subscription-handle.ts +644 -0
  36. package/src/common/trading-utils.ts +239 -0
  37. package/src/common/wsol-manager.ts +325 -0
  38. package/src/compute/compute_budget_manager.ts +187 -0
  39. package/src/compute/index.ts +21 -0
  40. package/src/constants/index.ts +96 -0
  41. package/src/execution/execution.ts +532 -0
  42. package/src/execution/index.ts +42 -0
  43. package/src/hotpath/executor.ts +464 -0
  44. package/src/hotpath/index.ts +64 -0
  45. package/src/hotpath/state.ts +435 -0
  46. package/src/index.ts +2117 -0
  47. package/src/instruction/bonk_builder.ts +730 -0
  48. package/src/instruction/index.ts +24 -0
  49. package/src/instruction/meteora_damm_v2_builder.ts +509 -0
  50. package/src/instruction/pumpfun_builder.ts +1183 -0
  51. package/src/instruction/pumpswap.ts +1123 -0
  52. package/src/instruction/raydium_amm_v4_builder.ts +692 -0
  53. package/src/instruction/raydium_cpmm_builder.ts +795 -0
  54. package/src/middleware/traits.ts +407 -0
  55. package/src/params/index.ts +483 -0
  56. package/src/perf/compiler-optimization.ts +529 -0
  57. package/src/perf/hardware.ts +631 -0
  58. package/src/perf/index.ts +9 -0
  59. package/src/perf/kernel-bypass.ts +656 -0
  60. package/src/perf/protocol.ts +682 -0
  61. package/src/perf/realtime.ts +592 -0
  62. package/src/perf/simd.ts +668 -0
  63. package/src/perf/syscall-bypass.ts +331 -0
  64. package/src/perf/ultra-low-latency.ts +505 -0
  65. package/src/perf/zero-copy.ts +589 -0
  66. package/src/pool/pool.ts +294 -0
  67. package/src/rpc/client.ts +345 -0
  68. package/src/sdk-errors.ts +13 -0
  69. package/src/security/index.ts +26 -0
  70. package/src/security/secure-key.ts +303 -0
  71. package/src/security/validators.ts +281 -0
  72. package/src/seed/pda.ts +262 -0
  73. package/src/serialization/index.ts +28 -0
  74. package/src/serialization/serialization.ts +288 -0
  75. package/src/swqos/clients.ts +1754 -0
  76. package/src/swqos/index.ts +50 -0
  77. package/src/swqos/providers.ts +1707 -0
  78. package/src/trading/core/async-executor.ts +702 -0
  79. package/src/trading/core/confirmation-monitor.ts +711 -0
  80. package/src/trading/core/index.ts +82 -0
  81. package/src/trading/core/retry-handler.ts +683 -0
  82. package/src/trading/core/transaction-pool.ts +780 -0
  83. package/src/trading/executor.ts +385 -0
  84. package/src/trading/factory.ts +282 -0
  85. package/src/trading/index.ts +30 -0
  86. package/src/types.ts +8 -0
  87. package/src/utils/index.ts +155 -0
@@ -0,0 +1,644 @@
1
+ /**
2
+ * Subscription handle utilities for Sol Trade SDK
3
+ * Provides subscription management for accounts, programs, and signatures.
4
+ */
5
+
6
+ import { PublicKey, Connection, Commitment } from '@solana/web3.js';
7
+ import type { GetProgramAccountsFilter } from '@solana/web3.js';
8
+
9
+ // ===== Subscription State =====
10
+
11
+ /**
12
+ * Subscription state enum
13
+ */
14
+ export enum SubscriptionState {
15
+ Pending = 'pending',
16
+ Active = 'active',
17
+ Paused = 'paused',
18
+ Error = 'error',
19
+ Closed = 'closed',
20
+ }
21
+
22
+ // ===== Subscription Configuration =====
23
+
24
+ /**
25
+ * Base subscription configuration
26
+ */
27
+ export interface SubscriptionConfig {
28
+ commitment?: Commitment;
29
+ encoding?: 'base58' | 'base64' | 'base64+zstd' | 'jsonParsed';
30
+ }
31
+
32
+ /**
33
+ * Account subscription configuration
34
+ */
35
+ export interface AccountSubscriptionConfig extends SubscriptionConfig {
36
+ publicKey: PublicKey;
37
+ }
38
+
39
+ /**
40
+ * Program subscription configuration
41
+ */
42
+ export interface ProgramSubscriptionConfig extends SubscriptionConfig {
43
+ programId: PublicKey;
44
+ filters?: ProgramAccountFilter[];
45
+ }
46
+
47
+ /**
48
+ * Program account filter
49
+ */
50
+ export interface ProgramAccountFilter {
51
+ memcmp?: {
52
+ offset: number;
53
+ bytes: string;
54
+ };
55
+ dataSize?: number;
56
+ }
57
+
58
+ /**
59
+ * Signature subscription configuration
60
+ */
61
+ export interface SignatureSubscriptionConfig extends SubscriptionConfig {
62
+ signature: string;
63
+ }
64
+
65
+ // ===== Subscription Handle =====
66
+
67
+ /**
68
+ * Subscription handle for managing a single subscription
69
+ */
70
+ export class SubscriptionHandle {
71
+ private state: SubscriptionState = SubscriptionState.Pending;
72
+ private subscriptionId?: number;
73
+ private error?: Error;
74
+ private lastUpdate?: Date;
75
+ private updateCount: number = 0;
76
+
77
+ private _unsubscribeFn?: () => Promise<void>;
78
+
79
+ constructor(
80
+ private type: 'account' | 'program' | 'signature',
81
+ private config: AccountSubscriptionConfig | ProgramSubscriptionConfig | SignatureSubscriptionConfig,
82
+ unsubscribeFn?: () => Promise<void>
83
+ ) {
84
+ this._unsubscribeFn = unsubscribeFn;
85
+ }
86
+
87
+ /**
88
+ * Get subscription type
89
+ */
90
+ getType(): 'account' | 'program' | 'signature' {
91
+ return this.type;
92
+ }
93
+
94
+ /**
95
+ * Get subscription configuration
96
+ */
97
+ getConfig(): AccountSubscriptionConfig | ProgramSubscriptionConfig | SignatureSubscriptionConfig {
98
+ return this.config;
99
+ }
100
+
101
+ /**
102
+ * Get current subscription state
103
+ */
104
+ getState(): SubscriptionState {
105
+ return this.state;
106
+ }
107
+
108
+ /**
109
+ * Set subscription state
110
+ */
111
+ setState(state: SubscriptionState): void {
112
+ this.state = state;
113
+ }
114
+
115
+ /**
116
+ * Get subscription ID from connection
117
+ */
118
+ getSubscriptionId(): number | undefined {
119
+ return this.subscriptionId;
120
+ }
121
+
122
+ /**
123
+ * Set subscription ID
124
+ */
125
+ setSubscriptionId(id: number): void {
126
+ this.subscriptionId = id;
127
+ }
128
+
129
+ /**
130
+ * Get last error
131
+ */
132
+ getError(): Error | undefined {
133
+ return this.error;
134
+ }
135
+
136
+ /**
137
+ * Set error state
138
+ */
139
+ setError(error: Error): void {
140
+ this.error = error;
141
+ this.state = SubscriptionState.Error;
142
+ }
143
+
144
+ /**
145
+ * Record an update
146
+ */
147
+ recordUpdate(): void {
148
+ this.lastUpdate = new Date();
149
+ this.updateCount++;
150
+ }
151
+
152
+ /**
153
+ * Get last update timestamp
154
+ */
155
+ getLastUpdate(): Date | undefined {
156
+ return this.lastUpdate;
157
+ }
158
+
159
+ /**
160
+ * Get total update count
161
+ */
162
+ getUpdateCount(): number {
163
+ return this.updateCount;
164
+ }
165
+
166
+ /**
167
+ * Check if subscription is active
168
+ */
169
+ isActive(): boolean {
170
+ return this.state === SubscriptionState.Active;
171
+ }
172
+
173
+ /**
174
+ * Check if subscription is closed
175
+ */
176
+ isClosed(): boolean {
177
+ return this.state === SubscriptionState.Closed;
178
+ }
179
+
180
+ /**
181
+ * Set the unsubscribe function
182
+ */
183
+ setUnsubscribeFn(fn: () => Promise<void>): void {
184
+ this._unsubscribeFn = fn;
185
+ }
186
+
187
+ /**
188
+ * Unsubscribe from this subscription
189
+ */
190
+ async unsubscribe(): Promise<void> {
191
+ if (this.state === SubscriptionState.Closed) {
192
+ return;
193
+ }
194
+
195
+ try {
196
+ if (this._unsubscribeFn) {
197
+ await this._unsubscribeFn();
198
+ }
199
+ this.state = SubscriptionState.Closed;
200
+ } catch (error) {
201
+ this.setError(error as Error);
202
+ throw error;
203
+ }
204
+ }
205
+ }
206
+
207
+ // ===== Subscription Manager =====
208
+
209
+ /**
210
+ * Subscription manager for handling multiple subscriptions
211
+ */
212
+ export class SubscriptionManager {
213
+ private subscriptions: Map<string, SubscriptionHandle> = new Map();
214
+ private connection: Connection;
215
+
216
+ constructor(connection: Connection) {
217
+ this.connection = connection;
218
+ }
219
+
220
+ /**
221
+ * Generate a unique subscription key
222
+ */
223
+ private generateKey(type: string, identifier: string): string {
224
+ return `${type}:${identifier}`;
225
+ }
226
+
227
+ /**
228
+ * Subscribe to account changes
229
+ */
230
+ async subscribeAccount(
231
+ config: AccountSubscriptionConfig,
232
+ callback: (accountInfo: any, context: any) => void
233
+ ): Promise<SubscriptionHandle> {
234
+ const key = this.generateKey('account', config.publicKey.toBase58());
235
+
236
+ // Unsubscribe existing if any
237
+ if (this.subscriptions.has(key)) {
238
+ await this.subscriptions.get(key)!.unsubscribe();
239
+ }
240
+
241
+ const handle = new SubscriptionHandle('account', config);
242
+ handle.setState(SubscriptionState.Active);
243
+
244
+ const subscriptionId = this.connection.onAccountChange(
245
+ config.publicKey,
246
+ (accountInfo, context) => {
247
+ handle.recordUpdate();
248
+ callback(accountInfo, context);
249
+ },
250
+ config.commitment ?? 'confirmed'
251
+ );
252
+
253
+ handle.setSubscriptionId(subscriptionId);
254
+ handle.setUnsubscribeFn(async () => {
255
+ await this.connection.removeAccountChangeListener(subscriptionId);
256
+ });
257
+
258
+ this.subscriptions.set(key, handle);
259
+ return handle;
260
+ }
261
+
262
+ /**
263
+ * Subscribe to program account changes
264
+ */
265
+ async subscribeProgram(
266
+ config: ProgramSubscriptionConfig,
267
+ callback: (keyedAccountInfo: any, context: any) => void
268
+ ): Promise<SubscriptionHandle> {
269
+ const key = this.generateKey('program', config.programId.toBase58());
270
+
271
+ // Unsubscribe existing if any
272
+ if (this.subscriptions.has(key)) {
273
+ await this.subscriptions.get(key)!.unsubscribe();
274
+ }
275
+
276
+ const handle = new SubscriptionHandle('program', config);
277
+ handle.setState(SubscriptionState.Active);
278
+
279
+ const filters: GetProgramAccountsFilter[] | undefined = config.filters
280
+ ?.map((filter): GetProgramAccountsFilter | undefined => {
281
+ if (filter.memcmp) {
282
+ return { memcmp: filter.memcmp };
283
+ }
284
+ if (filter.dataSize !== undefined) {
285
+ return { dataSize: filter.dataSize };
286
+ }
287
+ return undefined;
288
+ })
289
+ .filter((filter): filter is GetProgramAccountsFilter => filter !== undefined);
290
+
291
+ const subscriptionId = this.connection.onProgramAccountChange(
292
+ config.programId,
293
+ (keyedAccountInfo, context) => {
294
+ handle.recordUpdate();
295
+ callback(keyedAccountInfo, context);
296
+ },
297
+ config.commitment ?? 'confirmed',
298
+ filters
299
+ );
300
+
301
+ handle.setSubscriptionId(subscriptionId);
302
+ handle.setUnsubscribeFn(async () => {
303
+ await this.connection.removeProgramAccountChangeListener(subscriptionId);
304
+ });
305
+
306
+ this.subscriptions.set(key, handle);
307
+ return handle;
308
+ }
309
+
310
+ /**
311
+ * Subscribe to signature status changes
312
+ */
313
+ async subscribeSignature(
314
+ config: SignatureSubscriptionConfig,
315
+ callback: (signatureResult: any, context: any) => void
316
+ ): Promise<SubscriptionHandle> {
317
+ const key = this.generateKey('signature', config.signature);
318
+
319
+ // Unsubscribe existing if any
320
+ if (this.subscriptions.has(key)) {
321
+ await this.subscriptions.get(key)!.unsubscribe();
322
+ }
323
+
324
+ const handle = new SubscriptionHandle('signature', config);
325
+ handle.setState(SubscriptionState.Active);
326
+
327
+ const subscriptionId = this.connection.onSignature(
328
+ config.signature,
329
+ (signatureResult, context) => {
330
+ handle.recordUpdate();
331
+ callback(signatureResult, context);
332
+ },
333
+ config.commitment ?? 'confirmed'
334
+ );
335
+
336
+ handle.setSubscriptionId(subscriptionId);
337
+ handle.setUnsubscribeFn(async () => {
338
+ await this.connection.removeSignatureListener(subscriptionId);
339
+ });
340
+
341
+ this.subscriptions.set(key, handle);
342
+ return handle;
343
+ }
344
+
345
+ /**
346
+ * Subscribe to slot changes
347
+ */
348
+ async subscribeSlot(callback: (slotInfo: any) => void): Promise<SubscriptionHandle> {
349
+ const key = this.generateKey('slot', 'global');
350
+
351
+ // Unsubscribe existing if any
352
+ if (this.subscriptions.has(key)) {
353
+ await this.subscriptions.get(key)!.unsubscribe();
354
+ }
355
+
356
+ const config: SubscriptionConfig = {};
357
+ const handle = new SubscriptionHandle('slot' as any, config as any);
358
+ handle.setState(SubscriptionState.Active);
359
+
360
+ const subscriptionId = this.connection.onSlotChange((slotInfo) => {
361
+ handle.recordUpdate();
362
+ callback(slotInfo);
363
+ });
364
+
365
+ handle.setSubscriptionId(subscriptionId);
366
+ handle.setUnsubscribeFn(async () => {
367
+ await this.connection.removeSlotChangeListener(subscriptionId);
368
+ });
369
+
370
+ this.subscriptions.set(key, handle);
371
+ return handle;
372
+ }
373
+
374
+ /**
375
+ * Subscribe to root changes
376
+ */
377
+ async subscribeRoot(callback: (root: number) => void): Promise<SubscriptionHandle> {
378
+ const key = this.generateKey('root', 'global');
379
+
380
+ // Unsubscribe existing if any
381
+ if (this.subscriptions.has(key)) {
382
+ await this.subscriptions.get(key)!.unsubscribe();
383
+ }
384
+
385
+ const config: SubscriptionConfig = {};
386
+ const handle = new SubscriptionHandle('signature', config as SignatureSubscriptionConfig);
387
+ handle.setState(SubscriptionState.Active);
388
+
389
+ const subscriptionId = this.connection.onRootChange((root) => {
390
+ handle.recordUpdate();
391
+ callback(root);
392
+ });
393
+
394
+ handle.setSubscriptionId(subscriptionId);
395
+ handle.setUnsubscribeFn(async () => {
396
+ await this.connection.removeRootChangeListener(subscriptionId);
397
+ });
398
+
399
+ this.subscriptions.set(key, handle);
400
+ return handle;
401
+ }
402
+
403
+ /**
404
+ * Get a subscription by key
405
+ */
406
+ getSubscription(key: string): SubscriptionHandle | undefined {
407
+ return this.subscriptions.get(key);
408
+ }
409
+
410
+ /**
411
+ * Get all subscriptions
412
+ */
413
+ getAllSubscriptions(): SubscriptionHandle[] {
414
+ return Array.from(this.subscriptions.values());
415
+ }
416
+
417
+ /**
418
+ * Get subscriptions by type
419
+ */
420
+ getSubscriptionsByType(type: 'account' | 'program' | 'signature'): SubscriptionHandle[] {
421
+ return this.getAllSubscriptions().filter((sub) => sub.getType() === type);
422
+ }
423
+
424
+ /**
425
+ * Unsubscribe from a specific subscription
426
+ */
427
+ async unsubscribe(key: string): Promise<void> {
428
+ const handle = this.subscriptions.get(key);
429
+ if (handle) {
430
+ await handle.unsubscribe();
431
+ this.subscriptions.delete(key);
432
+ }
433
+ }
434
+
435
+ /**
436
+ * Unsubscribe from all subscriptions
437
+ */
438
+ async unsubscribeAll(): Promise<void> {
439
+ const promises: Promise<void>[] = [];
440
+ for (const [key, handle] of this.subscriptions) {
441
+ promises.push(
442
+ handle.unsubscribe().then(() => {
443
+ this.subscriptions.delete(key);
444
+ })
445
+ );
446
+ }
447
+ await Promise.all(promises);
448
+ }
449
+
450
+ /**
451
+ * Get subscription statistics
452
+ */
453
+ getStats(): {
454
+ total: number;
455
+ active: number;
456
+ pending: number;
457
+ paused: number;
458
+ error: number;
459
+ closed: number;
460
+ totalUpdates: number;
461
+ } {
462
+ const subs = this.getAllSubscriptions();
463
+ return {
464
+ total: subs.length,
465
+ active: subs.filter((s) => s.getState() === SubscriptionState.Active).length,
466
+ pending: subs.filter((s) => s.getState() === SubscriptionState.Pending).length,
467
+ paused: subs.filter((s) => s.getState() === SubscriptionState.Paused).length,
468
+ error: subs.filter((s) => s.getState() === SubscriptionState.Error).length,
469
+ closed: subs.filter((s) => s.getState() === SubscriptionState.Closed).length,
470
+ totalUpdates: subs.reduce((sum, s) => sum + s.getUpdateCount(), 0),
471
+ };
472
+ }
473
+ }
474
+
475
+ // ===== Convenience Classes =====
476
+
477
+ /**
478
+ * Account subscription helper
479
+ */
480
+ export class AccountSubscription {
481
+ private handle?: SubscriptionHandle;
482
+
483
+ constructor(
484
+ private manager: SubscriptionManager,
485
+ private publicKey: PublicKey
486
+ ) {}
487
+
488
+ /**
489
+ * Subscribe to account changes
490
+ */
491
+ async subscribe(
492
+ callback: (accountInfo: any, context: any) => void,
493
+ commitment?: Commitment
494
+ ): Promise<SubscriptionHandle> {
495
+ this.handle = await this.manager.subscribeAccount(
496
+ { publicKey: this.publicKey, commitment },
497
+ callback
498
+ );
499
+ return this.handle;
500
+ }
501
+
502
+ /**
503
+ * Unsubscribe from account changes
504
+ */
505
+ async unsubscribe(): Promise<void> {
506
+ if (this.handle) {
507
+ await this.handle.unsubscribe();
508
+ this.handle = undefined;
509
+ }
510
+ }
511
+
512
+ /**
513
+ * Check if subscribed
514
+ */
515
+ isSubscribed(): boolean {
516
+ return this.handle?.isActive() ?? false;
517
+ }
518
+ }
519
+
520
+ /**
521
+ * Program subscription helper
522
+ */
523
+ export class ProgramSubscription {
524
+ private handle?: SubscriptionHandle;
525
+
526
+ constructor(
527
+ private manager: SubscriptionManager,
528
+ private programId: PublicKey
529
+ ) {}
530
+
531
+ /**
532
+ * Subscribe to program account changes
533
+ */
534
+ async subscribe(
535
+ callback: (keyedAccountInfo: any, context: any) => void,
536
+ filters?: ProgramAccountFilter[],
537
+ commitment?: Commitment
538
+ ): Promise<SubscriptionHandle> {
539
+ this.handle = await this.manager.subscribeProgram(
540
+ { programId: this.programId, filters, commitment },
541
+ callback
542
+ );
543
+ return this.handle;
544
+ }
545
+
546
+ /**
547
+ * Unsubscribe from program changes
548
+ */
549
+ async unsubscribe(): Promise<void> {
550
+ if (this.handle) {
551
+ await this.handle.unsubscribe();
552
+ this.handle = undefined;
553
+ }
554
+ }
555
+
556
+ /**
557
+ * Check if subscribed
558
+ */
559
+ isSubscribed(): boolean {
560
+ return this.handle?.isActive() ?? false;
561
+ }
562
+ }
563
+
564
+ /**
565
+ * Signature subscription helper
566
+ */
567
+ export class SignatureSubscription {
568
+ private handle?: SubscriptionHandle;
569
+
570
+ constructor(
571
+ private manager: SubscriptionManager,
572
+ private signature: string
573
+ ) {}
574
+
575
+ /**
576
+ * Subscribe to signature status changes
577
+ */
578
+ async subscribe(
579
+ callback: (signatureResult: any, context: any) => void,
580
+ commitment?: Commitment
581
+ ): Promise<SubscriptionHandle> {
582
+ this.handle = await this.manager.subscribeSignature(
583
+ { signature: this.signature, commitment },
584
+ callback
585
+ );
586
+ return this.handle;
587
+ }
588
+
589
+ /**
590
+ * Unsubscribe from signature changes
591
+ */
592
+ async unsubscribe(): Promise<void> {
593
+ if (this.handle) {
594
+ await this.handle.unsubscribe();
595
+ this.handle = undefined;
596
+ }
597
+ }
598
+
599
+ /**
600
+ * Check if subscribed
601
+ */
602
+ isSubscribed(): boolean {
603
+ return this.handle?.isActive() ?? false;
604
+ }
605
+ }
606
+
607
+ // ===== Factory Functions =====
608
+
609
+ /**
610
+ * Create a subscription manager
611
+ */
612
+ export function createSubscriptionManager(connection: Connection): SubscriptionManager {
613
+ return new SubscriptionManager(connection);
614
+ }
615
+
616
+ /**
617
+ * Create an account subscription
618
+ */
619
+ export function createAccountSubscription(
620
+ manager: SubscriptionManager,
621
+ publicKey: PublicKey
622
+ ): AccountSubscription {
623
+ return new AccountSubscription(manager, publicKey);
624
+ }
625
+
626
+ /**
627
+ * Create a program subscription
628
+ */
629
+ export function createProgramSubscription(
630
+ manager: SubscriptionManager,
631
+ programId: PublicKey
632
+ ): ProgramSubscription {
633
+ return new ProgramSubscription(manager, programId);
634
+ }
635
+
636
+ /**
637
+ * Create a signature subscription
638
+ */
639
+ export function createSignatureSubscription(
640
+ manager: SubscriptionManager,
641
+ signature: string
642
+ ): SignatureSubscription {
643
+ return new SignatureSubscription(manager, signature);
644
+ }