@k256/sdk 0.1.4 → 0.1.7

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/index.ts"],"names":["NetworkState"],"mappings":";;;AAsIO,IAAK,YAAA,qBAAAA,aAAAA,KAAL;AACL,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,SAAM,CAAA,CAAA,GAAN,KAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,YAAS,CAAA,CAAA,GAAT,QAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,UAAO,CAAA,CAAA,GAAP,MAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,eAAY,CAAA,CAAA,GAAZ,WAAA;AAJU,EAAA,OAAAA,aAAAA;AAAA,CAAA,EAAA,YAAA,IAAA,EAAA","file":"index.cjs","sourcesContent":["/**\n * Shared type definitions for K256 SDK\n * \n * These types are used across WebSocket and REST API modules.\n * \n * @module @k256/sdk/types\n */\n\n/**\n * Pool state from DEX\n */\nexport interface Pool {\n /** Pool address (Base58) */\n address: string;\n /** Protocol/DEX name */\n protocol: string;\n /** Token mints in the pool (Base58) */\n tokenMints: string[];\n /** Token balances (as strings for precision) */\n tokenBalances: string[];\n /** Token decimals */\n tokenDecimals: number[];\n /** Whether pool is valid for trading */\n isValid: boolean;\n}\n\n/**\n * Real-time pool state update\n */\nexport interface PoolUpdate extends Pool {\n /** Global sequence number (monotonically increasing) */\n sequence: number;\n /** Solana slot when updated */\n slot: number;\n /** Write version within slot */\n writeVersion: number;\n /** Best bid price/size (orderbook pools only) */\n bestBid?: OrderLevel;\n /** Best ask price/size (orderbook pools only) */\n bestAsk?: OrderLevel;\n}\n\n/**\n * Order book level (bid or ask)\n */\nexport interface OrderLevel {\n /** Price in base units (as string for precision) */\n price: string;\n /** Size in base units (as string for precision) */\n size: string;\n}\n\n/**\n * Token metadata\n */\nexport interface Token {\n /** Token mint address (Base58) */\n mint: string;\n /** Token symbol (e.g., \"SOL\", \"USDC\") */\n symbol: string;\n /** Token name */\n name: string;\n /** Decimal places */\n decimals: number;\n /** Logo URL (optional) */\n logoUri?: string;\n /** Coingecko ID (optional) */\n coingeckoId?: string;\n}\n\n/**\n * Swap quote from aggregator\n */\nexport interface Quote {\n /** Input token mint (Base58) */\n inputMint: string;\n /** Output token mint (Base58) */\n outputMint: string;\n /** Input amount (as string for precision) */\n inAmount: string;\n /** Output amount (as string for precision) */\n outAmount: string;\n /** Price impact in basis points */\n priceImpactBps: number;\n /** Slippage in basis points */\n slippageBps: number;\n /** Route plan (DEXes used) */\n routePlan: RoutePlanStep[];\n /** Context slot */\n contextSlot: number;\n /** Algorithm used for routing */\n algorithm: string;\n}\n\n/**\n * Step in a swap route\n */\nexport interface RoutePlanStep {\n /** DEX/protocol name */\n protocol: string;\n /** Pool address (Base58) */\n poolAddress: string;\n /** Input mint for this step */\n inputMint: string;\n /** Output mint for this step */\n outputMint: string;\n /** Percentage of input for this step (0-100) */\n percent: number;\n}\n\n/**\n * Priority fee estimates\n */\nexport interface PriorityFees {\n /** Current slot */\n slot: number;\n /** Timestamp in milliseconds */\n timestampMs: number;\n /** Recommended fee in microlamports */\n recommended: number;\n /** Network state (0=low, 1=normal, 2=high, 3=congested) */\n state: NetworkState;\n /** Whether data is stale */\n isStale: boolean;\n /** Swap fee percentiles */\n swapP50: number;\n swapP75: number;\n swapP90: number;\n swapP99: number;\n}\n\n/**\n * Network congestion state\n */\nexport enum NetworkState {\n Low = 0,\n Normal = 1,\n High = 2,\n Congested = 3,\n}\n\n/**\n * Recent blockhash for transactions\n */\nexport interface Blockhash {\n /** Slot of blockhash */\n slot: number;\n /** Timestamp in milliseconds */\n timestampMs: number;\n /** Recent blockhash (Base58) */\n blockhash: string;\n /** Block height */\n blockHeight: number;\n /** Last valid block height for transactions */\n lastValidBlockHeight: number;\n /** Whether data is stale */\n isStale: boolean;\n}\n\n/**\n * WebSocket connection heartbeat\n */\nexport interface Heartbeat {\n /** Server timestamp in milliseconds */\n timestampMs: number;\n /** Connection uptime in seconds */\n uptimeSecs: number;\n /** Total messages sent */\n messagesSent: number;\n /** Pool updates sent */\n poolUpdatesSent: number;\n /** Messages dropped (slow client) */\n messagesDropped: number;\n /** Whether pool updates are enabled */\n poolUpdatesEnabled: boolean;\n /** Subscribed channels */\n subscribedChannels: string[];\n /** Server sequence number */\n serverSequence: number;\n}\n\n/**\n * Subscribe request for WebSocket\n */\nexport interface SubscribeRequest {\n /** Channels to subscribe to */\n channels: ('pools' | 'priority_fees' | 'blockhash')[];\n /** Response format (default: binary) */\n format?: 'binary' | 'json';\n /** Filter by protocol names */\n protocols?: string[];\n /** Filter by pool addresses (Base58) */\n pools?: string[];\n /** Filter by token pairs [[mintA, mintB], ...] */\n tokenPairs?: [string, string][];\n}\n\n/**\n * Quote subscription request\n */\nexport interface SubscribeQuoteRequest {\n /** Input token mint (Base58) */\n inputMint: string;\n /** Output token mint (Base58) */\n outputMint: string;\n /** Amount in base units */\n amount: number;\n /** Slippage tolerance in basis points */\n slippageBps?: number;\n /** Refresh interval in milliseconds */\n refreshIntervalMs?: number;\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/index.ts"],"names":["NetworkState"],"mappings":";;;AAuKO,IAAK,YAAA,qBAAAA,aAAAA,KAAL;AACL,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,SAAM,CAAA,CAAA,GAAN,KAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,YAAS,CAAA,CAAA,GAAT,QAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,UAAO,CAAA,CAAA,GAAP,MAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,eAAY,CAAA,CAAA,GAAZ,WAAA;AAJU,EAAA,OAAAA,aAAAA;AAAA,CAAA,EAAA,YAAA,IAAA,EAAA","file":"index.cjs","sourcesContent":["/**\n * Shared type definitions for K256 SDK\n *\n * These types are used across WebSocket and REST API modules.\n *\n * @module @k256/sdk/types\n */\n\n/**\n * Pool state from DEX\n */\nexport interface Pool {\n /** Pool address (Base58) */\n address: string;\n /** Protocol/DEX name */\n protocol: string;\n /** Token mints in the pool (Base58) */\n tokenMints: string[];\n /** Token balances (as strings for precision) */\n tokenBalances: string[];\n /** Token decimals */\n tokenDecimals: number[];\n}\n\n/**\n * Real-time pool state update\n */\nexport interface PoolUpdate extends Pool {\n /** Global sequence number (monotonically increasing) */\n sequence: number;\n /** Solana slot when updated */\n slot: number;\n /** Write version within slot */\n writeVersion: number;\n /** Best bid price/size (orderbook pools only) */\n bestBid?: OrderLevel;\n /** Best ask price/size (orderbook pools only) */\n bestAsk?: OrderLevel;\n}\n\n/**\n * Order book level (bid or ask)\n */\nexport interface OrderLevel {\n /** Price in base units (as string for precision) */\n price: string;\n /** Size in base units (as string for precision) */\n size: string;\n}\n\n/**\n * Token metadata\n */\nexport interface Token {\n /** Token mint address (Base58) */\n mint: string;\n /** Token symbol (e.g., \"SOL\", \"USDC\") */\n symbol: string;\n /** Token name */\n name: string;\n /** Decimal places */\n decimals: number;\n /** Logo URL (optional) */\n logoUri?: string;\n /** Coingecko ID (optional) */\n coingeckoId?: string;\n}\n\n/**\n * Swap quote from aggregator\n */\nexport interface Quote {\n /** Input token mint (Base58) */\n inputMint: string;\n /** Output token mint (Base58) */\n outputMint: string;\n /** Input amount (as string for precision) */\n inAmount: string;\n /** Output amount (as string for precision) */\n outAmount: string;\n /** Price impact in basis points */\n priceImpactBps: number;\n /** Slippage in basis points */\n slippageBps: number;\n /** Route plan (DEXes used) */\n routePlan: RoutePlanStep[];\n /** Context slot */\n contextSlot: number;\n /** Algorithm used for routing */\n algorithm: string;\n}\n\n/**\n * Step in a swap route\n */\nexport interface RoutePlanStep {\n /** DEX/protocol name */\n protocol: string;\n /** Pool address (Base58) */\n poolAddress: string;\n /** Input mint for this step */\n inputMint: string;\n /** Output mint for this step */\n outputMint: string;\n /** Percentage of input for this step (0-100) */\n percent: number;\n}\n\n/**\n * Per-writable-account fee data\n *\n * Solana's scheduler limits each writable account to 12M CU per block.\n * Fee pricing is per-account: the fee you pay should be\n * max(p75(account) for account in your writable accounts).\n */\nexport interface AccountFee {\n /** Account public key (Base58) */\n pubkey: string;\n /** Total transactions touching this account in the window */\n totalTxs: number;\n /** Number of slots where this account was active */\n activeSlots: number;\n /** Total CU consumed by transactions touching this account */\n cuConsumed: number;\n /** Account utilization percentage (0-100) of 12M CU limit */\n utilizationPct: number;\n /** 25th percentile fee in microlamports/CU */\n p25: number;\n /** 50th percentile fee in microlamports/CU */\n p50: number;\n /** 75th percentile fee in microlamports/CU */\n p75: number;\n /** 90th percentile fee in microlamports/CU */\n p90: number;\n /** Minimum non-zero fee observed */\n minNonzeroPrice: number;\n}\n\n/**\n * Fee market update (per-writable-account model)\n *\n * Replaces the old flat PriorityFees struct. Now provides per-account\n * fee data so clients can price transactions based on the specific\n * writable accounts they touch.\n */\nexport interface FeeMarket {\n /** Current slot */\n slot: number;\n /** Timestamp in milliseconds */\n timestampMs: number;\n /** Recommended fee in microlamports/CU (max p75 across hottest accounts) */\n recommended: number;\n /** Network state (0=low, 1=normal, 2=high, 3=extreme) */\n state: NetworkState;\n /** Whether data is stale */\n isStale: boolean;\n /** Block utilization percentage (0-100) */\n blockUtilizationPct: number;\n /** Number of blocks in the observation window */\n blocksInWindow: number;\n /** Per-account fee data */\n accounts: AccountFee[];\n}\n\n/**\n * Network congestion state\n */\nexport enum NetworkState {\n Low = 0,\n Normal = 1,\n High = 2,\n Congested = 3,\n}\n\n/**\n * Recent blockhash for transactions\n */\nexport interface Blockhash {\n /** Slot of blockhash */\n slot: number;\n /** Timestamp in milliseconds */\n timestampMs: number;\n /** Recent blockhash (Base58) */\n blockhash: string;\n /** Block height */\n blockHeight: number;\n /** Last valid block height for transactions */\n lastValidBlockHeight: number;\n /** Whether data is stale */\n isStale: boolean;\n}\n\n/**\n * WebSocket connection heartbeat\n */\nexport interface Heartbeat {\n /** Server timestamp in milliseconds */\n timestampMs: number;\n /** Connection uptime in seconds */\n uptimeSecs: number;\n /** Total messages sent */\n messagesSent: number;\n /** Pool updates sent */\n poolUpdatesSent: number;\n /** Messages dropped (slow client) */\n messagesDropped: number;\n /** Whether pool updates are enabled */\n poolUpdatesEnabled: boolean;\n /** Subscribed channels */\n subscribedChannels: string[];\n /** Server sequence number */\n serverSequence: number;\n}\n\n/**\n * Subscribe request for WebSocket\n */\nexport interface SubscribeRequest {\n /** Channels to subscribe to */\n channels: ('pools' | 'priority_fees' | 'blockhash')[];\n /** Response format (default: binary) */\n format?: 'binary' | 'json';\n /** Filter by protocol names */\n protocols?: string[];\n /** Filter by pool addresses (Base58) */\n pools?: string[];\n /** Filter by token pairs [[mintA, mintB], ...] */\n tokenPairs?: [string, string][];\n}\n\n/**\n * Quote subscription request\n */\nexport interface SubscribeQuoteRequest {\n /** Input token mint (Base58) */\n inputMint: string;\n /** Output token mint (Base58) */\n outputMint: string;\n /** Amount in base units */\n amount: number;\n /** Slippage tolerance in basis points */\n slippageBps?: number;\n /** Refresh interval in milliseconds */\n refreshIntervalMs?: number;\n}\n"]}
@@ -19,8 +19,6 @@ interface Pool {
19
19
  tokenBalances: string[];
20
20
  /** Token decimals */
21
21
  tokenDecimals: number[];
22
- /** Whether pool is valid for trading */
23
- isValid: boolean;
24
22
  }
25
23
  /**
26
24
  * Real-time pool state update
@@ -102,24 +100,58 @@ interface RoutePlanStep {
102
100
  percent: number;
103
101
  }
104
102
  /**
105
- * Priority fee estimates
103
+ * Per-writable-account fee data
104
+ *
105
+ * Solana's scheduler limits each writable account to 12M CU per block.
106
+ * Fee pricing is per-account: the fee you pay should be
107
+ * max(p75(account) for account in your writable accounts).
108
+ */
109
+ interface AccountFee {
110
+ /** Account public key (Base58) */
111
+ pubkey: string;
112
+ /** Total transactions touching this account in the window */
113
+ totalTxs: number;
114
+ /** Number of slots where this account was active */
115
+ activeSlots: number;
116
+ /** Total CU consumed by transactions touching this account */
117
+ cuConsumed: number;
118
+ /** Account utilization percentage (0-100) of 12M CU limit */
119
+ utilizationPct: number;
120
+ /** 25th percentile fee in microlamports/CU */
121
+ p25: number;
122
+ /** 50th percentile fee in microlamports/CU */
123
+ p50: number;
124
+ /** 75th percentile fee in microlamports/CU */
125
+ p75: number;
126
+ /** 90th percentile fee in microlamports/CU */
127
+ p90: number;
128
+ /** Minimum non-zero fee observed */
129
+ minNonzeroPrice: number;
130
+ }
131
+ /**
132
+ * Fee market update (per-writable-account model)
133
+ *
134
+ * Replaces the old flat PriorityFees struct. Now provides per-account
135
+ * fee data so clients can price transactions based on the specific
136
+ * writable accounts they touch.
106
137
  */
107
- interface PriorityFees {
138
+ interface FeeMarket {
108
139
  /** Current slot */
109
140
  slot: number;
110
141
  /** Timestamp in milliseconds */
111
142
  timestampMs: number;
112
- /** Recommended fee in microlamports */
143
+ /** Recommended fee in microlamports/CU (max p75 across hottest accounts) */
113
144
  recommended: number;
114
- /** Network state (0=low, 1=normal, 2=high, 3=congested) */
145
+ /** Network state (0=low, 1=normal, 2=high, 3=extreme) */
115
146
  state: NetworkState;
116
147
  /** Whether data is stale */
117
148
  isStale: boolean;
118
- /** Swap fee percentiles */
119
- swapP50: number;
120
- swapP75: number;
121
- swapP90: number;
122
- swapP99: number;
149
+ /** Block utilization percentage (0-100) */
150
+ blockUtilizationPct: number;
151
+ /** Number of blocks in the observation window */
152
+ blocksInWindow: number;
153
+ /** Per-account fee data */
154
+ accounts: AccountFee[];
123
155
  }
124
156
  /**
125
157
  * Network congestion state
@@ -199,4 +231,4 @@ interface SubscribeQuoteRequest {
199
231
  refreshIntervalMs?: number;
200
232
  }
201
233
 
202
- export { type Blockhash, type Heartbeat, NetworkState, type OrderLevel, type Pool, type PoolUpdate, type PriorityFees, type Quote, type RoutePlanStep, type SubscribeQuoteRequest, type SubscribeRequest, type Token };
234
+ export { type AccountFee, type Blockhash, type FeeMarket, type Heartbeat, NetworkState, type OrderLevel, type Pool, type PoolUpdate, type Quote, type RoutePlanStep, type SubscribeQuoteRequest, type SubscribeRequest, type Token };
@@ -19,8 +19,6 @@ interface Pool {
19
19
  tokenBalances: string[];
20
20
  /** Token decimals */
21
21
  tokenDecimals: number[];
22
- /** Whether pool is valid for trading */
23
- isValid: boolean;
24
22
  }
25
23
  /**
26
24
  * Real-time pool state update
@@ -102,24 +100,58 @@ interface RoutePlanStep {
102
100
  percent: number;
103
101
  }
104
102
  /**
105
- * Priority fee estimates
103
+ * Per-writable-account fee data
104
+ *
105
+ * Solana's scheduler limits each writable account to 12M CU per block.
106
+ * Fee pricing is per-account: the fee you pay should be
107
+ * max(p75(account) for account in your writable accounts).
108
+ */
109
+ interface AccountFee {
110
+ /** Account public key (Base58) */
111
+ pubkey: string;
112
+ /** Total transactions touching this account in the window */
113
+ totalTxs: number;
114
+ /** Number of slots where this account was active */
115
+ activeSlots: number;
116
+ /** Total CU consumed by transactions touching this account */
117
+ cuConsumed: number;
118
+ /** Account utilization percentage (0-100) of 12M CU limit */
119
+ utilizationPct: number;
120
+ /** 25th percentile fee in microlamports/CU */
121
+ p25: number;
122
+ /** 50th percentile fee in microlamports/CU */
123
+ p50: number;
124
+ /** 75th percentile fee in microlamports/CU */
125
+ p75: number;
126
+ /** 90th percentile fee in microlamports/CU */
127
+ p90: number;
128
+ /** Minimum non-zero fee observed */
129
+ minNonzeroPrice: number;
130
+ }
131
+ /**
132
+ * Fee market update (per-writable-account model)
133
+ *
134
+ * Replaces the old flat PriorityFees struct. Now provides per-account
135
+ * fee data so clients can price transactions based on the specific
136
+ * writable accounts they touch.
106
137
  */
107
- interface PriorityFees {
138
+ interface FeeMarket {
108
139
  /** Current slot */
109
140
  slot: number;
110
141
  /** Timestamp in milliseconds */
111
142
  timestampMs: number;
112
- /** Recommended fee in microlamports */
143
+ /** Recommended fee in microlamports/CU (max p75 across hottest accounts) */
113
144
  recommended: number;
114
- /** Network state (0=low, 1=normal, 2=high, 3=congested) */
145
+ /** Network state (0=low, 1=normal, 2=high, 3=extreme) */
115
146
  state: NetworkState;
116
147
  /** Whether data is stale */
117
148
  isStale: boolean;
118
- /** Swap fee percentiles */
119
- swapP50: number;
120
- swapP75: number;
121
- swapP90: number;
122
- swapP99: number;
149
+ /** Block utilization percentage (0-100) */
150
+ blockUtilizationPct: number;
151
+ /** Number of blocks in the observation window */
152
+ blocksInWindow: number;
153
+ /** Per-account fee data */
154
+ accounts: AccountFee[];
123
155
  }
124
156
  /**
125
157
  * Network congestion state
@@ -199,4 +231,4 @@ interface SubscribeQuoteRequest {
199
231
  refreshIntervalMs?: number;
200
232
  }
201
233
 
202
- export { type Blockhash, type Heartbeat, NetworkState, type OrderLevel, type Pool, type PoolUpdate, type PriorityFees, type Quote, type RoutePlanStep, type SubscribeQuoteRequest, type SubscribeRequest, type Token };
234
+ export { type AccountFee, type Blockhash, type FeeMarket, type Heartbeat, NetworkState, type OrderLevel, type Pool, type PoolUpdate, type Quote, type RoutePlanStep, type SubscribeQuoteRequest, type SubscribeRequest, type Token };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/index.ts"],"names":["NetworkState"],"mappings":";AAsIO,IAAK,YAAA,qBAAAA,aAAAA,KAAL;AACL,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,SAAM,CAAA,CAAA,GAAN,KAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,YAAS,CAAA,CAAA,GAAT,QAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,UAAO,CAAA,CAAA,GAAP,MAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,eAAY,CAAA,CAAA,GAAZ,WAAA;AAJU,EAAA,OAAAA,aAAAA;AAAA,CAAA,EAAA,YAAA,IAAA,EAAA","file":"index.js","sourcesContent":["/**\n * Shared type definitions for K256 SDK\n * \n * These types are used across WebSocket and REST API modules.\n * \n * @module @k256/sdk/types\n */\n\n/**\n * Pool state from DEX\n */\nexport interface Pool {\n /** Pool address (Base58) */\n address: string;\n /** Protocol/DEX name */\n protocol: string;\n /** Token mints in the pool (Base58) */\n tokenMints: string[];\n /** Token balances (as strings for precision) */\n tokenBalances: string[];\n /** Token decimals */\n tokenDecimals: number[];\n /** Whether pool is valid for trading */\n isValid: boolean;\n}\n\n/**\n * Real-time pool state update\n */\nexport interface PoolUpdate extends Pool {\n /** Global sequence number (monotonically increasing) */\n sequence: number;\n /** Solana slot when updated */\n slot: number;\n /** Write version within slot */\n writeVersion: number;\n /** Best bid price/size (orderbook pools only) */\n bestBid?: OrderLevel;\n /** Best ask price/size (orderbook pools only) */\n bestAsk?: OrderLevel;\n}\n\n/**\n * Order book level (bid or ask)\n */\nexport interface OrderLevel {\n /** Price in base units (as string for precision) */\n price: string;\n /** Size in base units (as string for precision) */\n size: string;\n}\n\n/**\n * Token metadata\n */\nexport interface Token {\n /** Token mint address (Base58) */\n mint: string;\n /** Token symbol (e.g., \"SOL\", \"USDC\") */\n symbol: string;\n /** Token name */\n name: string;\n /** Decimal places */\n decimals: number;\n /** Logo URL (optional) */\n logoUri?: string;\n /** Coingecko ID (optional) */\n coingeckoId?: string;\n}\n\n/**\n * Swap quote from aggregator\n */\nexport interface Quote {\n /** Input token mint (Base58) */\n inputMint: string;\n /** Output token mint (Base58) */\n outputMint: string;\n /** Input amount (as string for precision) */\n inAmount: string;\n /** Output amount (as string for precision) */\n outAmount: string;\n /** Price impact in basis points */\n priceImpactBps: number;\n /** Slippage in basis points */\n slippageBps: number;\n /** Route plan (DEXes used) */\n routePlan: RoutePlanStep[];\n /** Context slot */\n contextSlot: number;\n /** Algorithm used for routing */\n algorithm: string;\n}\n\n/**\n * Step in a swap route\n */\nexport interface RoutePlanStep {\n /** DEX/protocol name */\n protocol: string;\n /** Pool address (Base58) */\n poolAddress: string;\n /** Input mint for this step */\n inputMint: string;\n /** Output mint for this step */\n outputMint: string;\n /** Percentage of input for this step (0-100) */\n percent: number;\n}\n\n/**\n * Priority fee estimates\n */\nexport interface PriorityFees {\n /** Current slot */\n slot: number;\n /** Timestamp in milliseconds */\n timestampMs: number;\n /** Recommended fee in microlamports */\n recommended: number;\n /** Network state (0=low, 1=normal, 2=high, 3=congested) */\n state: NetworkState;\n /** Whether data is stale */\n isStale: boolean;\n /** Swap fee percentiles */\n swapP50: number;\n swapP75: number;\n swapP90: number;\n swapP99: number;\n}\n\n/**\n * Network congestion state\n */\nexport enum NetworkState {\n Low = 0,\n Normal = 1,\n High = 2,\n Congested = 3,\n}\n\n/**\n * Recent blockhash for transactions\n */\nexport interface Blockhash {\n /** Slot of blockhash */\n slot: number;\n /** Timestamp in milliseconds */\n timestampMs: number;\n /** Recent blockhash (Base58) */\n blockhash: string;\n /** Block height */\n blockHeight: number;\n /** Last valid block height for transactions */\n lastValidBlockHeight: number;\n /** Whether data is stale */\n isStale: boolean;\n}\n\n/**\n * WebSocket connection heartbeat\n */\nexport interface Heartbeat {\n /** Server timestamp in milliseconds */\n timestampMs: number;\n /** Connection uptime in seconds */\n uptimeSecs: number;\n /** Total messages sent */\n messagesSent: number;\n /** Pool updates sent */\n poolUpdatesSent: number;\n /** Messages dropped (slow client) */\n messagesDropped: number;\n /** Whether pool updates are enabled */\n poolUpdatesEnabled: boolean;\n /** Subscribed channels */\n subscribedChannels: string[];\n /** Server sequence number */\n serverSequence: number;\n}\n\n/**\n * Subscribe request for WebSocket\n */\nexport interface SubscribeRequest {\n /** Channels to subscribe to */\n channels: ('pools' | 'priority_fees' | 'blockhash')[];\n /** Response format (default: binary) */\n format?: 'binary' | 'json';\n /** Filter by protocol names */\n protocols?: string[];\n /** Filter by pool addresses (Base58) */\n pools?: string[];\n /** Filter by token pairs [[mintA, mintB], ...] */\n tokenPairs?: [string, string][];\n}\n\n/**\n * Quote subscription request\n */\nexport interface SubscribeQuoteRequest {\n /** Input token mint (Base58) */\n inputMint: string;\n /** Output token mint (Base58) */\n outputMint: string;\n /** Amount in base units */\n amount: number;\n /** Slippage tolerance in basis points */\n slippageBps?: number;\n /** Refresh interval in milliseconds */\n refreshIntervalMs?: number;\n}\n"]}
1
+ {"version":3,"sources":["../../src/types/index.ts"],"names":["NetworkState"],"mappings":";AAuKO,IAAK,YAAA,qBAAAA,aAAAA,KAAL;AACL,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,SAAM,CAAA,CAAA,GAAN,KAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,YAAS,CAAA,CAAA,GAAT,QAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,UAAO,CAAA,CAAA,GAAP,MAAA;AACA,EAAAA,aAAAA,CAAAA,aAAAA,CAAA,eAAY,CAAA,CAAA,GAAZ,WAAA;AAJU,EAAA,OAAAA,aAAAA;AAAA,CAAA,EAAA,YAAA,IAAA,EAAA","file":"index.js","sourcesContent":["/**\n * Shared type definitions for K256 SDK\n *\n * These types are used across WebSocket and REST API modules.\n *\n * @module @k256/sdk/types\n */\n\n/**\n * Pool state from DEX\n */\nexport interface Pool {\n /** Pool address (Base58) */\n address: string;\n /** Protocol/DEX name */\n protocol: string;\n /** Token mints in the pool (Base58) */\n tokenMints: string[];\n /** Token balances (as strings for precision) */\n tokenBalances: string[];\n /** Token decimals */\n tokenDecimals: number[];\n}\n\n/**\n * Real-time pool state update\n */\nexport interface PoolUpdate extends Pool {\n /** Global sequence number (monotonically increasing) */\n sequence: number;\n /** Solana slot when updated */\n slot: number;\n /** Write version within slot */\n writeVersion: number;\n /** Best bid price/size (orderbook pools only) */\n bestBid?: OrderLevel;\n /** Best ask price/size (orderbook pools only) */\n bestAsk?: OrderLevel;\n}\n\n/**\n * Order book level (bid or ask)\n */\nexport interface OrderLevel {\n /** Price in base units (as string for precision) */\n price: string;\n /** Size in base units (as string for precision) */\n size: string;\n}\n\n/**\n * Token metadata\n */\nexport interface Token {\n /** Token mint address (Base58) */\n mint: string;\n /** Token symbol (e.g., \"SOL\", \"USDC\") */\n symbol: string;\n /** Token name */\n name: string;\n /** Decimal places */\n decimals: number;\n /** Logo URL (optional) */\n logoUri?: string;\n /** Coingecko ID (optional) */\n coingeckoId?: string;\n}\n\n/**\n * Swap quote from aggregator\n */\nexport interface Quote {\n /** Input token mint (Base58) */\n inputMint: string;\n /** Output token mint (Base58) */\n outputMint: string;\n /** Input amount (as string for precision) */\n inAmount: string;\n /** Output amount (as string for precision) */\n outAmount: string;\n /** Price impact in basis points */\n priceImpactBps: number;\n /** Slippage in basis points */\n slippageBps: number;\n /** Route plan (DEXes used) */\n routePlan: RoutePlanStep[];\n /** Context slot */\n contextSlot: number;\n /** Algorithm used for routing */\n algorithm: string;\n}\n\n/**\n * Step in a swap route\n */\nexport interface RoutePlanStep {\n /** DEX/protocol name */\n protocol: string;\n /** Pool address (Base58) */\n poolAddress: string;\n /** Input mint for this step */\n inputMint: string;\n /** Output mint for this step */\n outputMint: string;\n /** Percentage of input for this step (0-100) */\n percent: number;\n}\n\n/**\n * Per-writable-account fee data\n *\n * Solana's scheduler limits each writable account to 12M CU per block.\n * Fee pricing is per-account: the fee you pay should be\n * max(p75(account) for account in your writable accounts).\n */\nexport interface AccountFee {\n /** Account public key (Base58) */\n pubkey: string;\n /** Total transactions touching this account in the window */\n totalTxs: number;\n /** Number of slots where this account was active */\n activeSlots: number;\n /** Total CU consumed by transactions touching this account */\n cuConsumed: number;\n /** Account utilization percentage (0-100) of 12M CU limit */\n utilizationPct: number;\n /** 25th percentile fee in microlamports/CU */\n p25: number;\n /** 50th percentile fee in microlamports/CU */\n p50: number;\n /** 75th percentile fee in microlamports/CU */\n p75: number;\n /** 90th percentile fee in microlamports/CU */\n p90: number;\n /** Minimum non-zero fee observed */\n minNonzeroPrice: number;\n}\n\n/**\n * Fee market update (per-writable-account model)\n *\n * Replaces the old flat PriorityFees struct. Now provides per-account\n * fee data so clients can price transactions based on the specific\n * writable accounts they touch.\n */\nexport interface FeeMarket {\n /** Current slot */\n slot: number;\n /** Timestamp in milliseconds */\n timestampMs: number;\n /** Recommended fee in microlamports/CU (max p75 across hottest accounts) */\n recommended: number;\n /** Network state (0=low, 1=normal, 2=high, 3=extreme) */\n state: NetworkState;\n /** Whether data is stale */\n isStale: boolean;\n /** Block utilization percentage (0-100) */\n blockUtilizationPct: number;\n /** Number of blocks in the observation window */\n blocksInWindow: number;\n /** Per-account fee data */\n accounts: AccountFee[];\n}\n\n/**\n * Network congestion state\n */\nexport enum NetworkState {\n Low = 0,\n Normal = 1,\n High = 2,\n Congested = 3,\n}\n\n/**\n * Recent blockhash for transactions\n */\nexport interface Blockhash {\n /** Slot of blockhash */\n slot: number;\n /** Timestamp in milliseconds */\n timestampMs: number;\n /** Recent blockhash (Base58) */\n blockhash: string;\n /** Block height */\n blockHeight: number;\n /** Last valid block height for transactions */\n lastValidBlockHeight: number;\n /** Whether data is stale */\n isStale: boolean;\n}\n\n/**\n * WebSocket connection heartbeat\n */\nexport interface Heartbeat {\n /** Server timestamp in milliseconds */\n timestampMs: number;\n /** Connection uptime in seconds */\n uptimeSecs: number;\n /** Total messages sent */\n messagesSent: number;\n /** Pool updates sent */\n poolUpdatesSent: number;\n /** Messages dropped (slow client) */\n messagesDropped: number;\n /** Whether pool updates are enabled */\n poolUpdatesEnabled: boolean;\n /** Subscribed channels */\n subscribedChannels: string[];\n /** Server sequence number */\n serverSequence: number;\n}\n\n/**\n * Subscribe request for WebSocket\n */\nexport interface SubscribeRequest {\n /** Channels to subscribe to */\n channels: ('pools' | 'priority_fees' | 'blockhash')[];\n /** Response format (default: binary) */\n format?: 'binary' | 'json';\n /** Filter by protocol names */\n protocols?: string[];\n /** Filter by pool addresses (Base58) */\n pools?: string[];\n /** Filter by token pairs [[mintA, mintB], ...] */\n tokenPairs?: [string, string][];\n}\n\n/**\n * Quote subscription request\n */\nexport interface SubscribeQuoteRequest {\n /** Input token mint (Base58) */\n inputMint: string;\n /** Output token mint (Base58) */\n outputMint: string;\n /** Amount in base units */\n amount: number;\n /** Slippage tolerance in basis points */\n slippageBps?: number;\n /** Refresh interval in milliseconds */\n refreshIntervalMs?: number;\n}\n"]}
@@ -23,8 +23,15 @@ function base58Encode(bytes) {
23
23
  return leadingZeros + digits.reverse().map((d) => BASE58_ALPHABET[d]).join("");
24
24
  }
25
25
  function base58Decode(str) {
26
+ if (str.length === 0) {
27
+ return new Uint8Array(0);
28
+ }
29
+ let leadingZeros = 0;
30
+ for (let i = 0; i < str.length && str[i] === "1"; i++) {
31
+ leadingZeros++;
32
+ }
26
33
  const bytes = [0];
27
- for (let i = 0; i < str.length; i++) {
34
+ for (let i = leadingZeros; i < str.length; i++) {
28
35
  const char = str[i];
29
36
  const value = BASE58_ALPHABET.indexOf(char);
30
37
  if (value === -1) {
@@ -41,10 +48,19 @@ function base58Decode(str) {
41
48
  carry >>= 8;
42
49
  }
43
50
  }
44
- for (let i = 0; i < str.length && str[i] === "1"; i++) {
45
- bytes.push(0);
51
+ bytes.reverse();
52
+ if (leadingZeros > 0 && bytes.length === 1 && bytes[0] === 0) {
53
+ return new Uint8Array(leadingZeros);
54
+ }
55
+ const startIdx = bytes.length > 1 && bytes[0] === 0 ? 1 : 0;
56
+ const result = new Uint8Array(leadingZeros + bytes.length - startIdx);
57
+ for (let i = 0; i < leadingZeros; i++) {
58
+ result[i] = 0;
59
+ }
60
+ for (let i = startIdx; i < bytes.length; i++) {
61
+ result[leadingZeros + i - startIdx] = bytes[i];
46
62
  }
47
- return new Uint8Array(bytes.reverse());
63
+ return result;
48
64
  }
49
65
  function isValidPubkey(address) {
50
66
  if (address.length < 32 || address.length > 44) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/base58.ts"],"names":[],"mappings":";;;AAMA,IAAM,eAAA,GAAkB,4DAAA;AAejB,SAAS,aAAa,KAAA,EAA2B;AACtD,EAAA,MAAM,MAAA,GAAS,CAAC,CAAC,CAAA;AAEjB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,IAAI,KAAA,GAAQ,MAAM,CAAC,CAAA;AACnB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,MAAA,KAAA,IAAS,MAAA,CAAO,CAAC,CAAA,IAAK,CAAA;AACtB,MAAA,MAAA,CAAO,CAAC,IAAI,KAAA,GAAQ,EAAA;AACpB,MAAA,KAAA,GAAS,QAAQ,EAAA,GAAM,CAAA;AAAA,IACzB;AACA,IAAA,OAAO,QAAQ,CAAA,EAAG;AAChB,MAAA,MAAA,CAAO,IAAA,CAAK,QAAQ,EAAE,CAAA;AACtB,MAAA,KAAA,GAAS,QAAQ,EAAA,GAAM,CAAA;AAAA,IACzB;AAAA,EACF;AAGA,EAAA,IAAI,YAAA,GAAe,EAAA;AACnB,EAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,GAAI,KAAA,CAAM,UAAU,KAAA,CAAM,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA,EAAA,EAAK;AACvD,IAAA,YAAA,IAAgB,GAAA;AAAA,EAClB;AAEA,EAAA,OAAO,YAAA,GAAe,MAAA,CAAO,OAAA,EAAQ,CAAE,GAAA,CAAI,CAAA,CAAA,KAAK,eAAA,CAAgB,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AAC7E;AAeO,SAAS,aAAa,GAAA,EAAyB;AACpD,EAAA,MAAM,KAAA,GAAQ,CAAC,CAAC,CAAA;AAEhB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,CAAI,QAAQ,CAAA,EAAA,EAAK;AACnC,IAAA,MAAM,IAAA,GAAO,IAAI,CAAC,CAAA;AAClB,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,OAAA,CAAQ,IAAI,CAAA;AAE1C,IAAA,IAAI,UAAU,EAAA,EAAI;AAChB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,IAAI,CAAA,CAAE,CAAA;AAAA,IACrD;AAEA,IAAA,IAAI,KAAA,GAAQ,KAAA;AACZ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,MAAA,KAAA,IAAS,KAAA,CAAM,CAAC,CAAA,GAAI,EAAA;AACpB,MAAA,KAAA,CAAM,CAAC,IAAI,KAAA,GAAQ,GAAA;AACnB,MAAA,KAAA,KAAU,CAAA;AAAA,IACZ;AACA,IAAA,OAAO,QAAQ,CAAA,EAAG;AAChB,MAAA,KAAA,CAAM,IAAA,CAAK,QAAQ,GAAI,CAAA;AACvB,MAAA,KAAA,KAAU,CAAA;AAAA,IACZ;AAAA,EACF;AAGA,EAAA,KAAA,IAAS,CAAA,GAAI,GAAG,CAAA,GAAI,GAAA,CAAI,UAAU,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA,EAAK,CAAA,EAAA,EAAK;AACrD,IAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,EACd;AAEA,EAAA,OAAO,IAAI,UAAA,CAAW,KAAA,CAAM,OAAA,EAAS,CAAA;AACvC;AAcO,SAAS,cAAc,OAAA,EAA0B;AAEtD,EAAA,IAAI,OAAA,CAAQ,MAAA,GAAS,EAAA,IAAM,OAAA,CAAQ,SAAS,EAAA,EAAI;AAC9C,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,KAAA,MAAW,QAAQ,OAAA,EAAS;AAC1B,IAAA,IAAI,CAAC,eAAA,CAAgB,QAAA,CAAS,IAAI,CAAA,EAAG;AACnC,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAGA,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,aAAa,OAAO,CAAA;AAClC,IAAA,OAAO,MAAM,MAAA,KAAW,EAAA;AAAA,EAC1B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"index.cjs","sourcesContent":["/**\n * Base58 encoding utilities for Solana addresses\n * \n * Solana uses Base58 encoding (Bitcoin-style) for public keys and signatures.\n */\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\n/**\n * Encode bytes to Base58 string (Solana address format)\n * \n * @param bytes - Uint8Array to encode\n * @returns Base58 encoded string\n * \n * @example\n * ```typescript\n * const pubkey = new Uint8Array([1, 2, 3, ...]);\n * const address = base58Encode(pubkey);\n * // \"EPjFWdd5...\"\n * ```\n */\nexport function base58Encode(bytes: Uint8Array): string {\n const digits = [0];\n \n for (let i = 0; i < bytes.length; i++) {\n let carry = bytes[i];\n for (let j = 0; j < digits.length; j++) {\n carry += digits[j] << 8;\n digits[j] = carry % 58;\n carry = (carry / 58) | 0;\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = (carry / 58) | 0;\n }\n }\n\n // Leading zeros\n let leadingZeros = '';\n for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {\n leadingZeros += '1';\n }\n\n return leadingZeros + digits.reverse().map(d => BASE58_ALPHABET[d]).join('');\n}\n\n/**\n * Decode Base58 string to bytes\n * \n * @param str - Base58 encoded string\n * @returns Uint8Array of decoded bytes\n * @throws Error if string contains invalid characters\n * \n * @example\n * ```typescript\n * const bytes = base58Decode(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\");\n * // Uint8Array(32) [...]\n * ```\n */\nexport function base58Decode(str: string): Uint8Array {\n const bytes = [0];\n \n for (let i = 0; i < str.length; i++) {\n const char = str[i];\n const value = BASE58_ALPHABET.indexOf(char);\n \n if (value === -1) {\n throw new Error(`Invalid Base58 character: ${char}`);\n }\n \n let carry = value;\n for (let j = 0; j < bytes.length; j++) {\n carry += bytes[j] * 58;\n bytes[j] = carry & 0xff;\n carry >>= 8;\n }\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n\n // Leading '1's are leading zeros\n for (let i = 0; i < str.length && str[i] === '1'; i++) {\n bytes.push(0);\n }\n\n return new Uint8Array(bytes.reverse());\n}\n\n/**\n * Check if a string is a valid Solana public key (Base58, 32-44 chars)\n * \n * @param address - String to validate\n * @returns true if valid Solana pubkey format\n * \n * @example\n * ```typescript\n * isValidPubkey(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\") // true\n * isValidPubkey(\"invalid\") // false\n * ```\n */\nexport function isValidPubkey(address: string): boolean {\n // Solana pubkeys are 32-44 characters in Base58\n if (address.length < 32 || address.length > 44) {\n return false;\n }\n\n // Check all characters are valid Base58\n for (const char of address) {\n if (!BASE58_ALPHABET.includes(char)) {\n return false;\n }\n }\n\n // Try to decode and verify length\n try {\n const bytes = base58Decode(address);\n return bytes.length === 32;\n } catch {\n return false;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/base58.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Base58 encoding utilities for Solana addresses\n * \n * Solana uses Base58 encoding (Bitcoin-style) for public keys and signatures.\n */\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\n/**\n * Encode bytes to Base58 string (Solana address format)\n * \n * @param bytes - Uint8Array to encode\n * @returns Base58 encoded string\n * \n * @example\n * ```typescript\n * const pubkey = new Uint8Array([1, 2, 3, ...]);\n * const address = base58Encode(pubkey);\n * // \"EPjFWdd5...\"\n * ```\n */\nexport function base58Encode(bytes: Uint8Array): string {\n const digits = [0];\n \n for (let i = 0; i < bytes.length; i++) {\n let carry = bytes[i];\n for (let j = 0; j < digits.length; j++) {\n carry += digits[j] << 8;\n digits[j] = carry % 58;\n carry = (carry / 58) | 0;\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = (carry / 58) | 0;\n }\n }\n\n // Leading zeros\n let leadingZeros = '';\n for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {\n leadingZeros += '1';\n }\n\n return leadingZeros + digits.reverse().map(d => BASE58_ALPHABET[d]).join('');\n}\n\n/**\n * Decode Base58 string to bytes\n * \n * @param str - Base58 encoded string\n * @returns Uint8Array of decoded bytes\n * @throws Error if string contains invalid characters\n * \n * @example\n * ```typescript\n * const bytes = base58Decode(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\");\n * // Uint8Array(32) [...]\n * ```\n */\nexport function base58Decode(str: string): Uint8Array {\n if (str.length === 0) {\n return new Uint8Array(0);\n }\n\n // Count leading '1's (they represent leading zero bytes)\n let leadingZeros = 0;\n for (let i = 0; i < str.length && str[i] === '1'; i++) {\n leadingZeros++;\n }\n\n // Process remaining characters through base conversion\n const bytes = [0];\n for (let i = leadingZeros; i < str.length; i++) {\n const char = str[i];\n const value = BASE58_ALPHABET.indexOf(char);\n \n if (value === -1) {\n throw new Error(`Invalid Base58 character: ${char}`);\n }\n \n let carry = value;\n for (let j = 0; j < bytes.length; j++) {\n carry += bytes[j] * 58;\n bytes[j] = carry & 0xff;\n carry >>= 8;\n }\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n\n // Build result: leading zeros + converted bytes (reversed)\n bytes.reverse();\n \n // Handle case where input was all '1's (all leading zeros, no data to convert)\n // In this case, bytes is just [0] from initialization, which we should ignore\n if (leadingZeros > 0 && bytes.length === 1 && bytes[0] === 0) {\n // Input was all '1's, return that many zero bytes\n return new Uint8Array(leadingZeros);\n }\n \n // Remove leading zero from conversion if present (artifact of starting with [0])\n const startIdx = bytes.length > 1 && bytes[0] === 0 ? 1 : 0;\n \n const result = new Uint8Array(leadingZeros + bytes.length - startIdx);\n // Fill leading zeros\n for (let i = 0; i < leadingZeros; i++) {\n result[i] = 0;\n }\n // Copy converted bytes\n for (let i = startIdx; i < bytes.length; i++) {\n result[leadingZeros + i - startIdx] = bytes[i];\n }\n \n return result;\n}\n\n/**\n * Check if a string is a valid Solana public key (Base58, 32-44 chars)\n * \n * @param address - String to validate\n * @returns true if valid Solana pubkey format\n * \n * @example\n * ```typescript\n * isValidPubkey(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\") // true\n * isValidPubkey(\"invalid\") // false\n * ```\n */\nexport function isValidPubkey(address: string): boolean {\n // Solana pubkeys are 32-44 characters in Base58\n if (address.length < 32 || address.length > 44) {\n return false;\n }\n\n // Check all characters are valid Base58\n for (const char of address) {\n if (!BASE58_ALPHABET.includes(char)) {\n return false;\n }\n }\n\n // Try to decode and verify length\n try {\n const bytes = base58Decode(address);\n return bytes.length === 32;\n } catch {\n return false;\n }\n}\n"]}
@@ -21,8 +21,15 @@ function base58Encode(bytes) {
21
21
  return leadingZeros + digits.reverse().map((d) => BASE58_ALPHABET[d]).join("");
22
22
  }
23
23
  function base58Decode(str) {
24
+ if (str.length === 0) {
25
+ return new Uint8Array(0);
26
+ }
27
+ let leadingZeros = 0;
28
+ for (let i = 0; i < str.length && str[i] === "1"; i++) {
29
+ leadingZeros++;
30
+ }
24
31
  const bytes = [0];
25
- for (let i = 0; i < str.length; i++) {
32
+ for (let i = leadingZeros; i < str.length; i++) {
26
33
  const char = str[i];
27
34
  const value = BASE58_ALPHABET.indexOf(char);
28
35
  if (value === -1) {
@@ -39,10 +46,19 @@ function base58Decode(str) {
39
46
  carry >>= 8;
40
47
  }
41
48
  }
42
- for (let i = 0; i < str.length && str[i] === "1"; i++) {
43
- bytes.push(0);
49
+ bytes.reverse();
50
+ if (leadingZeros > 0 && bytes.length === 1 && bytes[0] === 0) {
51
+ return new Uint8Array(leadingZeros);
52
+ }
53
+ const startIdx = bytes.length > 1 && bytes[0] === 0 ? 1 : 0;
54
+ const result = new Uint8Array(leadingZeros + bytes.length - startIdx);
55
+ for (let i = 0; i < leadingZeros; i++) {
56
+ result[i] = 0;
57
+ }
58
+ for (let i = startIdx; i < bytes.length; i++) {
59
+ result[leadingZeros + i - startIdx] = bytes[i];
44
60
  }
45
- return new Uint8Array(bytes.reverse());
61
+ return result;
46
62
  }
47
63
  function isValidPubkey(address) {
48
64
  if (address.length < 32 || address.length > 44) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/base58.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Base58 encoding utilities for Solana addresses\n * \n * Solana uses Base58 encoding (Bitcoin-style) for public keys and signatures.\n */\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\n/**\n * Encode bytes to Base58 string (Solana address format)\n * \n * @param bytes - Uint8Array to encode\n * @returns Base58 encoded string\n * \n * @example\n * ```typescript\n * const pubkey = new Uint8Array([1, 2, 3, ...]);\n * const address = base58Encode(pubkey);\n * // \"EPjFWdd5...\"\n * ```\n */\nexport function base58Encode(bytes: Uint8Array): string {\n const digits = [0];\n \n for (let i = 0; i < bytes.length; i++) {\n let carry = bytes[i];\n for (let j = 0; j < digits.length; j++) {\n carry += digits[j] << 8;\n digits[j] = carry % 58;\n carry = (carry / 58) | 0;\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = (carry / 58) | 0;\n }\n }\n\n // Leading zeros\n let leadingZeros = '';\n for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {\n leadingZeros += '1';\n }\n\n return leadingZeros + digits.reverse().map(d => BASE58_ALPHABET[d]).join('');\n}\n\n/**\n * Decode Base58 string to bytes\n * \n * @param str - Base58 encoded string\n * @returns Uint8Array of decoded bytes\n * @throws Error if string contains invalid characters\n * \n * @example\n * ```typescript\n * const bytes = base58Decode(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\");\n * // Uint8Array(32) [...]\n * ```\n */\nexport function base58Decode(str: string): Uint8Array {\n const bytes = [0];\n \n for (let i = 0; i < str.length; i++) {\n const char = str[i];\n const value = BASE58_ALPHABET.indexOf(char);\n \n if (value === -1) {\n throw new Error(`Invalid Base58 character: ${char}`);\n }\n \n let carry = value;\n for (let j = 0; j < bytes.length; j++) {\n carry += bytes[j] * 58;\n bytes[j] = carry & 0xff;\n carry >>= 8;\n }\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n\n // Leading '1's are leading zeros\n for (let i = 0; i < str.length && str[i] === '1'; i++) {\n bytes.push(0);\n }\n\n return new Uint8Array(bytes.reverse());\n}\n\n/**\n * Check if a string is a valid Solana public key (Base58, 32-44 chars)\n * \n * @param address - String to validate\n * @returns true if valid Solana pubkey format\n * \n * @example\n * ```typescript\n * isValidPubkey(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\") // true\n * isValidPubkey(\"invalid\") // false\n * ```\n */\nexport function isValidPubkey(address: string): boolean {\n // Solana pubkeys are 32-44 characters in Base58\n if (address.length < 32 || address.length > 44) {\n return false;\n }\n\n // Check all characters are valid Base58\n for (const char of address) {\n if (!BASE58_ALPHABET.includes(char)) {\n return false;\n }\n }\n\n // Try to decode and verify length\n try {\n const bytes = base58Decode(address);\n return bytes.length === 32;\n } catch {\n return false;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/base58.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Base58 encoding utilities for Solana addresses\n * \n * Solana uses Base58 encoding (Bitcoin-style) for public keys and signatures.\n */\n\nconst BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\n\n/**\n * Encode bytes to Base58 string (Solana address format)\n * \n * @param bytes - Uint8Array to encode\n * @returns Base58 encoded string\n * \n * @example\n * ```typescript\n * const pubkey = new Uint8Array([1, 2, 3, ...]);\n * const address = base58Encode(pubkey);\n * // \"EPjFWdd5...\"\n * ```\n */\nexport function base58Encode(bytes: Uint8Array): string {\n const digits = [0];\n \n for (let i = 0; i < bytes.length; i++) {\n let carry = bytes[i];\n for (let j = 0; j < digits.length; j++) {\n carry += digits[j] << 8;\n digits[j] = carry % 58;\n carry = (carry / 58) | 0;\n }\n while (carry > 0) {\n digits.push(carry % 58);\n carry = (carry / 58) | 0;\n }\n }\n\n // Leading zeros\n let leadingZeros = '';\n for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {\n leadingZeros += '1';\n }\n\n return leadingZeros + digits.reverse().map(d => BASE58_ALPHABET[d]).join('');\n}\n\n/**\n * Decode Base58 string to bytes\n * \n * @param str - Base58 encoded string\n * @returns Uint8Array of decoded bytes\n * @throws Error if string contains invalid characters\n * \n * @example\n * ```typescript\n * const bytes = base58Decode(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\");\n * // Uint8Array(32) [...]\n * ```\n */\nexport function base58Decode(str: string): Uint8Array {\n if (str.length === 0) {\n return new Uint8Array(0);\n }\n\n // Count leading '1's (they represent leading zero bytes)\n let leadingZeros = 0;\n for (let i = 0; i < str.length && str[i] === '1'; i++) {\n leadingZeros++;\n }\n\n // Process remaining characters through base conversion\n const bytes = [0];\n for (let i = leadingZeros; i < str.length; i++) {\n const char = str[i];\n const value = BASE58_ALPHABET.indexOf(char);\n \n if (value === -1) {\n throw new Error(`Invalid Base58 character: ${char}`);\n }\n \n let carry = value;\n for (let j = 0; j < bytes.length; j++) {\n carry += bytes[j] * 58;\n bytes[j] = carry & 0xff;\n carry >>= 8;\n }\n while (carry > 0) {\n bytes.push(carry & 0xff);\n carry >>= 8;\n }\n }\n\n // Build result: leading zeros + converted bytes (reversed)\n bytes.reverse();\n \n // Handle case where input was all '1's (all leading zeros, no data to convert)\n // In this case, bytes is just [0] from initialization, which we should ignore\n if (leadingZeros > 0 && bytes.length === 1 && bytes[0] === 0) {\n // Input was all '1's, return that many zero bytes\n return new Uint8Array(leadingZeros);\n }\n \n // Remove leading zero from conversion if present (artifact of starting with [0])\n const startIdx = bytes.length > 1 && bytes[0] === 0 ? 1 : 0;\n \n const result = new Uint8Array(leadingZeros + bytes.length - startIdx);\n // Fill leading zeros\n for (let i = 0; i < leadingZeros; i++) {\n result[i] = 0;\n }\n // Copy converted bytes\n for (let i = startIdx; i < bytes.length; i++) {\n result[leadingZeros + i - startIdx] = bytes[i];\n }\n \n return result;\n}\n\n/**\n * Check if a string is a valid Solana public key (Base58, 32-44 chars)\n * \n * @param address - String to validate\n * @returns true if valid Solana pubkey format\n * \n * @example\n * ```typescript\n * isValidPubkey(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\") // true\n * isValidPubkey(\"invalid\") // false\n * ```\n */\nexport function isValidPubkey(address: string): boolean {\n // Solana pubkeys are 32-44 characters in Base58\n if (address.length < 32 || address.length > 44) {\n return false;\n }\n\n // Check all characters are valid Base58\n for (const char of address) {\n if (!BASE58_ALPHABET.includes(char)) {\n return false;\n }\n }\n\n // Try to decode and verify length\n try {\n const bytes = base58Decode(address);\n return bytes.length === 32;\n } catch {\n return false;\n }\n}\n"]}
package/dist/ws/index.cjs CHANGED
@@ -93,55 +93,54 @@ function decodeMessage(data) {
93
93
  return { type: "error", data: { message: text } };
94
94
  }
95
95
  case MessageType.PriorityFees: {
96
- if (payload.byteLength < 24) return null;
96
+ if (payload.byteLength < 42) return null;
97
97
  const slot = Number(payloadView.getBigUint64(0, true));
98
98
  const timestampMs = Number(payloadView.getBigUint64(8, true));
99
99
  const recommended = Number(payloadView.getBigUint64(16, true));
100
- const state = payload.byteLength > 24 ? payloadView.getUint8(24) : 1;
101
- const isStale = payload.byteLength > 25 ? payloadView.getUint8(25) !== 0 : false;
102
- let swapP50 = 0, swapP75 = 0, swapP90 = 0, swapP99 = 0;
103
- if (payload.byteLength >= 58) {
104
- swapP50 = Number(payloadView.getBigUint64(26, true));
105
- swapP75 = Number(payloadView.getBigUint64(34, true));
106
- swapP90 = Number(payloadView.getBigUint64(42, true));
107
- swapP99 = Number(payloadView.getBigUint64(50, true));
108
- }
109
- let swapSamples = 0;
110
- let landingP50Fee = 0, landingP75Fee = 0, landingP90Fee = 0, landingP99Fee = 0;
111
- let top10Fee = 0, top25Fee = 0;
112
- let spikeDetected = false, spikeFee = 0;
113
- if (payload.byteLength >= 119) {
114
- swapSamples = payloadView.getUint32(58, true);
115
- landingP50Fee = Number(payloadView.getBigUint64(62, true));
116
- landingP75Fee = Number(payloadView.getBigUint64(70, true));
117
- landingP90Fee = Number(payloadView.getBigUint64(78, true));
118
- landingP99Fee = Number(payloadView.getBigUint64(86, true));
119
- top10Fee = Number(payloadView.getBigUint64(94, true));
120
- top25Fee = Number(payloadView.getBigUint64(102, true));
121
- spikeDetected = payloadView.getUint8(110) !== 0;
122
- spikeFee = Number(payloadView.getBigUint64(111, true));
100
+ const state = payloadView.getUint8(24);
101
+ const isStale = payloadView.getUint8(25) !== 0;
102
+ const blockUtilizationPct = payloadView.getFloat32(26, true);
103
+ const blocksInWindow = payloadView.getUint32(30, true);
104
+ const accountCount = Number(payloadView.getBigUint64(34, true));
105
+ const accounts = [];
106
+ let offset = 42;
107
+ for (let i = 0; i < accountCount && offset + 92 <= payload.byteLength; i++) {
108
+ const pubkeyBytes = new Uint8Array(payload, offset, 32);
109
+ const pubkey = base58Encode(pubkeyBytes);
110
+ const totalTxs = payloadView.getUint32(offset + 32, true);
111
+ const activeSlots = payloadView.getUint32(offset + 36, true);
112
+ const cuConsumed = Number(payloadView.getBigUint64(offset + 40, true));
113
+ const utilizationPct = payloadView.getFloat32(offset + 48, true);
114
+ const p25 = Number(payloadView.getBigUint64(offset + 52, true));
115
+ const p50 = Number(payloadView.getBigUint64(offset + 60, true));
116
+ const p75 = Number(payloadView.getBigUint64(offset + 68, true));
117
+ const p90 = Number(payloadView.getBigUint64(offset + 76, true));
118
+ const minNonzeroPrice = Number(payloadView.getBigUint64(offset + 84, true));
119
+ accounts.push({
120
+ pubkey,
121
+ totalTxs,
122
+ activeSlots,
123
+ cuConsumed,
124
+ utilizationPct,
125
+ p25,
126
+ p50,
127
+ p75,
128
+ p90,
129
+ minNonzeroPrice
130
+ });
131
+ offset += 92;
123
132
  }
124
133
  return {
125
- type: "priority_fees",
134
+ type: "fee_market",
126
135
  data: {
127
136
  slot,
128
137
  timestampMs,
129
138
  recommended,
130
139
  state,
131
140
  isStale,
132
- swapP50,
133
- swapP75,
134
- swapP90,
135
- swapP99,
136
- swapSamples,
137
- landingP50Fee,
138
- landingP75Fee,
139
- landingP90Fee,
140
- landingP99Fee,
141
- top10Fee,
142
- top25Fee,
143
- spikeDetected,
144
- spikeFee
141
+ blockUtilizationPct,
142
+ blocksInWindow,
143
+ accounts
145
144
  }
146
145
  };
147
146
  }
@@ -253,8 +252,6 @@ function decodePoolUpdate(payload, payloadView) {
253
252
  tokenDecimals.push(payloadView.getInt32(offset, true));
254
253
  offset += 4;
255
254
  }
256
- const isValid = offset < payload.byteLength ? payloadView.getUint8(offset) !== 0 : true;
257
- offset += 1;
258
255
  return {
259
256
  type: "pool_update",
260
257
  data: {
@@ -265,25 +262,11 @@ function decodePoolUpdate(payload, payloadView) {
265
262
  poolAddress: base58Encode(poolAddr),
266
263
  tokenMints,
267
264
  tokenBalances,
268
- tokenDecimals,
269
- isValid
265
+ tokenDecimals
270
266
  }
271
267
  };
272
268
  } catch {
273
- return {
274
- type: "pool_update",
275
- data: {
276
- sequence: 0,
277
- slot: 0,
278
- writeVersion: 0,
279
- protocol: "unknown",
280
- poolAddress: "",
281
- tokenMints: [],
282
- tokenBalances: [],
283
- tokenDecimals: [],
284
- isValid: false
285
- }
286
- };
269
+ return null;
287
270
  }
288
271
  }
289
272
  function decodeQuote(payload, payloadView) {
@@ -354,25 +337,7 @@ function decodeQuote(payload, payloadView) {
354
337
  }
355
338
  };
356
339
  } catch {
357
- return {
358
- type: "quote",
359
- data: {
360
- topicId: "",
361
- timestampMs: 0,
362
- sequence: 0,
363
- inputMint: "",
364
- outputMint: "",
365
- inAmount: "0",
366
- outAmount: "0",
367
- priceImpactBps: 0,
368
- contextSlot: 0,
369
- algorithm: "",
370
- isImprovement: false,
371
- isCached: false,
372
- isStale: false,
373
- routePlan: null
374
- }
375
- };
340
+ return null;
376
341
  }
377
342
  }
378
343
 
@@ -674,8 +639,8 @@ var K256WebSocketClient = class {
674
639
  case "pool_update":
675
640
  this.config.onPoolUpdate?.(decoded);
676
641
  break;
677
- case "priority_fees":
678
- this.config.onPriorityFees?.(decoded);
642
+ case "fee_market":
643
+ this.config.onFeeMarket?.(decoded);
679
644
  break;
680
645
  case "blockhash":
681
646
  this.config.onBlockhash?.(decoded);