@oobe-protocol-labs/synapse-sap-sdk 0.6.0 → 0.6.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.
Files changed (70) hide show
  1. package/README.md +107 -3
  2. package/dist/cjs/events/geyser.js +295 -0
  3. package/dist/cjs/events/geyser.js.map +1 -0
  4. package/dist/cjs/index.js +14 -2
  5. package/dist/cjs/index.js.map +1 -1
  6. package/dist/cjs/modules/escrow.js +23 -8
  7. package/dist/cjs/modules/escrow.js.map +1 -1
  8. package/dist/cjs/plugin/index.js +18 -2
  9. package/dist/cjs/plugin/index.js.map +1 -1
  10. package/dist/cjs/plugin/schemas.js +32 -0
  11. package/dist/cjs/plugin/schemas.js.map +1 -1
  12. package/dist/cjs/postgres/sync.js +72 -4
  13. package/dist/cjs/postgres/sync.js.map +1 -1
  14. package/dist/cjs/registries/index.js.map +1 -1
  15. package/dist/cjs/registries/x402.js +51 -8
  16. package/dist/cjs/registries/x402.js.map +1 -1
  17. package/dist/cjs/utils/index.js +10 -1
  18. package/dist/cjs/utils/index.js.map +1 -1
  19. package/dist/cjs/utils/priority-fee.js +163 -0
  20. package/dist/cjs/utils/priority-fee.js.map +1 -0
  21. package/dist/esm/events/geyser.js +258 -0
  22. package/dist/esm/events/geyser.js.map +1 -0
  23. package/dist/esm/index.js +4 -0
  24. package/dist/esm/index.js.map +1 -1
  25. package/dist/esm/modules/escrow.js +23 -8
  26. package/dist/esm/modules/escrow.js.map +1 -1
  27. package/dist/esm/plugin/index.js +18 -2
  28. package/dist/esm/plugin/index.js.map +1 -1
  29. package/dist/esm/plugin/schemas.js +32 -0
  30. package/dist/esm/plugin/schemas.js.map +1 -1
  31. package/dist/esm/postgres/sync.js +72 -4
  32. package/dist/esm/postgres/sync.js.map +1 -1
  33. package/dist/esm/registries/index.js.map +1 -1
  34. package/dist/esm/registries/x402.js +51 -8
  35. package/dist/esm/registries/x402.js.map +1 -1
  36. package/dist/esm/utils/index.js +2 -0
  37. package/dist/esm/utils/index.js.map +1 -1
  38. package/dist/esm/utils/priority-fee.js +158 -0
  39. package/dist/esm/utils/priority-fee.js.map +1 -0
  40. package/dist/types/events/geyser.d.ts +150 -0
  41. package/dist/types/events/geyser.d.ts.map +1 -0
  42. package/dist/types/index.d.ts +5 -1
  43. package/dist/types/index.d.ts.map +1 -1
  44. package/dist/types/modules/escrow.d.ts +7 -2
  45. package/dist/types/modules/escrow.d.ts.map +1 -1
  46. package/dist/types/plugin/index.d.ts.map +1 -1
  47. package/dist/types/plugin/schemas.d.ts +6 -0
  48. package/dist/types/plugin/schemas.d.ts.map +1 -1
  49. package/dist/types/postgres/sync.d.ts +26 -2
  50. package/dist/types/postgres/sync.d.ts.map +1 -1
  51. package/dist/types/registries/index.d.ts +1 -1
  52. package/dist/types/registries/index.d.ts.map +1 -1
  53. package/dist/types/registries/x402.d.ts +34 -2
  54. package/dist/types/registries/x402.d.ts.map +1 -1
  55. package/dist/types/utils/index.d.ts +2 -0
  56. package/dist/types/utils/index.d.ts.map +1 -1
  57. package/dist/types/utils/priority-fee.d.ts +185 -0
  58. package/dist/types/utils/priority-fee.d.ts.map +1 -0
  59. package/package.json +5 -1
  60. package/src/events/geyser.ts +384 -0
  61. package/src/events/yellowstone.d.ts +7 -0
  62. package/src/index.ts +19 -0
  63. package/src/modules/escrow.ts +33 -6
  64. package/src/plugin/index.ts +20 -0
  65. package/src/plugin/schemas.ts +32 -0
  66. package/src/postgres/sync.ts +90 -4
  67. package/src/registries/index.ts +1 -0
  68. package/src/registries/x402.ts +63 -6
  69. package/src/utils/index.ts +15 -0
  70. package/src/utils/priority-fee.ts +270 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGnE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,gBAAgB,EAChB,0BAA0B,EAC1B,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACpB,OAAO,EACP,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EACL,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,EACvB,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,EACpB,eAAe,GAChB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGnE,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,GACf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,gBAAgB,EAChB,0BAA0B,EAC1B,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACpB,OAAO,EACP,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EACL,eAAe,EACf,8BAA8B,EAC9B,uBAAuB,EACvB,6BAA6B,EAC7B,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,EACpB,eAAe,GAChB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B,EAC5B,kCAAkC,GACnC,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,iBAAiB,EACjB,aAAa,GACd,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,185 @@
1
+ /**
2
+ * @module utils/priority-fee
3
+ * @description Compute budget and priority fee utilities for SAP transactions.
4
+ *
5
+ * Solana transactions that include a priority fee (via the Compute Budget program)
6
+ * land faster because validators prefer higher-fee transactions. This module
7
+ * provides a clean, composable API for building priority-fee instructions
8
+ * that can be prepended to any Anchor method builder via `.preInstructions()`.
9
+ *
10
+ * Typical use: x402 settlement transactions where the receiving agent's RPC
11
+ * has a short confirmation window (e.g., 30 seconds).
12
+ *
13
+ * @category Utils
14
+ * @since v0.6.2
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { buildPriorityFeeIxs, DEFAULT_SETTLE_PRIORITY } from "@synapse-sap/sdk";
19
+ *
20
+ * // Append to any Anchor method builder:
21
+ * await program.methods
22
+ * .settleCalls(calls, hash)
23
+ * .accounts({ ... })
24
+ * .preInstructions(buildPriorityFeeIxs({ priorityFeeMicroLamports: 5000 }))
25
+ * .rpc({ skipPreflight: true });
26
+ * ```
27
+ */
28
+ import { type TransactionInstruction } from "@solana/web3.js";
29
+ /**
30
+ * Default priority fee for settlement transactions (in microlamports).
31
+ * 5000 µL ≈ 0.0005 SOL per 200k CU — fast enough for most agent RPCs.
32
+ *
33
+ * @since v0.6.2
34
+ */
35
+ export declare const DEFAULT_SETTLE_PRIORITY_FEE = 5000;
36
+ /**
37
+ * Default compute unit limit for settlement transactions.
38
+ * `settle_calls` uses ~60k CU; 100k provides a safe margin.
39
+ *
40
+ * @since v0.6.2
41
+ */
42
+ export declare const DEFAULT_SETTLE_COMPUTE_UNITS = 100000;
43
+ /**
44
+ * Default compute unit limit for batch settlement transactions.
45
+ * `settle_batch` with 10 entries uses ~200k CU; 300k provides margin.
46
+ *
47
+ * @since v0.6.2
48
+ */
49
+ export declare const DEFAULT_BATCH_SETTLE_COMPUTE_UNITS = 300000;
50
+ /**
51
+ * @interface PriorityFeeConfig
52
+ * @description Configuration for building compute budget instructions.
53
+ * @category Utils
54
+ * @since v0.6.2
55
+ */
56
+ export interface PriorityFeeConfig {
57
+ /**
58
+ * Priority fee in microlamports per compute unit.
59
+ * Higher values = faster confirmation.
60
+ *
61
+ * Common values:
62
+ * - `1000` — low priority (~0.0001 SOL)
63
+ * - `5000` — medium priority (~0.0005 SOL) ← recommended for settle
64
+ * - `50000` — high priority (~0.005 SOL)
65
+ * - `0` — no priority fee (default Solana behavior)
66
+ *
67
+ * @default 0
68
+ */
69
+ readonly priorityFeeMicroLamports?: number;
70
+ /**
71
+ * Maximum compute units the transaction may consume.
72
+ * Setting an explicit limit avoids overpaying for unused CU.
73
+ *
74
+ * @default 200_000 (Solana default)
75
+ */
76
+ readonly computeUnits?: number;
77
+ }
78
+ /**
79
+ * @interface SettleOptions
80
+ * @description Options for x402 settlement transactions.
81
+ * Controls priority fees, compute budget, and RPC behavior
82
+ * to optimize confirmation speed for time-sensitive settlements.
83
+ *
84
+ * @category Registries
85
+ * @since v0.6.2
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * // Fast settlement with priority fee
90
+ * const receipt = await x402.settle(depositor, 1, "data", {
91
+ * priorityFeeMicroLamports: 5000,
92
+ * computeUnits: 100_000,
93
+ * skipPreflight: true,
94
+ * });
95
+ *
96
+ * // Use the convenience preset
97
+ * import { FAST_SETTLE_OPTIONS } from "@synapse-sap/sdk";
98
+ * const receipt = await x402.settle(depositor, 1, "data", FAST_SETTLE_OPTIONS);
99
+ * ```
100
+ */
101
+ export interface SettleOptions extends PriorityFeeConfig {
102
+ /**
103
+ * Skip Solana simulation before submitting.
104
+ * Saves ~400ms but loses pre-flight error detection.
105
+ *
106
+ * Recommended for settlements where the escrow state
107
+ * has already been pre-fetched and validated.
108
+ *
109
+ * @default false
110
+ */
111
+ readonly skipPreflight?: boolean;
112
+ /**
113
+ * Transaction commitment level override.
114
+ * Uses the provider's default when omitted.
115
+ *
116
+ * - `"processed"` — fastest, least reliable
117
+ * - `"confirmed"` — balanced (recommended)
118
+ * - `"finalized"` — slowest, most reliable
119
+ */
120
+ readonly commitment?: "processed" | "confirmed" | "finalized";
121
+ /**
122
+ * Maximum number of RPC retry attempts.
123
+ * @default provider default (usually 3)
124
+ */
125
+ readonly maxRetries?: number;
126
+ }
127
+ /**
128
+ * Recommended preset for fast x402 settlements.
129
+ * Priority fee 5000 µL, 100k CU, skip preflight, confirmed commitment.
130
+ *
131
+ * @since v0.6.2
132
+ */
133
+ export declare const FAST_SETTLE_OPTIONS: Readonly<SettleOptions>;
134
+ /**
135
+ * Recommended preset for fast batch settlements.
136
+ * Priority fee 5000 µL, 300k CU, skip preflight, confirmed commitment.
137
+ *
138
+ * @since v0.6.2
139
+ */
140
+ export declare const FAST_BATCH_SETTLE_OPTIONS: Readonly<SettleOptions>;
141
+ /**
142
+ * @name buildPriorityFeeIxs
143
+ * @description Build compute budget instructions for priority fee transactions.
144
+ *
145
+ * Returns an array of 0–2 `TransactionInstruction`s:
146
+ * - `SetComputeUnitPrice` (if `priorityFeeMicroLamports > 0`)
147
+ * - `SetComputeUnitLimit` (if `computeUnits` provided)
148
+ *
149
+ * The returned array is designed to be passed directly to
150
+ * Anchor's `.preInstructions()` builder method.
151
+ *
152
+ * @param config - Priority fee configuration.
153
+ * @returns Array of compute budget instructions (may be empty).
154
+ *
155
+ * @category Utils
156
+ * @since v0.6.2
157
+ *
158
+ * @example
159
+ * ```ts
160
+ * const ixs = buildPriorityFeeIxs({
161
+ * priorityFeeMicroLamports: 5000,
162
+ * computeUnits: 100_000,
163
+ * });
164
+ *
165
+ * await program.methods
166
+ * .settleCalls(calls, hash)
167
+ * .accounts({ ... })
168
+ * .preInstructions(ixs)
169
+ * .rpc({ skipPreflight: true });
170
+ * ```
171
+ */
172
+ export declare function buildPriorityFeeIxs(config?: PriorityFeeConfig): TransactionInstruction[];
173
+ /**
174
+ * @name buildRpcOptions
175
+ * @description Build Anchor `.rpc()` options from {@link SettleOptions}.
176
+ *
177
+ * @param opts - Settle options.
178
+ * @returns Options object suitable for Anchor `.rpc(opts)`.
179
+ *
180
+ * @category Utils
181
+ * @since v0.6.2
182
+ * @internal
183
+ */
184
+ export declare function buildRpcOptions(opts?: SettleOptions): Record<string, unknown> | undefined;
185
+ //# sourceMappingURL=priority-fee.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority-fee.d.ts","sourceRoot":"","sources":["../../../src/utils/priority-fee.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AAMzB;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAC;AAEjD;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,SAAU,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,SAAU,CAAC;AAM1D;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAE3C;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD;;;;;;;;OAQG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;IAE9D;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAMD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,aAAa,CAKtD,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,aAAa,CAK5D,CAAC;AAMH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,CAAC,EAAE,iBAAiB,GACzB,sBAAsB,EAAE,CAwB1B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,IAAI,CAAC,EAAE,aAAa,GACnB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAgBrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oobe-protocol-labs/synapse-sap-sdk",
3
- "version": "0.6.0",
3
+ "version": "0.6.3",
4
4
  "description": "TypeScript SDK for the Synapse Agent Protocol (SAP v2) on Solana",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",
@@ -166,6 +166,7 @@
166
166
  "peerDependencies": {
167
167
  "@coral-xyz/anchor": ">=0.30.0",
168
168
  "@solana/web3.js": ">=1.90.0",
169
+ "@triton-one/yellowstone-grpc": ">=1.0.0",
169
170
  "zod": ">=3.20.0",
170
171
  "pg": ">=8.0.0"
171
172
  },
@@ -175,6 +176,9 @@
175
176
  },
176
177
  "pg": {
177
178
  "optional": true
179
+ },
180
+ "@triton-one/yellowstone-grpc": {
181
+ "optional": true
178
182
  }
179
183
  },
180
184
  "engines": {
@@ -0,0 +1,384 @@
1
+ /**
2
+ * @module events/geyser
3
+ * @description Yellowstone gRPC (Geyser) event stream for SAP v2.
4
+ *
5
+ * Drop-in alternative to the WebSocket `connection.onLogs()` pipeline.
6
+ * Uses Triton / Helius / any Yellowstone-compatible gRPC endpoint to
7
+ * receive program transaction updates with sub-second latency and
8
+ * automatic reconnection.
9
+ *
10
+ * @category Events
11
+ * @since v0.6.3
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { GeyserEventStream } from "@oobe-protocol-labs/synapse-sap-sdk";
16
+ * import { EventParser } from "@oobe-protocol-labs/synapse-sap-sdk";
17
+ *
18
+ * const stream = new GeyserEventStream({
19
+ * endpoint: "https://grpc.triton.one",
20
+ * token: process.env.GEYSER_TOKEN!,
21
+ * programId: "SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ",
22
+ * });
23
+ *
24
+ * const parser = new EventParser(program);
25
+ *
26
+ * stream.on("logs", (logs, signature, slot) => {
27
+ * const events = parser.parseLogs(logs);
28
+ * for (const event of events) {
29
+ * console.log(event.name, event.data);
30
+ * }
31
+ * });
32
+ *
33
+ * stream.on("error", (err) => console.error("gRPC error:", err));
34
+ *
35
+ * await stream.connect();
36
+ * // ... later
37
+ * await stream.disconnect();
38
+ * ```
39
+ */
40
+
41
+ import { EventEmitter } from "events";
42
+
43
+ // ═══════════════════════════════════════════════════════════════════
44
+ // Types
45
+ // ═══════════════════════════════════════════════════════════════════
46
+
47
+ /**
48
+ * Configuration for the Yellowstone gRPC event stream.
49
+ *
50
+ * @interface GeyserConfig
51
+ * @since v0.6.3
52
+ */
53
+ export interface GeyserConfig {
54
+ /** Yellowstone gRPC endpoint URL (e.g. "https://grpc.triton.one") */
55
+ endpoint: string;
56
+
57
+ /** Authentication token for the gRPC endpoint */
58
+ token: string;
59
+
60
+ /** SAP program ID to filter. Defaults to SAP v2 program. */
61
+ programId?: string;
62
+
63
+ /**
64
+ * Commitment level for the subscription.
65
+ * @default "confirmed"
66
+ */
67
+ commitment?: "processed" | "confirmed" | "finalized";
68
+
69
+ /**
70
+ * Automatically reconnect on disconnect.
71
+ * @default true
72
+ */
73
+ autoReconnect?: boolean;
74
+
75
+ /**
76
+ * Delay between reconnection attempts in ms.
77
+ * @default 3000
78
+ */
79
+ reconnectDelayMs?: number;
80
+
81
+ /**
82
+ * Maximum number of reconnection attempts. 0 = unlimited.
83
+ * @default 0
84
+ */
85
+ maxReconnectAttempts?: number;
86
+
87
+ /**
88
+ * Include failed transactions in the stream.
89
+ * @default false
90
+ */
91
+ includeFailedTxs?: boolean;
92
+ }
93
+
94
+ /**
95
+ * Events emitted by {@link GeyserEventStream}.
96
+ *
97
+ * @interface GeyserStreamEvents
98
+ * @since v0.6.3
99
+ */
100
+ export interface GeyserStreamEvents {
101
+ /**
102
+ * Emitted for each transaction's log messages.
103
+ * Same shape as `connection.onLogs()` callback — plug into `EventParser.parseLogs()`.
104
+ */
105
+ logs: (logs: string[], signature: string, slot: number) => void;
106
+
107
+ /** Emitted when the gRPC stream connects or reconnects. */
108
+ connected: () => void;
109
+
110
+ /** Emitted when the stream disconnects. */
111
+ disconnected: (reason: string) => void;
112
+
113
+ /** Emitted on transport or parsing errors. */
114
+ error: (err: Error) => void;
115
+
116
+ /** Emitted on reconnection attempt. */
117
+ reconnecting: (attempt: number) => void;
118
+ }
119
+
120
+ // ═══════════════════════════════════════════════════════════════════
121
+ // Constants
122
+ // ═══════════════════════════════════════════════════════════════════
123
+
124
+ const SAP_PROGRAM_ID = "SAPpUhsWLJG1FfkGRcXagEDMrMsWGjbky7AyhGpFETZ";
125
+
126
+ const COMMITMENT_MAP: Record<string, number> = {
127
+ processed: 0,
128
+ confirmed: 1,
129
+ finalized: 2,
130
+ };
131
+
132
+ // ═══════════════════════════════════════════════════════════════════
133
+ // GeyserEventStream
134
+ // ═══════════════════════════════════════════════════════════════════
135
+
136
+ /**
137
+ * Yellowstone gRPC event stream for SAP v2 programs.
138
+ *
139
+ * Wraps `@triton-one/yellowstone-grpc` and emits parsed log lines
140
+ * compatible with the existing {@link EventParser}.
141
+ *
142
+ * @name GeyserEventStream
143
+ * @category Events
144
+ * @since v0.6.3
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * const stream = new GeyserEventStream({
149
+ * endpoint: "https://grpc.triton.one",
150
+ * token: process.env.GEYSER_TOKEN!,
151
+ * });
152
+ *
153
+ * stream.on("logs", (logs, sig, slot) => {
154
+ * const events = parser.parseLogs(logs);
155
+ * events.forEach(e => db.insertEvent(e));
156
+ * });
157
+ *
158
+ * await stream.connect();
159
+ * ```
160
+ */
161
+ export class GeyserEventStream extends EventEmitter {
162
+ private readonly config: Required<GeyserConfig>;
163
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
164
+ private client: any = null;
165
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
166
+ private stream: any = null;
167
+ private reconnectAttempts = 0;
168
+ private _connected = false;
169
+ private _stopped = false;
170
+
171
+ constructor(config: GeyserConfig) {
172
+ super();
173
+ this.config = {
174
+ endpoint: config.endpoint,
175
+ token: config.token,
176
+ programId: config.programId ?? SAP_PROGRAM_ID,
177
+ commitment: config.commitment ?? "confirmed",
178
+ autoReconnect: config.autoReconnect ?? true,
179
+ reconnectDelayMs: config.reconnectDelayMs ?? 3_000,
180
+ maxReconnectAttempts: config.maxReconnectAttempts ?? 0,
181
+ includeFailedTxs: config.includeFailedTxs ?? false,
182
+ };
183
+ }
184
+
185
+ /** Whether the gRPC stream is currently connected. */
186
+ get connected(): boolean {
187
+ return this._connected;
188
+ }
189
+
190
+ /**
191
+ * Connect to the Yellowstone gRPC endpoint and start streaming.
192
+ *
193
+ * @throws If `@triton-one/yellowstone-grpc` is not installed.
194
+ */
195
+ async connect(): Promise<void> {
196
+ this._stopped = false;
197
+ this.reconnectAttempts = 0;
198
+
199
+ // Dynamic import — yellowstone is an optional peer dependency
200
+ let YellowstoneClient: new (...args: unknown[]) => unknown;
201
+ try {
202
+ const mod = await import("@triton-one/yellowstone-grpc");
203
+ YellowstoneClient = mod.default ?? mod.Client;
204
+ } catch {
205
+ throw new Error(
206
+ "Missing dependency: @triton-one/yellowstone-grpc\n" +
207
+ "Install it with: npm i @triton-one/yellowstone-grpc",
208
+ );
209
+ }
210
+
211
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
212
+ this.client = new (YellowstoneClient as any)(
213
+ this.config.endpoint,
214
+ this.config.token,
215
+ undefined, // TLS options — use defaults
216
+ );
217
+
218
+ await this.subscribe();
219
+ }
220
+
221
+ /**
222
+ * Disconnect from the gRPC stream and stop reconnection.
223
+ */
224
+ async disconnect(): Promise<void> {
225
+ this._stopped = true;
226
+ this._connected = false;
227
+
228
+ if (this.stream) {
229
+ try {
230
+ this.stream.cancel?.();
231
+ this.stream = null;
232
+ } catch {
233
+ // ignore cancel errors
234
+ }
235
+ }
236
+
237
+ this.emit("disconnected", "manual");
238
+ }
239
+
240
+ // ─── Internal ──────────────────────────────────────
241
+
242
+ private async subscribe(): Promise<void> {
243
+ if (!this.client || this._stopped) return;
244
+
245
+ try {
246
+ this.stream = await this.client.subscribe();
247
+ } catch (err) {
248
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
249
+ await this.maybeReconnect();
250
+ return;
251
+ }
252
+
253
+ // Build the subscription request
254
+ const request = {
255
+ accounts: {},
256
+ slots: {},
257
+ transactions: {
258
+ sap: {
259
+ vote: false,
260
+ failed: this.config.includeFailedTxs,
261
+ signature: undefined,
262
+ accountInclude: [this.config.programId],
263
+ accountExclude: [],
264
+ accountRequired: [],
265
+ },
266
+ },
267
+ transactionsStatus: {},
268
+ blocks: {},
269
+ blocksMeta: {},
270
+ entry: {},
271
+ commitment: COMMITMENT_MAP[this.config.commitment] ?? 1,
272
+ accountsDataSlice: [],
273
+ ping: { id: 1 },
274
+ };
275
+
276
+ // Send subscription
277
+ try {
278
+ await new Promise<void>((resolve, reject) => {
279
+ this.stream.write(request, (err: Error | null) => {
280
+ if (err) reject(err);
281
+ else resolve();
282
+ });
283
+ });
284
+ } catch (err) {
285
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
286
+ await this.maybeReconnect();
287
+ return;
288
+ }
289
+
290
+ this._connected = true;
291
+ this.reconnectAttempts = 0;
292
+ this.emit("connected");
293
+
294
+ // Listen for data
295
+ this.stream.on("data", (data: GeyserUpdateMessage) => {
296
+ try {
297
+ this.handleMessage(data);
298
+ } catch (err) {
299
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
300
+ }
301
+ });
302
+
303
+ this.stream.on("error", (err: Error) => {
304
+ this.emit("error", err);
305
+ });
306
+
307
+ this.stream.on("end", () => {
308
+ this._connected = false;
309
+ this.emit("disconnected", "stream-end");
310
+ this.maybeReconnect();
311
+ });
312
+
313
+ this.stream.on("close", () => {
314
+ this._connected = false;
315
+ this.emit("disconnected", "stream-close");
316
+ this.maybeReconnect();
317
+ });
318
+ }
319
+
320
+ private handleMessage(data: GeyserUpdateMessage): void {
321
+ // Respond to pings to keep the stream alive
322
+ if (data.ping) {
323
+ this.stream?.write({ ping: { id: data.ping.id } }, () => {});
324
+ return;
325
+ }
326
+
327
+ // Extract transaction data
328
+ const tx = data.transaction;
329
+ if (!tx?.transaction?.transaction) return;
330
+
331
+ const meta = tx.transaction.meta;
332
+ if (!meta) return;
333
+
334
+ // Extract log messages from the transaction meta
335
+ const logs: string[] = meta.logMessages ?? [];
336
+ if (logs.length === 0) return;
337
+
338
+ const signature = tx.transaction.signature
339
+ ? Buffer.from(tx.transaction.signature).toString("base64")
340
+ : "unknown";
341
+
342
+ const slot = Number(tx.slot ?? 0);
343
+
344
+ this.emit("logs", logs, signature, slot);
345
+ }
346
+
347
+ private async maybeReconnect(): Promise<void> {
348
+ if (this._stopped || !this.config.autoReconnect) return;
349
+
350
+ const max = this.config.maxReconnectAttempts;
351
+ if (max > 0 && this.reconnectAttempts >= max) {
352
+ this.emit(
353
+ "error",
354
+ new Error(`Max reconnect attempts (${max}) exceeded`),
355
+ );
356
+ return;
357
+ }
358
+
359
+ this.reconnectAttempts++;
360
+ this.emit("reconnecting", this.reconnectAttempts);
361
+
362
+ await new Promise((r) => setTimeout(r, this.config.reconnectDelayMs));
363
+
364
+ if (!this._stopped) {
365
+ await this.subscribe();
366
+ }
367
+ }
368
+ }
369
+
370
+ // ─── Internal Yellowstone message types ─────────────
371
+
372
+ interface GeyserUpdateMessage {
373
+ ping?: { id: number };
374
+ transaction?: {
375
+ slot?: string | number;
376
+ transaction?: {
377
+ signature?: Uint8Array;
378
+ transaction?: unknown;
379
+ meta?: {
380
+ logMessages?: string[];
381
+ };
382
+ };
383
+ };
384
+ }
@@ -0,0 +1,7 @@
1
+ // Optional peer dependency — only needed when using GeyserEventStream
2
+ declare module "@triton-one/yellowstone-grpc" {
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
+ const Client: any;
5
+ export default Client;
6
+ export { Client };
7
+ }
package/src/index.ts CHANGED
@@ -202,6 +202,20 @@ export {
202
202
  validateOrThrow,
203
203
  } from "./utils";
204
204
 
205
+ // v0.6.2 — Priority fee & settle options
206
+ export {
207
+ buildPriorityFeeIxs,
208
+ buildRpcOptions,
209
+ FAST_SETTLE_OPTIONS,
210
+ FAST_BATCH_SETTLE_OPTIONS,
211
+ DEFAULT_SETTLE_PRIORITY_FEE,
212
+ DEFAULT_SETTLE_COMPUTE_UNITS,
213
+ DEFAULT_BATCH_SETTLE_COMPUTE_UNITS,
214
+ } from "./utils";
215
+ export type {
216
+ PriorityFeeConfig,
217
+ } from "./utils";
218
+
205
219
  // ── Errors ───────────────────────────────────────────
206
220
  export {
207
221
  SapError,
@@ -226,6 +240,10 @@ export type {
226
240
  LedgerEntryEventData,
227
241
  } from "./events";
228
242
 
243
+ // ── Geyser (Yellowstone gRPC) ────────────────────────
244
+ export { GeyserEventStream } from "./events/geyser";
245
+ export type { GeyserConfig, GeyserStreamEvents } from "./events/geyser";
246
+
229
247
  // ── Modules (for advanced usage / tree-shaking) ──────
230
248
  export {
231
249
  AgentModule,
@@ -315,6 +333,7 @@ export type {
315
333
  EscrowBalance,
316
334
  SettlementResult,
317
335
  BatchSettlementResult,
336
+ SettleOptions,
318
337
  SessionContext,
319
338
  WriteResult,
320
339
  SealResult,