@k256/sdk 0.1.6 → 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":";;;AAoIO,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 * 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"]}
@@ -100,24 +100,58 @@ interface RoutePlanStep {
100
100
  percent: number;
101
101
  }
102
102
  /**
103
- * 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.
104
137
  */
105
- interface PriorityFees {
138
+ interface FeeMarket {
106
139
  /** Current slot */
107
140
  slot: number;
108
141
  /** Timestamp in milliseconds */
109
142
  timestampMs: number;
110
- /** Recommended fee in microlamports */
143
+ /** Recommended fee in microlamports/CU (max p75 across hottest accounts) */
111
144
  recommended: number;
112
- /** Network state (0=low, 1=normal, 2=high, 3=congested) */
145
+ /** Network state (0=low, 1=normal, 2=high, 3=extreme) */
113
146
  state: NetworkState;
114
147
  /** Whether data is stale */
115
148
  isStale: boolean;
116
- /** Swap fee percentiles */
117
- swapP50: number;
118
- swapP75: number;
119
- swapP90: number;
120
- 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[];
121
155
  }
122
156
  /**
123
157
  * Network congestion state
@@ -197,4 +231,4 @@ interface SubscribeQuoteRequest {
197
231
  refreshIntervalMs?: number;
198
232
  }
199
233
 
200
- 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 };
@@ -100,24 +100,58 @@ interface RoutePlanStep {
100
100
  percent: number;
101
101
  }
102
102
  /**
103
- * 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.
104
137
  */
105
- interface PriorityFees {
138
+ interface FeeMarket {
106
139
  /** Current slot */
107
140
  slot: number;
108
141
  /** Timestamp in milliseconds */
109
142
  timestampMs: number;
110
- /** Recommended fee in microlamports */
143
+ /** Recommended fee in microlamports/CU (max p75 across hottest accounts) */
111
144
  recommended: number;
112
- /** Network state (0=low, 1=normal, 2=high, 3=congested) */
145
+ /** Network state (0=low, 1=normal, 2=high, 3=extreme) */
113
146
  state: NetworkState;
114
147
  /** Whether data is stale */
115
148
  isStale: boolean;
116
- /** Swap fee percentiles */
117
- swapP50: number;
118
- swapP75: number;
119
- swapP90: number;
120
- 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[];
121
155
  }
122
156
  /**
123
157
  * Network congestion state
@@ -197,4 +231,4 @@ interface SubscribeQuoteRequest {
197
231
  refreshIntervalMs?: number;
198
232
  }
199
233
 
200
- 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":";AAoIO,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 * 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
  }
@@ -267,19 +266,7 @@ function decodePoolUpdate(payload, payloadView) {
267
266
  }
268
267
  };
269
268
  } catch {
270
- return {
271
- type: "pool_update",
272
- data: {
273
- sequence: 0,
274
- slot: 0,
275
- writeVersion: 0,
276
- protocol: "unknown",
277
- poolAddress: "",
278
- tokenMints: [],
279
- tokenBalances: [],
280
- tokenDecimals: []
281
- }
282
- };
269
+ return null;
283
270
  }
284
271
  }
285
272
  function decodeQuote(payload, payloadView) {
@@ -350,25 +337,7 @@ function decodeQuote(payload, payloadView) {
350
337
  }
351
338
  };
352
339
  } catch {
353
- return {
354
- type: "quote",
355
- data: {
356
- topicId: "",
357
- timestampMs: 0,
358
- sequence: 0,
359
- inputMint: "",
360
- outputMint: "",
361
- inAmount: "0",
362
- outAmount: "0",
363
- priceImpactBps: 0,
364
- contextSlot: 0,
365
- algorithm: "",
366
- isImprovement: false,
367
- isCached: false,
368
- isStale: false,
369
- routePlan: null
370
- }
371
- };
340
+ return null;
372
341
  }
373
342
  }
374
343
 
@@ -670,8 +639,8 @@ var K256WebSocketClient = class {
670
639
  case "pool_update":
671
640
  this.config.onPoolUpdate?.(decoded);
672
641
  break;
673
- case "priority_fees":
674
- this.config.onPriorityFees?.(decoded);
642
+ case "fee_market":
643
+ this.config.onFeeMarket?.(decoded);
675
644
  break;
676
645
  case "blockhash":
677
646
  this.config.onBlockhash?.(decoded);