Skip to content

Commit

Permalink
start adding ts changes
Browse files Browse the repository at this point in the history
  • Loading branch information
crispheaney committed Nov 26, 2024
1 parent 35f943d commit 9bf508f
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 49 deletions.
80 changes: 48 additions & 32 deletions sdk/src/accounts/pollingDriftClientAccountSubscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
SpotMarketAccount,
StateAccount,
UserAccount,
OracleSource,
} from '../types';
import {
getDriftStateAccountPublicKey,
Expand All @@ -28,8 +29,12 @@ import { OracleInfo, OraclePriceData } from '../oracles/types';
import { OracleClientCache } from '../oracles/oracleClientCache';
import { QUOTE_ORACLE_PRICE_DATA } from '../oracles/quoteAssetOracleClient';
import { findAllMarketAndOracles } from '../config';
import { getOracleId } from '../oracles/oracleId';

const ORACLE_DEFAULT_KEY = PublicKey.default.toBase58();
const ORACLE_DEFAULT_ID = getOracleId(
PublicKey.default,
OracleSource.QUOTE_ASSET
);

export class PollingDriftClientAccountSubscriber
implements DriftClientAccountSubscriber
Expand Down Expand Up @@ -217,10 +222,13 @@ export class PollingDriftClientAccountSubscriber
}

addOracleToPoll(oracleInfo: OracleInfo): boolean {
this.oraclesToPoll.set(oracleInfo.publicKey.toString(), {
publicKey: oracleInfo.publicKey,
source: oracleInfo.source,
});
this.oraclesToPoll.set(
getOracleId(oracleInfo.publicKey, oracleInfo.source),
{
publicKey: oracleInfo.publicKey,
source: oracleInfo.source,
}
);

return true;
}
Expand Down Expand Up @@ -279,6 +287,8 @@ export class PollingDriftClientAccountSubscriber
this.program
);

const oracleId = getOracleId(oracleToPoll.publicKey, oracleToPoll.source);

oracleToPoll.callbackId = await this.accountLoader.addAccount(
oracleToPoll.publicKey,
(buffer: Buffer, slot: number) => {
Expand All @@ -291,11 +301,12 @@ export class PollingDriftClientAccountSubscriber
slot,
};

this.oracles.set(oracleToPoll.publicKey.toString(), dataAndSlot);
this.oracles.set(oracleId, dataAndSlot);

this.eventEmitter.emit(
'oraclePriceUpdate',
oracleToPoll.publicKey,
oracleToPoll.source,
oraclePriceData
);
this.eventEmitter.emit('update');
Expand Down Expand Up @@ -353,9 +364,11 @@ export class PollingDriftClientAccountSubscriber
);
const oraclePriceData =
oracleClient.getOraclePriceDataFromBuffer(buffer);
this.oracles.set(oracleToPoll.publicKey.toString(), {
data: oraclePriceData,
slot,
this.oracles.set(
getOracleId(oracleToPoll.publicKey, oracleToPoll.source),
{
data: oraclePriceData,
slot,
});
}
}
Expand Down Expand Up @@ -427,23 +440,23 @@ export class PollingDriftClientAccountSubscriber
}

async addOracle(oracleInfo: OracleInfo): Promise<boolean> {
const oracleId = getOracleId(oracleInfo.publicKey, oracleInfo.source);
if (
oracleInfo.publicKey.equals(PublicKey.default) ||
this.oracles.has(oracleInfo.publicKey.toBase58())
this.oracles.has(oracleId)
) {
return true;
}

const oracleString = oracleInfo.publicKey.toBase58();
// this func can be called multiple times before the first pauseForOracleToBeAdded finishes
// avoid adding to oraclesToPoll multiple time
if (!this.oraclesToPoll.has(oracleString)) {
if (!this.oraclesToPoll.has(oracleId)) {
this.addOracleToPoll(oracleInfo);
const oracleToPoll = this.oraclesToPoll.get(oracleString);
const oracleToPoll = this.oraclesToPoll.get(oracleId);
await this.addOracleToAccountLoader(oracleToPoll);
}

await this.pauseForOracleToBeAdded(3, oracleString);
await this.pauseForOracleToBeAdded(3, oracleInfo.publicKey.toBase58());

return true;
}
Expand All @@ -464,14 +477,16 @@ export class PollingDriftClientAccountSubscriber
}
console.log(`Pausing to find oracle ${oracle} failed`);
}

async setPerpOracleMap() {
const perpMarkets = this.getMarketAccountsAndSlots();
const oraclePromises = [];
for (const perpMarket of perpMarkets) {
const perpMarketAccount = perpMarket.data;
const perpMarketIndex = perpMarketAccount.marketIndex;
const oracle = perpMarketAccount.amm.oracle;
if (!this.oracles.has(oracle.toBase58())) {
const oracleId = getOracleId(oracle, perpMarketAccount.amm.oracleSource);
if (!this.oracles.has(oracleId)) {
oraclePromises.push(
this.addOracle({
publicKey: oracle,
Expand All @@ -480,7 +495,10 @@ export class PollingDriftClientAccountSubscriber
);
}
this.perpOracleMap.set(perpMarketIndex, oracle);
this.perpOracleStringMap.set(perpMarketIndex, oracle.toBase58());
this.perpOracleStringMap.set(
perpMarketIndex,
oracleId
);
}
await Promise.all(oraclePromises);
}
Expand All @@ -492,7 +510,8 @@ export class PollingDriftClientAccountSubscriber
const spotMarketAccount = spotMarket.data;
const spotMarketIndex = spotMarketAccount.marketIndex;
const oracle = spotMarketAccount.oracle;
if (!this.oracles.has(oracle.toBase58())) {
const oracleId = getOracleId(oracle, spotMarketAccount.oracleSource);
if (!this.oracles.has(oracleId)) {
oraclePromises.push(
this.addOracle({
publicKey: oracle,
Expand All @@ -501,7 +520,7 @@ export class PollingDriftClientAccountSubscriber
);
}
this.spotOracleMap.set(spotMarketIndex, oracle);
this.spotOracleStringMap.set(spotMarketIndex, oracle.toBase58());
this.spotOracleStringMap.set(spotMarketIndex, oracleId);
}
await Promise.all(oraclePromises);
}
Expand All @@ -528,10 +547,11 @@ export class PollingDriftClientAccountSubscriber
}

for (const oracle of oracles) {
const callbackId = this.oraclesToPoll.get(oracle.toBase58()).callbackId;
this.accountLoader.removeAccount(oracle, callbackId);
const oracleId = getOracleId(oracle.publicKey, oracle.source);
const callbackId = this.oraclesToPoll.get(oracleId).callbackId;
this.accountLoader.removeAccount(oracle.publicKey, callbackId);
if (this.delistedMarketSetting === DelistedMarketSetting.Discard) {
this.oracles.delete(oracle.toBase58());
this.oracles.delete(oracleId);
}
}
}
Expand Down Expand Up @@ -570,29 +590,25 @@ export class PollingDriftClientAccountSubscriber
}

public getOraclePriceDataAndSlot(
oraclePublicKey: PublicKey | string
oracleId: string
): DataAndSlot<OraclePriceData> | undefined {
this.assertIsSubscribed();
const oracleString =
typeof oraclePublicKey === 'string'
? oraclePublicKey
: oraclePublicKey.toBase58();
if (oracleString === ORACLE_DEFAULT_KEY) {
if (oracleId === ORACLE_DEFAULT_ID) {
return {
data: QUOTE_ORACLE_PRICE_DATA,
slot: 0,
};
}

return this.oracles.get(oracleString);
return this.oracles.get(oracleId);
}

public getOraclePriceDataAndSlotForPerpMarket(
marketIndex: number
): DataAndSlot<OraclePriceData> | undefined {
const perpMarketAccount = this.getMarketAccountAndSlot(marketIndex);
const oracle = this.perpOracleMap.get(marketIndex);
const oracleString = this.perpOracleStringMap.get(marketIndex);
const oracleId = this.perpOracleStringMap.get(marketIndex);

if (!perpMarketAccount || !oracle) {
return undefined;
Expand All @@ -603,15 +619,15 @@ export class PollingDriftClientAccountSubscriber
this.setPerpOracleMap();
}

return this.getOraclePriceDataAndSlot(oracleString);
return this.getOraclePriceDataAndSlot(oracleId);
}

public getOraclePriceDataAndSlotForSpotMarket(
marketIndex: number
): DataAndSlot<OraclePriceData> | undefined {
const spotMarketAccount = this.getSpotMarketAccountAndSlot(marketIndex);
const oracle = this.spotOracleMap.get(marketIndex);
const oracleString = this.spotOracleStringMap.get(marketIndex);
const oracleId = this.spotOracleStringMap.get(marketIndex);
if (!spotMarketAccount || !oracle) {
return undefined;
}
Expand All @@ -621,7 +637,7 @@ export class PollingDriftClientAccountSubscriber
this.setSpotOracleMap();
}

return this.getOraclePriceDataAndSlot(oracleString);
return this.getOraclePriceDataAndSlot(oracleId);
}

public updateAccountLoaderPollingFrequency(pollingFrequency: number): void {
Expand Down
8 changes: 6 additions & 2 deletions sdk/src/accounts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ export interface DriftClientAccountEvents {
stateAccountUpdate: (payload: StateAccount) => void;
perpMarketAccountUpdate: (payload: PerpMarketAccount) => void;
spotMarketAccountUpdate: (payload: SpotMarketAccount) => void;
oraclePriceUpdate: (publicKey: PublicKey, data: OraclePriceData) => void;
oraclePriceUpdate: (
publicKey: PublicKey,
oracleSource: OracleSource,
data: OraclePriceData
) => void;
userAccountUpdate: (payload: UserAccount) => void;
update: void;
error: (e: Error) => void;
Expand Down Expand Up @@ -73,7 +77,7 @@ export interface DriftClientAccountSubscriber {
): DataAndSlot<SpotMarketAccount> | undefined;
getSpotMarketAccountsAndSlots(): DataAndSlot<SpotMarketAccount>[];
getOraclePriceDataAndSlot(
oraclePublicKey: PublicKey | string
oracleId: string
): DataAndSlot<OraclePriceData> | undefined;
getOraclePriceDataAndSlotForPerpMarket(
marketIndex: number
Expand Down
12 changes: 8 additions & 4 deletions sdk/src/accounts/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { PublicKey } from '@solana/web3.js';

Check failure on line 1 in sdk/src/accounts/utils.ts

View workflow job for this annotation

GitHub Actions / yarn-lint

'PublicKey' is defined but never used. Allowed unused vars must match /^_/u
import { DataAndSlot } from './types';
import { isVariant, PerpMarketAccount, SpotMarketAccount } from '../types';
import { OracleInfo } from '../oracles/types';

export function capitalize(value: string): string {
return value[0].toUpperCase() + value.slice(1);
Expand All @@ -9,17 +10,20 @@ export function capitalize(value: string): string {
export function findDelistedPerpMarketsAndOracles(
perpMarkets: DataAndSlot<PerpMarketAccount>[],
spotMarkets: DataAndSlot<SpotMarketAccount>[]
): { perpMarketIndexes: number[]; oracles: PublicKey[] } {
): { perpMarketIndexes: number[]; oracles: OracleInfo[] } {
const delistedPerpMarketIndexes = [];
const delistedOracles = [];
const delistedOracles: OracleInfo[] = [];
for (const perpMarket of perpMarkets) {
if (!perpMarket.data) {
continue;
}

if (isVariant(perpMarket.data.status, 'delisted')) {
delistedPerpMarketIndexes.push(perpMarket.data.marketIndex);
delistedOracles.push(perpMarket.data.amm.oracle);
delistedOracles.push({
publicKey: perpMarket.data.amm.oracle,
source: perpMarket.data.amm.oracleSource,
});
}
}

Expand All @@ -31,7 +35,7 @@ export function findDelistedPerpMarketsAndOracles(
continue;
}

if (spotMarket.data.oracle.equals(delistedOracle)) {
if (spotMarket.data.oracle.equals(delistedOracle.publicKey)) {
break;
}
}
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/accounts/webSocketDriftClientAccountSubscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,9 +508,9 @@ export class WebSocketDriftClientAccountSubscriber
}

for (const oracle of oracles) {
await this.oracleSubscribers.get(oracle.toBase58()).unsubscribe();
await this.oracleSubscribers.get(oracle.publicKey.toBase58()).unsubscribe();
if (this.delistedMarketSetting === DelistedMarketSetting.Discard) {
this.oracleSubscribers.delete(oracle.toBase58());
this.oracleSubscribers.delete(oracle.publicKey.toBase58());
}
}
}
Expand Down
18 changes: 11 additions & 7 deletions sdk/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
ON_DEMAND_DEVNET_PID,
ON_DEMAND_MAINNET_PID,
} from '@switchboard-xyz/on-demand';
import { getOracleId } from './oracles/oracleId';

type DriftConfig = {
ENV: DriftEnv;
Expand Down Expand Up @@ -134,15 +135,15 @@ export function getMarketsAndOraclesForSubscription(

for (const market of perpMarketsToUse) {
perpMarketIndexes.push(market.marketIndex);
oracleInfos.set(market.oracle.toString(), {
oracleInfos.set(getOracleId(market.oracle, market.oracleSource), {
publicKey: market.oracle,
source: market.oracleSource,
});
}

for (const spotMarket of spotMarketsToUse) {
spotMarketIndexes.push(spotMarket.marketIndex);
oracleInfos.set(spotMarket.oracle.toString(), {
oracleInfos.set(getOracleId(spotMarket.oracle, spotMarket.oracleSource), {
publicKey: spotMarket.oracle,
source: spotMarket.oracleSource,
});
Expand Down Expand Up @@ -174,16 +175,19 @@ export async function findAllMarketAndOracles(program: Program): Promise<{
for (const perpMarketProgramAccount of perpMarketProgramAccounts) {
const perpMarket = perpMarketProgramAccount.account as PerpMarketAccount;
perpMarketIndexes.push(perpMarket.marketIndex);
oracleInfos.set(perpMarket.amm.oracle.toString(), {
publicKey: perpMarket.amm.oracle,
source: perpMarket.amm.oracleSource,
});
oracleInfos.set(
getOracleId(perpMarket.amm.oracle, perpMarket.amm.oracleSource),
{
publicKey: perpMarket.amm.oracle,
source: perpMarket.amm.oracleSource,
}
);
}

for (const spotMarketProgramAccount of spotMarketProgramAccounts) {
const spotMarket = spotMarketProgramAccount.account as SpotMarketAccount;
spotMarketIndexes.push(spotMarket.marketIndex);
oracleInfos.set(spotMarket.oracle.toString(), {
oracleInfos.set(getOracleId(spotMarket.oracle, spotMarket.oracleSource), {
publicKey: spotMarket.oracle,
source: spotMarket.oracleSource,
});
Expand Down
7 changes: 5 additions & 2 deletions sdk/src/driftClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
ModifyOrderPolicy,
OpenbookV2FulfillmentConfigAccount,
OptionalOrderParams,
OracleSource,
Order,
OrderParams,
OrderTriggerCondition,
Expand Down Expand Up @@ -175,6 +176,7 @@ import { gprcDriftClientAccountSubscriber } from './accounts/grpcDriftClientAcco
import nacl from 'tweetnacl';
import { digest } from './util/digest';
import { Slothash } from './slot/SlothashSubscriber';
import { getOracleId } from './oracles/oracleId';

type RemainingAccountParams = {
userAccounts: UserAccount[];
Expand Down Expand Up @@ -600,10 +602,11 @@ export class DriftClient {
}

public getOraclePriceDataAndSlot(
oraclePublicKey: PublicKey
oraclePublicKey: PublicKey,
oracleSource: OracleSource,
): DataAndSlot<OraclePriceData> | undefined {
return this.accountSubscriber.getOraclePriceDataAndSlot(
oraclePublicKey.toBase58()
getOracleId(oraclePublicKey, oracleSource)
);
}

Expand Down
Loading

0 comments on commit 9bf508f

Please sign in to comment.