@haven-fi/solauto-sdk 1.0.687 → 1.0.688
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.
- package/dist/services/transactions/manager/clientTransactionsManager.js +2 -2
- package/dist/services/transactions/manager/transactionsManager.js +3 -1
- package/dist/utils/generalUtils.d.ts +1 -0
- package/dist/utils/generalUtils.d.ts.map +1 -1
- package/dist/utils/generalUtils.js +4 -0
- package/dist/utils/priceUtils.d.ts +3 -3
- package/dist/utils/priceUtils.d.ts.map +1 -1
- package/dist/utils/priceUtils.js +43 -47
- package/package.json +1 -1
- package/src/services/transactions/manager/clientTransactionsManager.ts +3 -3
- package/src/services/transactions/manager/transactionsManager.ts +3 -3
- package/src/utils/generalUtils.ts +13 -2
- package/src/utils/priceUtils.ts +62 -72
@@ -25,8 +25,8 @@ class ClientTransactionsManager extends transactionsManager_1.TransactionsManage
|
|
25
25
|
];
|
26
26
|
if (txs.find((x) => x.oracleInteractor) && switchboardMints.length) {
|
27
27
|
this.txHandler.log("Requires oracle update(s)...");
|
28
|
-
const
|
29
|
-
txs.unshift(...
|
28
|
+
const oracleTxs = switchboardMints.map((x) => new types_1.TransactionItem(async () => await (0, utils_1.buildSwbSubmitResponseTx)(this.txHandler.connection, this.txHandler.signer, x), this.updateOracleTxName));
|
29
|
+
txs.unshift(...oracleTxs);
|
30
30
|
}
|
31
31
|
}
|
32
32
|
async addChoreTxs(txs, updateLutTx) {
|
@@ -260,7 +260,9 @@ class TransactionsManager {
|
|
260
260
|
}
|
261
261
|
else {
|
262
262
|
await Promise.all(itemSets.map((itemSet) => itemSet.reset()));
|
263
|
-
|
263
|
+
for (const itemSet of itemSets) {
|
264
|
+
await itemSet.refetchAll(attemptNum, prevError);
|
265
|
+
}
|
264
266
|
}
|
265
267
|
const newItemSets = await this.assembleTransactionSets(currentIndex !== undefined
|
266
268
|
? [
|
@@ -21,4 +21,5 @@ export declare function toEnumValue<E extends object>(enumObj: E, value: number)
|
|
21
21
|
export declare function customRpcCall(umi: Umi, method: string, params?: any): Promise<any>;
|
22
22
|
export declare function u16ToArrayBufferLE(value: number): Uint8Array;
|
23
23
|
export declare function validPubkey(pubkey?: PublicKey | UmiPublicKey | string): boolean;
|
24
|
+
export declare function createRecord<T>(keys: string[], values: T[]): Record<string, T>;
|
24
25
|
//# sourceMappingURL=generalUtils.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../src/utils/generalUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,
|
1
|
+
{"version":3,"file":"generalUtils.d.ts","sourceRoot":"","sources":["../../src/utils/generalUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,eAAe,EAEf,GAAG,EACH,SAAS,IAAI,YAAY,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAc,SAAS,EAAE,MAAM,cAAc,CAAC;AAErD,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,UAErD;AAED,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,UAE3D;AAED,wBAAgB,UAAU,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAI/C;AAED,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAErD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAW1D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,yBAQ/C;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAMlE;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAO1C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,GAAG,EACR,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC,OAAO,CAAC,CAKlB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAEnE;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAU1E;AAED,wBAAgB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAS1D;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,CAAC,CAAC;AAEjE,wBAAgB,2BAA2B,CAAC,CAAC,EAC3C,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EACvD,OAAO,GAAE,MAAU,EACnB,KAAK,GAAE,MAAY,EACnB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,CAAC,CAAC,CA8BZ;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC1C,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,MAAM,GACZ,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAUxB;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,gBAuBzE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAU5D;AAED,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,WAErE;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAI9E"}
|
@@ -22,6 +22,7 @@ exports.toEnumValue = toEnumValue;
|
|
22
22
|
exports.customRpcCall = customRpcCall;
|
23
23
|
exports.u16ToArrayBufferLE = u16ToArrayBufferLE;
|
24
24
|
exports.validPubkey = validPubkey;
|
25
|
+
exports.createRecord = createRecord;
|
25
26
|
const axios_1 = __importDefault(require("axios"));
|
26
27
|
const web3_js_1 = require("@solana/web3.js");
|
27
28
|
const umi_1 = require("@metaplex-foundation/umi");
|
@@ -173,3 +174,6 @@ function u16ToArrayBufferLE(value) {
|
|
173
174
|
function validPubkey(pubkey) {
|
174
175
|
return Boolean(pubkey) && pubkey.toString() !== web3_js_1.PublicKey.default.toString();
|
175
176
|
}
|
177
|
+
function createRecord(keys, values) {
|
178
|
+
return Object.fromEntries(zip(keys, values).map(([k, v]) => [k.toString(), v]));
|
179
|
+
}
|
@@ -6,9 +6,9 @@ interface PriceResult {
|
|
6
6
|
emaPrice?: number;
|
7
7
|
}
|
8
8
|
export declare function fetchTokenPrices(mints: PublicKey[], priceType?: PriceType): Promise<number[]>;
|
9
|
-
export declare function getPythPrices(mints: PublicKey[]
|
10
|
-
export declare function getSwitchboardPrices(mints: PublicKey[]): Promise<PriceResult
|
11
|
-
export declare function getJupTokenPrices(mints: PublicKey[]): Promise<PriceResult
|
9
|
+
export declare function getPythPrices(mints: PublicKey[]): Promise<Record<string, PriceResult>>;
|
10
|
+
export declare function getSwitchboardPrices(mints: PublicKey[]): Promise<Record<string, PriceResult>>;
|
11
|
+
export declare function getJupTokenPrices(mints: PublicKey[]): Promise<Record<string, PriceResult>>;
|
12
12
|
export declare function safeGetPrice(mint: PublicKey | UmiPublicKey | string | undefined, priceType?: PriceType): number | undefined;
|
13
13
|
export {};
|
14
14
|
//# sourceMappingURL=priceUtils.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"priceUtils.d.ts","sourceRoot":"","sources":["../../src/utils/priceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAerE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,UAAU,WAAW;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,SAAS,EAAE,EAClB,SAAS,GAAE,SAA8B,GACxC,OAAO,CAAC,MAAM,EAAE,CAAC,
|
1
|
+
{"version":3,"file":"priceUtils.d.ts","sourceRoot":"","sources":["../../src/utils/priceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAerE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,UAAU,WAAW;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,SAAS,EAAE,EAClB,SAAS,GAAE,SAA8B,GACxC,OAAO,CAAC,MAAM,EAAE,CAAC,CAkDnB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAkDtC;AAkBD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CA+CtC;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,SAAS,EAAE,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAiBtC;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,MAAM,GAAG,SAAS,EACnD,SAAS,GAAE,SAA8B,GACxC,MAAM,GAAG,SAAS,CAQpB"}
|
package/dist/utils/priceUtils.js
CHANGED
@@ -37,42 +37,42 @@ const jupiterUtils_1 = require("./jupiterUtils");
|
|
37
37
|
const generated_1 = require("../generated");
|
38
38
|
async function fetchTokenPrices(mints, priceType = generated_1.PriceType.Realtime) {
|
39
39
|
const currentTime = (0, generalUtils_1.currentUnixSeconds)();
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
(
|
56
|
-
]);
|
57
|
-
const prices = mints.map((mint) => {
|
58
|
-
const item = [...pythData, ...switchboardData, ...jupData].find((data) => data[0].equals(mint));
|
59
|
-
return item ? item[1] : { realtimePrice: 0 };
|
60
|
-
});
|
61
|
-
for (var i = 0; i < mints.length; i++) {
|
62
|
-
const realtimePrice = prices[i].realtimePrice;
|
63
|
-
constants_1.PRICES[mints[i].toString()] = {
|
40
|
+
const mintStrs = mints.map((x) => x.toString());
|
41
|
+
const cachedPrices = Object.fromEntries(Object.entries(constants_1.PRICES).filter(([mint, price]) => mintStrs.includes(mint) && currentTime - price.time <= 3));
|
42
|
+
const newMints = mintStrs
|
43
|
+
.filter((x) => !Object.keys(cachedPrices).includes(x))
|
44
|
+
.map((x) => new web3_js_1.PublicKey(x));
|
45
|
+
const pythMints = newMints.filter((x) => x.toString() in constants_1.PYTH_PRICE_FEED_IDS);
|
46
|
+
const switchboardMints = newMints.filter((x) => x.toString() in Object.keys(constants_1.SWITCHBOARD_PRICE_FEED_IDS));
|
47
|
+
const otherMints = newMints.filter((x) => !pythMints.includes(x) && !switchboardMints.includes(x));
|
48
|
+
const newPrices = Object.assign({}, ...(await Promise.all([
|
49
|
+
getPythPrices(pythMints),
|
50
|
+
getSwitchboardPrices(switchboardMints),
|
51
|
+
getJupTokenPrices(otherMints),
|
52
|
+
])));
|
53
|
+
for (const mint of newMints) {
|
54
|
+
const realtimePrice = newPrices[mint.toString()].realtimePrice;
|
55
|
+
constants_1.PRICES[mint.toString()] = {
|
64
56
|
realtimePrice,
|
65
|
-
emaPrice:
|
57
|
+
emaPrice: newPrices[mint.toString()].emaPrice ?? realtimePrice,
|
66
58
|
time: (0, generalUtils_1.currentUnixSeconds)(),
|
67
59
|
};
|
68
60
|
}
|
69
|
-
|
70
|
-
|
71
|
-
|
61
|
+
const prices = {
|
62
|
+
...constants_1.PRICES,
|
63
|
+
...newPrices,
|
64
|
+
};
|
65
|
+
return mints.map((x) => {
|
66
|
+
const priceResult = prices[x.toString()];
|
67
|
+
const realtimePrice = priceResult.realtimePrice;
|
68
|
+
return priceType === generated_1.PriceType.Ema
|
69
|
+
? (priceResult.emaPrice ?? realtimePrice)
|
70
|
+
: realtimePrice;
|
71
|
+
});
|
72
72
|
}
|
73
|
-
async function getPythPrices(mints
|
73
|
+
async function getPythPrices(mints) {
|
74
74
|
if (mints.length === 0) {
|
75
|
-
return
|
75
|
+
return {};
|
76
76
|
}
|
77
77
|
const priceFeedIds = mints.map((mint) => constants_1.PYTH_PRICE_FEED_IDS[mint.toString()]);
|
78
78
|
const getReq = async () => await fetch(`https://hermes.pyth.network/v2/updates/price/latest?${priceFeedIds.map((x) => `ids%5B%5D=${x}`).join("&")}`);
|
@@ -102,7 +102,7 @@ async function getPythPrices(mints, priceType) {
|
|
102
102
|
});
|
103
103
|
return prices;
|
104
104
|
}, 5, 200);
|
105
|
-
return prices;
|
105
|
+
return (0, generalUtils_1.createRecord)(mints.map((x) => x.toString()), prices);
|
106
106
|
}
|
107
107
|
function getSortedPriceData(prices, mints) {
|
108
108
|
const sortedPrices = {};
|
@@ -116,7 +116,7 @@ function getSortedPriceData(prices, mints) {
|
|
116
116
|
}
|
117
117
|
async function getSwitchboardPrices(mints) {
|
118
118
|
if (mints.length === 0) {
|
119
|
-
return
|
119
|
+
return {};
|
120
120
|
}
|
121
121
|
const { CrossbarClient } = SwbCommon;
|
122
122
|
const crossbar = CrossbarClient.default();
|
@@ -133,7 +133,7 @@ async function getSwitchboardPrices(mints) {
|
|
133
133
|
for (const item of resp) {
|
134
134
|
for (const [k, v] of Object.entries(constants_1.SWITCHBOARD_PRICE_FEED_IDS)) {
|
135
135
|
if (item.feedHash === v.feedHash) {
|
136
|
-
finalMap[k] = Number(item.results[0]);
|
136
|
+
finalMap[k] = { realtimePrice: Number(item.results[0]) };
|
137
137
|
}
|
138
138
|
}
|
139
139
|
}
|
@@ -144,25 +144,21 @@ async function getSwitchboardPrices(mints) {
|
|
144
144
|
(0, generalUtils_1.consoleLog)("Failed to fetch Switchboard prices after multiple retries");
|
145
145
|
}
|
146
146
|
const missingMints = mints.filter((x) => !prices[x.toString()]);
|
147
|
-
const jupPrices =
|
148
|
-
|
149
|
-
return acc;
|
150
|
-
}, {});
|
151
|
-
return Object.values(getSortedPriceData({ ...prices, ...jupPrices }, mints)).map((x) => {
|
152
|
-
return { realtimePrice: x };
|
153
|
-
});
|
147
|
+
const jupPrices = await getJupTokenPrices(missingMints.map((x) => new web3_js_1.PublicKey(x)));
|
148
|
+
return { ...prices, ...jupPrices };
|
154
149
|
}
|
155
150
|
async function getJupTokenPrices(mints) {
|
156
151
|
if (mints.length == 0) {
|
157
|
-
return
|
152
|
+
return {};
|
158
153
|
}
|
159
154
|
const data = getSortedPriceData(await (0, jupiterUtils_1.getJupPriceData)(mints), mints);
|
160
|
-
const prices = Object.
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
155
|
+
const prices = Object.fromEntries(Object.entries(data).map(([mint, x]) => [
|
156
|
+
mint,
|
157
|
+
x !== null && typeof x === "object" && "price" in x
|
158
|
+
? { realtimePrice: parseFloat(x.price) }
|
159
|
+
: { realtimePrice: 0 },
|
160
|
+
]));
|
161
|
+
return prices;
|
166
162
|
}
|
167
163
|
function safeGetPrice(mint, priceType = generated_1.PriceType.Realtime) {
|
168
164
|
if (mint && mint?.toString() in constants_1.PRICES) {
|
package/package.json
CHANGED
@@ -45,11 +45,11 @@ export class ClientTransactionsManager extends TransactionsManager<SolautoClient
|
|
45
45
|
|
46
46
|
if (txs.find((x) => x.oracleInteractor) && switchboardMints.length) {
|
47
47
|
this.txHandler.log("Requires oracle update(s)...");
|
48
|
-
const
|
48
|
+
const oracleTxs = switchboardMints.map(
|
49
49
|
(x) =>
|
50
50
|
new TransactionItem(
|
51
51
|
async () =>
|
52
|
-
buildSwbSubmitResponseTx(
|
52
|
+
await buildSwbSubmitResponseTx(
|
53
53
|
this.txHandler.connection,
|
54
54
|
this.txHandler.signer,
|
55
55
|
x
|
@@ -57,7 +57,7 @@ export class ClientTransactionsManager extends TransactionsManager<SolautoClient
|
|
57
57
|
this.updateOracleTxName
|
58
58
|
)
|
59
59
|
);
|
60
|
-
txs.unshift(...
|
60
|
+
txs.unshift(...oracleTxs);
|
61
61
|
}
|
62
62
|
}
|
63
63
|
|
@@ -470,9 +470,9 @@ export class TransactionsManager<T extends TxHandler> {
|
|
470
470
|
await itemSet.refetchAll(attemptNum, prevError);
|
471
471
|
} else {
|
472
472
|
await Promise.all(itemSets.map((itemSet) => itemSet.reset()));
|
473
|
-
|
474
|
-
|
475
|
-
|
473
|
+
for (const itemSet of itemSets) {
|
474
|
+
await itemSet.refetchAll(attemptNum, prevError);
|
475
|
+
}
|
476
476
|
}
|
477
477
|
|
478
478
|
const newItemSets = await this.assembleTransactionSets(
|
@@ -1,6 +1,11 @@
|
|
1
1
|
import axios from "axios";
|
2
2
|
import { PublicKey } from "@solana/web3.js";
|
3
|
-
import {
|
3
|
+
import {
|
4
|
+
MaybeRpcAccount,
|
5
|
+
publicKey,
|
6
|
+
Umi,
|
7
|
+
PublicKey as UmiPublicKey,
|
8
|
+
} from "@metaplex-foundation/umi";
|
4
9
|
import { TOKEN_INFO, TokenInfo } from "../constants";
|
5
10
|
|
6
11
|
export function buildHeliusApiUrl(heliusApiKey: string) {
|
@@ -199,4 +204,10 @@ export function u16ToArrayBufferLE(value: number): Uint8Array {
|
|
199
204
|
|
200
205
|
export function validPubkey(pubkey?: PublicKey | UmiPublicKey | string) {
|
201
206
|
return Boolean(pubkey) && pubkey!.toString() !== PublicKey.default.toString();
|
202
|
-
}
|
207
|
+
}
|
208
|
+
|
209
|
+
export function createRecord<T>(keys: string[], values: T[]): Record<string, T> {
|
210
|
+
return Object.fromEntries(
|
211
|
+
zip(keys, values).map(([k, v]) => [k.toString(), v])
|
212
|
+
);
|
213
|
+
}
|
package/src/utils/priceUtils.ts
CHANGED
@@ -9,9 +9,9 @@ import {
|
|
9
9
|
import { fromBaseUnit, toBaseUnit } from "./numberUtils";
|
10
10
|
import {
|
11
11
|
consoleLog,
|
12
|
+
createRecord,
|
12
13
|
currentUnixSeconds,
|
13
14
|
retryWithExponentialBackoff,
|
14
|
-
zip,
|
15
15
|
} from "./generalUtils";
|
16
16
|
import { getJupPriceData } from "./jupiterUtils";
|
17
17
|
import { PriceType } from "../generated";
|
@@ -26,64 +26,61 @@ export async function fetchTokenPrices(
|
|
26
26
|
priceType: PriceType = PriceType.Realtime
|
27
27
|
): Promise<number[]> {
|
28
28
|
const currentTime = currentUnixSeconds();
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
currentTime -
|
29
|
+
const mintStrs = mints.map((x) => x.toString());
|
30
|
+
const cachedPrices: Record<string, PriceResult> = Object.fromEntries(
|
31
|
+
Object.entries(PRICES).filter(
|
32
|
+
([mint, price]) =>
|
33
|
+
mintStrs.includes(mint) && currentTime - price.time <= 3
|
34
34
|
)
|
35
|
-
)
|
36
|
-
return mints.map((mint) => {
|
37
|
-
const priceData = PRICES[mint.toString()];
|
38
|
-
return priceType === PriceType.Ema
|
39
|
-
? priceData.emaPrice
|
40
|
-
: priceData.realtimePrice;
|
41
|
-
});
|
42
|
-
}
|
35
|
+
);
|
43
36
|
|
44
|
-
const
|
45
|
-
|
37
|
+
const newMints = mintStrs
|
38
|
+
.filter((x) => !Object.keys(cachedPrices).includes(x))
|
39
|
+
.map((x) => new PublicKey(x));
|
40
|
+
const pythMints = newMints.filter((x) => x.toString() in PYTH_PRICE_FEED_IDS);
|
41
|
+
const switchboardMints = newMints.filter(
|
46
42
|
(x) => x.toString() in Object.keys(SWITCHBOARD_PRICE_FEED_IDS)
|
47
43
|
);
|
48
|
-
const otherMints =
|
44
|
+
const otherMints = newMints.filter(
|
49
45
|
(x) => !pythMints.includes(x) && !switchboardMints.includes(x)
|
50
46
|
);
|
47
|
+
const newPrices: Record<string, PriceResult> = Object.assign(
|
48
|
+
{},
|
49
|
+
...(await Promise.all([
|
50
|
+
getPythPrices(pythMints),
|
51
|
+
getSwitchboardPrices(switchboardMints),
|
52
|
+
getJupTokenPrices(otherMints),
|
53
|
+
]))
|
54
|
+
);
|
51
55
|
|
52
|
-
const
|
53
|
-
|
54
|
-
|
55
|
-
zip(otherMints, await getJupTokenPrices(otherMints)),
|
56
|
-
]);
|
57
|
-
|
58
|
-
const prices = mints.map((mint) => {
|
59
|
-
const item = [...pythData, ...switchboardData, ...jupData].find((data) =>
|
60
|
-
data[0].equals(mint)
|
61
|
-
);
|
62
|
-
return item ? item[1] : { realtimePrice: 0 };
|
63
|
-
});
|
64
|
-
|
65
|
-
for (var i = 0; i < mints.length; i++) {
|
66
|
-
const realtimePrice = prices[i].realtimePrice;
|
67
|
-
PRICES[mints[i].toString()] = {
|
56
|
+
for (const mint of newMints) {
|
57
|
+
const realtimePrice = newPrices[mint.toString()].realtimePrice;
|
58
|
+
PRICES[mint.toString()] = {
|
68
59
|
realtimePrice,
|
69
|
-
emaPrice:
|
60
|
+
emaPrice: newPrices[mint.toString()].emaPrice ?? realtimePrice,
|
70
61
|
time: currentUnixSeconds(),
|
71
62
|
};
|
72
63
|
}
|
73
64
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
65
|
+
const prices: Record<string, PriceResult> = {
|
66
|
+
...PRICES,
|
67
|
+
...newPrices,
|
68
|
+
};
|
69
|
+
|
70
|
+
return mints.map((x) => {
|
71
|
+
const priceResult = prices[x.toString()];
|
72
|
+
const realtimePrice = priceResult.realtimePrice;
|
73
|
+
return priceType === PriceType.Ema
|
74
|
+
? (priceResult.emaPrice ?? realtimePrice)
|
75
|
+
: realtimePrice;
|
76
|
+
});
|
79
77
|
}
|
80
78
|
|
81
79
|
export async function getPythPrices(
|
82
|
-
mints: PublicKey[]
|
83
|
-
|
84
|
-
): Promise<PriceResult[]> {
|
80
|
+
mints: PublicKey[]
|
81
|
+
): Promise<Record<string, PriceResult>> {
|
85
82
|
if (mints.length === 0) {
|
86
|
-
return
|
83
|
+
return {};
|
87
84
|
}
|
88
85
|
|
89
86
|
const priceFeedIds = mints.map(
|
@@ -127,7 +124,10 @@ export async function getPythPrices(
|
|
127
124
|
200
|
128
125
|
);
|
129
126
|
|
130
|
-
return
|
127
|
+
return createRecord(
|
128
|
+
mints.map((x) => x.toString()),
|
129
|
+
prices
|
130
|
+
);
|
131
131
|
}
|
132
132
|
|
133
133
|
function getSortedPriceData(
|
@@ -148,15 +148,15 @@ function getSortedPriceData(
|
|
148
148
|
|
149
149
|
export async function getSwitchboardPrices(
|
150
150
|
mints: PublicKey[]
|
151
|
-
): Promise<PriceResult
|
151
|
+
): Promise<Record<string, PriceResult>> {
|
152
152
|
if (mints.length === 0) {
|
153
|
-
return
|
153
|
+
return {};
|
154
154
|
}
|
155
155
|
|
156
156
|
const { CrossbarClient } = SwbCommon;
|
157
157
|
const crossbar = CrossbarClient.default();
|
158
158
|
|
159
|
-
let prices: Record<string,
|
159
|
+
let prices: Record<string, PriceResult> = {};
|
160
160
|
try {
|
161
161
|
prices = await retryWithExponentialBackoff(
|
162
162
|
async () => {
|
@@ -172,11 +172,11 @@ export async function getSwitchboardPrices(
|
|
172
172
|
throw new Error("Unable to fetch Switchboard prices");
|
173
173
|
}
|
174
174
|
|
175
|
-
const finalMap: Record<string,
|
175
|
+
const finalMap: Record<string, PriceResult> = {};
|
176
176
|
for (const item of resp) {
|
177
177
|
for (const [k, v] of Object.entries(SWITCHBOARD_PRICE_FEED_IDS)) {
|
178
178
|
if (item.feedHash === v.feedHash) {
|
179
|
-
finalMap[k] = Number(item.results[0]);
|
179
|
+
finalMap[k] = { realtimePrice: Number(item.results[0]) };
|
180
180
|
}
|
181
181
|
}
|
182
182
|
}
|
@@ -190,42 +190,32 @@ export async function getSwitchboardPrices(
|
|
190
190
|
}
|
191
191
|
|
192
192
|
const missingMints = mints.filter((x) => !prices[x.toString()]);
|
193
|
-
const jupPrices =
|
194
|
-
missingMints
|
195
|
-
await getJupTokenPrices(missingMints.map((x) => new PublicKey(x)))
|
196
|
-
).reduce(
|
197
|
-
(acc, [key, value]) => {
|
198
|
-
acc[key.toString()] = value.realtimePrice;
|
199
|
-
return acc;
|
200
|
-
},
|
201
|
-
{} as Record<string, number>
|
193
|
+
const jupPrices = await getJupTokenPrices(
|
194
|
+
missingMints.map((x) => new PublicKey(x))
|
202
195
|
);
|
203
196
|
|
204
|
-
return
|
205
|
-
getSortedPriceData({ ...prices, ...jupPrices }, mints)
|
206
|
-
).map((x) => {
|
207
|
-
return { realtimePrice: x };
|
208
|
-
});
|
197
|
+
return { ...prices, ...jupPrices };
|
209
198
|
}
|
210
199
|
|
211
200
|
export async function getJupTokenPrices(
|
212
201
|
mints: PublicKey[]
|
213
|
-
): Promise<PriceResult
|
202
|
+
): Promise<Record<string, PriceResult>> {
|
214
203
|
if (mints.length == 0) {
|
215
|
-
return
|
204
|
+
return {};
|
216
205
|
}
|
217
206
|
|
218
207
|
const data = getSortedPriceData(await getJupPriceData(mints), mints);
|
219
208
|
|
220
|
-
const prices = Object.
|
221
|
-
|
222
|
-
|
223
|
-
|
209
|
+
const prices: Record<string, PriceResult> = Object.fromEntries(
|
210
|
+
Object.entries(data).map(([mint, x]) => [
|
211
|
+
mint,
|
212
|
+
x !== null && typeof x === "object" && "price" in x
|
213
|
+
? { realtimePrice: parseFloat(x.price as string) }
|
214
|
+
: { realtimePrice: 0 },
|
215
|
+
])
|
224
216
|
);
|
225
217
|
|
226
|
-
return prices
|
227
|
-
return { realtimePrice: x };
|
228
|
-
});
|
218
|
+
return prices;
|
229
219
|
}
|
230
220
|
|
231
221
|
export function safeGetPrice(
|