fix: Improve enum handling robustness in discover-drift-markets script
Co-authored-by: mindesbunister <32161838+mindesbunister@users.noreply.github.com>
This commit is contained in:
@@ -11,7 +11,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { initializeDriftService, getDriftService } from '../lib/drift/client'
|
import { initializeDriftService, getDriftService } from '../lib/drift/client'
|
||||||
import { OracleSource } from '@drift-labs/sdk'
|
|
||||||
|
|
||||||
// Helper to decode market name from bytes (Drift stores names as 32-byte arrays)
|
// Helper to decode market name from bytes (Drift stores names as 32-byte arrays)
|
||||||
function decodeMarketName(nameBytes: number[] | Uint8Array | undefined): string {
|
function decodeMarketName(nameBytes: number[] | Uint8Array | undefined): string {
|
||||||
@@ -23,27 +22,87 @@ function decodeMarketName(nameBytes: number[] | Uint8Array | undefined): string
|
|||||||
return name.trim()
|
return name.trim()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map oracle source enum to human-readable string
|
/**
|
||||||
function getOracleSourceName(oracleSource: OracleSource | number): string {
|
* Extract numeric value from Anchor-style enum objects
|
||||||
// OracleSource enum values from Drift SDK
|
*
|
||||||
const sourceMap: Record<number, string> = {
|
* Drift SDK uses Anchor which represents enums as objects like:
|
||||||
0: 'Pyth',
|
* - { pyth: {} } for OracleSource.Pyth
|
||||||
1: 'Switchboard',
|
* - { active: {} } for MarketStatus.Active
|
||||||
2: 'QuoteAsset',
|
*
|
||||||
3: 'Pyth1K',
|
* This helper safely extracts the key name and maps it to a numeric index,
|
||||||
4: 'Pyth1M',
|
* or handles direct numeric values for backwards compatibility.
|
||||||
5: 'PythStableCoin',
|
*
|
||||||
6: 'Prelaunch',
|
* @param enumValue - The enum value (object or number)
|
||||||
7: 'PythPull',
|
* @param keyMap - Map of enum key names to their string representations
|
||||||
8: 'Pyth1KPull',
|
* @returns The string representation of the enum value
|
||||||
9: 'Pyth1MPull',
|
*/
|
||||||
10: 'PythStableCoinPull',
|
function getEnumName<T extends Record<string, string>>(
|
||||||
11: 'SwitchboardOnDemand',
|
enumValue: unknown,
|
||||||
|
keyMap: T
|
||||||
|
): string {
|
||||||
|
// Handle null/undefined
|
||||||
|
if (enumValue === null || enumValue === undefined) {
|
||||||
|
return 'Unknown'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle both enum and number types
|
// Handle direct numeric values (legacy support)
|
||||||
const sourceValue = typeof oracleSource === 'number' ? oracleSource : Object.values(oracleSource)[0]
|
if (typeof enumValue === 'number') {
|
||||||
return sourceMap[sourceValue as number] || `Unknown(${sourceValue})`
|
const values = Object.values(keyMap)
|
||||||
|
return values[enumValue] || `Unknown(${enumValue})`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle Anchor-style enum objects like { pyth: {} } or { active: {} }
|
||||||
|
if (typeof enumValue === 'object') {
|
||||||
|
const keys = Object.keys(enumValue as object)
|
||||||
|
if (keys.length === 1) {
|
||||||
|
const key = keys[0].toLowerCase()
|
||||||
|
// Find matching key in keyMap (case-insensitive)
|
||||||
|
for (const [mapKey, mapValue] of Object.entries(keyMap)) {
|
||||||
|
if (mapKey.toLowerCase() === key) {
|
||||||
|
return mapValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Return the key name capitalized if no map match
|
||||||
|
return keys[0].charAt(0).toUpperCase() + keys[0].slice(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return `Unknown(${JSON.stringify(enumValue)})`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Oracle source name mappings (Anchor enum key to display name)
|
||||||
|
const ORACLE_SOURCE_MAP: Record<string, string> = {
|
||||||
|
pyth: 'Pyth',
|
||||||
|
switchboard: 'Switchboard',
|
||||||
|
quoteAsset: 'QuoteAsset',
|
||||||
|
pyth1K: 'Pyth1K',
|
||||||
|
pyth1M: 'Pyth1M',
|
||||||
|
pythStableCoin: 'PythStableCoin',
|
||||||
|
prelaunch: 'Prelaunch',
|
||||||
|
pythPull: 'PythPull',
|
||||||
|
pyth1KPull: 'Pyth1KPull',
|
||||||
|
pyth1MPull: 'Pyth1MPull',
|
||||||
|
pythStableCoinPull: 'PythStableCoinPull',
|
||||||
|
switchboardOnDemand: 'SwitchboardOnDemand',
|
||||||
|
}
|
||||||
|
|
||||||
|
// Market status name mappings
|
||||||
|
const MARKET_STATUS_MAP: Record<string, string> = {
|
||||||
|
initialized: 'Initialized',
|
||||||
|
active: 'Active',
|
||||||
|
fundingPaused: 'FundingPaused',
|
||||||
|
ammPaused: 'AmmPaused',
|
||||||
|
fillPaused: 'FillPaused',
|
||||||
|
withdrawPaused: 'WithdrawPaused',
|
||||||
|
reduceOnly: 'ReduceOnly',
|
||||||
|
settlement: 'Settlement',
|
||||||
|
delisted: 'Delisted',
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contract type name mappings
|
||||||
|
const CONTRACT_TYPE_MAP: Record<string, string> = {
|
||||||
|
perpetual: 'Perpetual',
|
||||||
|
future: 'Future',
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format number with appropriate decimals
|
// Format number with appropriate decimals
|
||||||
@@ -137,31 +196,16 @@ async function discoverMarkets(searchSymbol?: string): Promise<void> {
|
|||||||
? Number(market.imfFactor) / 1e6
|
? Number(market.imfFactor) / 1e6
|
||||||
: 0
|
: 0
|
||||||
|
|
||||||
// Market status
|
// Market status - use robust enum extraction
|
||||||
const statusMap: Record<number, string> = {
|
const status = getEnumName(market.status, MARKET_STATUS_MAP)
|
||||||
0: 'Initialized',
|
|
||||||
1: 'Active',
|
|
||||||
2: 'FundingPaused',
|
|
||||||
3: 'AmmPaused',
|
|
||||||
4: 'FillPaused',
|
|
||||||
5: 'WithdrawPaused',
|
|
||||||
6: 'ReduceOnly',
|
|
||||||
7: 'Settlement',
|
|
||||||
8: 'Delisted',
|
|
||||||
}
|
|
||||||
const status = statusMap[Object.values(market.status)[0] as number] || 'Unknown'
|
|
||||||
|
|
||||||
// Contract type
|
// Contract type - use robust enum extraction
|
||||||
const contractTypeMap: Record<number, string> = {
|
const contractType = getEnumName(market.contractType, CONTRACT_TYPE_MAP)
|
||||||
0: 'Perpetual',
|
|
||||||
1: 'Future',
|
|
||||||
}
|
|
||||||
const contractType = contractTypeMap[Object.values(market.contractType)[0] as number] || 'Unknown'
|
|
||||||
|
|
||||||
const marketInfo: MarketInfo = {
|
const marketInfo: MarketInfo = {
|
||||||
index: i,
|
index: i,
|
||||||
symbol,
|
symbol,
|
||||||
oracleSource: getOracleSourceName(oracleSource),
|
oracleSource: getEnumName(oracleSource, ORACLE_SOURCE_MAP),
|
||||||
minOrderSize,
|
minOrderSize,
|
||||||
orderStepSize,
|
orderStepSize,
|
||||||
tickSize,
|
tickSize,
|
||||||
|
|||||||
Reference in New Issue
Block a user