diff --git a/solend-sdk/__tests__/obligation.test.ts b/solend-sdk/__tests__/obligation.test.ts index d94ec179..aec0e8ea 100644 --- a/solend-sdk/__tests__/obligation.test.ts +++ b/solend-sdk/__tests__/obligation.test.ts @@ -1,50 +1,165 @@ import { + ComputeBudgetProgram, Connection, + Keypair, PublicKey, + TransactionMessage, + VersionedTransaction, } from "@solana/web3.js"; import { parseObligation } from "../src"; +import { PriceServiceConnection } from "@pythnetwork/price-service-client"; +import { PythSolanaReceiver, pythSolanaReceiverIdl } from "@pythnetwork/pyth-solana-receiver"; +import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; +import { AnchorProvider, Program } from "@coral-xyz/anchor-30"; +import { CrossbarClient, loadLookupTables, PullFeed, SB_ON_DEMAND_PID } from "@switchboard-xyz/on-demand"; jest.setTimeout(50_000); describe("check", function () { it("parses obligation in both formats", async function () { - const zstdEncodedObligationData = Buffer.from( - "KLUv/QBYLQoAdBEBWZHIBwAAAAABM7MexO/4+iia6oyVTAFjLi12SQjOVE1oZb3vERv/YSsChcZ+Ktz1mRBrkyRk1BwBK+MRLDs2kN6sQJrkE/068ae2QKj1GoAIagEAUiLO4HOtZQD9iDA+OBRghg/ZNGo1t+NsujMBAQFsp+C1qN6toMtzc12/wVf8DODwcnh4K7b1j6DEElE6V8esAGvgw8KAVqMAbcvwdUngHTQhP3KK2EcTtbcXhy+sOBPKuWOvMSyN283/9ZTFWnxCDgDvyiK06ZHhKd04ANAh+wRuI+ENjqkOBTFIeS9ID9NTKr93sO+769EA4idmIqc8x1Enq7K/tz3DwaHWY5RMvzQOIJZ5G4lBjXXPHRJX7vzRwA8SAM1yFQDEt5APgChdqyVY2VtAAS80LATg+oCsBCUWCFQgLRhoqHwAcXWBMw==", - "base64" - ); - const base64EncodedObligationData = Buffer.from( - "AVmRyAcAAAAAATOzHsTv+PoomuqMlUwBYy4tdkkIzlRNaGW97xEb/2ErAoXGfirc9ZkQa5MkZNQcASvjESw7NpDerECa5BP9OvGntkCo9RqACGoBAAAAAAAAUiLO4HOtZQAAAAAAAAAAAP2IMD44FGCGDwEAAAAAAADZNGo1t+NsujMBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBbKfgtajeraDLc3Ndv8FX/Azg8HJ4eCu29Y+gxBJROlfHrAAAAAAAAGvgw8KAVqMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG3L8HVJ4B00IT9yithHE7W3F4cvrDgTyrljrzEsjdvN//WUxVp8Qg4AAAAAAAAAAO/KIrTpkeEp3TgAAAAAAABSIs7gc61lAAAAAAAAAAAAAAAAAAAAAABty/B1SeAdNCE/corYRxO1txeHL6w4E8q5Y68xLI3bzf/1lMVafEIOAAAAAAAAAADvyiK06ZHhKd04AAAAAAAAUiLO4HOtZQAAAAAAAAAAANAh+wQAAAAAbiPhDY6pDgUxAQAAAAAAAAAAAAAAAAAASHkvSA/TUyq/d7Dvu+vRAOInZiKnPMdRJ6uyv7c9w8Gh1mOUTL80DgAAAAAAAAAAIJZ5G4lBjXXPIfsEAAAAAB0SV+780cAPMQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", - "base64" - ); - - const obligationPubkey = new PublicKey( - "FfRLBU1gHm3MyqJ3KX6dBnsxxJtwVGCwKFwJrfDnceWN" - ); - const connection = new Connection("https://api.mainnet-beta.solana.com", { - commitment: "finalized", - }); - - const zstdEncodedObligation = await connection.getAccountInfo( - obligationPubkey - ); - zstdEncodedObligation!.data = zstdEncodedObligationData; - const base64EncodedObligation = await connection.getAccountInfo( - obligationPubkey - ); - base64EncodedObligation!.data = base64EncodedObligationData; - - const parsedzstdEncodedObligation = parseObligation( - obligationPubkey, - zstdEncodedObligation!, - "base64+zstd" - ); - const parsedbase64EncodedObligation = parseObligation( - obligationPubkey, - base64EncodedObligation! - ); - - expect(parsedzstdEncodedObligation!).toMatchObject( - parsedbase64EncodedObligation! - ); + const connection = new Connection("https://solendf-solendf-67c7.rpcpool.com/6096fc4b-78fc-4130-a42a-e6d4b9c37813"); + // const priceServiceConnection = new PriceServiceConnection("https://hermes.pyth.network"); + // const pythSolanaReceiver = new PythSolanaReceiver({ + // connection: connection, + // wallet: new NodeWallet(Keypair.fromSeed(new Uint8Array(32).fill(1))) + // }); + // const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({ + // closeUpdateAccounts: true, + // }); + + const provider = new AnchorProvider(connection, new NodeWallet(Keypair.fromSecretKey(new Uint8Array( + [103,129,37,223,47,99,63,95,41,95,190,254,216,11,20,217,101,217,65,173,210,207,137,44,176,136,93,84,15,87,212,78,254,157,169,160,244,214,188,162,227,202,121,33,107,191,169,212,16,93,176,86,248,238,250,64,147,23,50,212,180,223,6,63] + ))), {}); + const idl = (await Program.fetchIdl(SB_ON_DEMAND_PID, provider))!; + const sbod = new Program(idl, provider); + + const sbPulledOracles = [ + '2F9M59yYc28WMrAymNWceaBEk8ZmDAjUAKULp8seAJF3', + 'AZcoqpWhMJUaKEDUfKsfzCr3Y96gSQwv43KSQ6KpeyQ1' + ]; + const feedAccounts = sbPulledOracles.map((oracleKey) => new PullFeed(sbod as any, oracleKey)); + const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz"); + + // Responses is Array<[pullIx, responses, success]> + const responses = await Promise.all(feedAccounts.map((feedAccount) => feedAccount.fetchUpdateIx({ numSignatures: 1, crossbarClient: crossbar }))); + const oracles = responses.flatMap((x) => x[1].map(y => y.oracle)); + const lookupTables = await loadLookupTables([...oracles, ...feedAccounts]); + + console.log(responses); + + // Get the latest context + const { + value: { blockhash }, + } = await connection.getLatestBlockhashAndContext(); + + // Get Transaction Message + const message = new TransactionMessage({ + payerKey: provider.publicKey, + recentBlockhash: blockhash, + instructions: [...responses.map(r => r[0]!)], + }).compileToV0Message(lookupTables); + + // Get Versioned Transaction + const vtx = new VersionedTransaction(message); + provider.wallet.signAllTransactions([vtx]); + const sig = await connection.sendRawTransaction(vtx.serialize(), {skipPreflight: true}); + await connection.confirmTransaction(sig, 'confirmed'); + // let priceFeedUpdateData; + // priceFeedUpdateData = await priceServiceConnection.getLatestVaas( + // [ + // 'ef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d', + // '67be9f519b95cf24338801051f9a808eff0a578ccb388db73b7f6fe1de019ffb', + // 'c2289a6a43d2ce91c6f55caec370f4acc38a2ed477f58813334c6d03749ff2a4', + // '89875379e70f8fbadc17aef315adf3a8d5d160b811435537e03c97e8aac97d9c', + // '72b021217ca3fe68922a19aaf990109cb9d84e9ad004b4d2025ad6f529314419', + // 'eff7446475e218517566ea99e72a4abec2e1bd8498b43b7d8331e29dcb059389' + // ] + // ); + + // await transactionBuilder.addUpdatePriceFeed( + // priceFeedUpdateData, + // 0 // shardId of 0 + // ); + // await transactionBuilder.addPostPriceUpdates(priceFeedUpdateData); + + // const transactionsWithSigners = await transactionBuilder.buildVersionedTransactions({ + // tightComputeBudget: true, + // }); + + // console.log(transactionsWithSigners); + // console.log(transactionsWithSigners.map(t => t.tx.message.compiledInstructions)); + + }); + + // it("parses obligation in both formats", async function () { + // const connection = new Connection("https://solendf-solendf-67c7.rpcpool.com/6096fc4b-78fc-4130-a42a-e6d4b9c37813"); + // const priceServiceConnection = new PriceServiceConnection("https://hermes.pyth.network"); + // const pythSolanaReceiver = new PythSolanaReceiver({ + // connection: connection, + // wallet: new NodeWallet(Keypair.fromSecretKey(new Uint8Array( + // [103,129,37,223,47,99,63,95,41,95,190,254,216,11,20,217,101,217,65,173,210,207,137,44,176,136,93,84,15,87,212,78,254,157,169,160,244,214,188,162,227,202,121,33,107,191,169,212,16,93,176,86,248,238,250,64,147,23,50,212,180,223,6,63] + // ))) + // }); + // const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({ + // closeUpdateAccounts: true, + // }); + + // const oracleAccount = await connection.getAccountInfo(new PublicKey('FFv5yoCGhEgWv6mXhwv4KX8A2dYcVAzi88a6Yu8Tf3iB')); + + // console.log(oracleAccount, pythSolanaReceiverIdl); + // const priceUpdate = pythSolanaReceiver.receiver.account.priceUpdateV2.coder.accounts.decode( + // 'priceUpdateV2', + // oracleAccount!.data, + // ); + // const exponent = 10 ** priceUpdate.priceMessage.exponent; + // const spotPrice = priceUpdate.priceMessage.price.toNumber() * exponent; + // const emaPrice = priceUpdate.priceMessage.emaPrice.toNumber() * exponent; + // console.log(spotPrice, emaPrice) + // const priceFeedId = priceUpdate.priceMessage.feedId; + + // let priceFeedUpdateData; + // priceFeedUpdateData = await priceServiceConnection.getLatestVaas( + // [ + // '0x93c3def9b169f49eed14c9d73ed0e942c666cf0e1290657ec82038ebb792c2a8', // BLZE + // '0xf2fc1dfcf51867abfa70874c929e920edc649e4997cbac88f280094df8c72bcd', // EUROE + // ] + // ); + + // console.log(priceFeedUpdateData); + // await transactionBuilder.addUpdatePriceFeed( + // priceFeedUpdateData, + // 0 // shardId of 0 + // ); + // // await transactionBuilder.addPostPriceUpdates(priceFeedUpdateData); + + // const transactionsWithSigners = await transactionBuilder.buildVersionedTransactions({ + // tightComputeBudget: true, + // }); + + // // transactionBuilder.addPriceConsumerInstructions + + + // console.log(transactionsWithSigners); + // const pullPriceTxns = [] as Array; + // // TODO: Verify if there even is signers + // for (const transaction of transactionsWithSigners) { + // const signers = transaction.signers; + // let tx = transaction.tx; + + // if (signers) { + // tx.sign(signers); + // pullPriceTxns.push(tx); + // } + // } + + // pythSolanaReceiver.wallet.signAllTransactions(pullPriceTxns) + + // for (const tx of pullPriceTxns) { + // const serializedTransaction = tx.serialize(); + // const sig = await connection.sendRawTransaction(serializedTransaction, {skipPreflight: true}); + // await connection.confirmTransaction(sig, 'confirmed'); + // } + + // }); }); diff --git a/solend-sdk/__tests__/oracle.test.ts b/solend-sdk/__tests__/oracle.test.ts new file mode 100644 index 00000000..baa60fee --- /dev/null +++ b/solend-sdk/__tests__/oracle.test.ts @@ -0,0 +1,120 @@ +import { + ComputeBudgetProgram, + Connection, + Keypair, + PublicKey, + TransactionMessage, + VersionedTransaction, + } from "@solana/web3.js"; + import { parseObligation } from "../src"; + import { PriceServiceConnection } from "@pythnetwork/price-service-client"; + import { PythSolanaReceiver, pythSolanaReceiverIdl } from "@pythnetwork/pyth-solana-receiver"; + import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; + import { AnchorProvider, Program } from "@coral-xyz/anchor-30"; + import { CrossbarClient, loadLookupTables, PullFeed, SB_ON_DEMAND_PID } from "@switchboard-xyz/on-demand"; + + jest.setTimeout(50_000); + + describe("check", function () { + it("parses obligation in both formats", async function () { + const connection = new Connection("https://api.mainnet-beta.solana.com"); + const testKey = [] + if (testKey.length === 0) { + throw Error('Best tested with a throwaway mainnet test account.') + } + + const provider = new AnchorProvider(connection, new NodeWallet(Keypair.fromSecretKey(new Uint8Array( + testKey + ))), {}); + const idl = (await Program.fetchIdl(SB_ON_DEMAND_PID, provider))!; + const sbod = new Program(idl, provider); + + const sbPulledOracles = [ + '2F9M59yYc28WMrAymNWceaBEk8ZmDAjUAKULp8seAJF3', + 'AZcoqpWhMJUaKEDUfKsfzCr3Y96gSQwv43KSQ6KpeyQ1' + ]; + + const feedAccounts = sbPulledOracles.map((oracleKey) => new PullFeed(sbod as any, oracleKey)); + const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz"); + + // Responses is Array<[pullIx, responses, success]> + const responses = await Promise.all(feedAccounts.map((feedAccount) => feedAccount.fetchUpdateIx({ numSignatures: 1, crossbarClient: crossbar }))); + const oracles = responses.flatMap((x) => x[1].map(y => y.oracle)); + const lookupTables = await loadLookupTables([...oracles, ...feedAccounts]); + + // Get the latest context + const { + value: { blockhash }, + } = await connection.getLatestBlockhashAndContext(); + + // Get Transaction Message + const message = new TransactionMessage({ + payerKey: provider.publicKey, + recentBlockhash: blockhash, + instructions: [...responses.map(r => r[0]!)], + }).compileToV0Message(lookupTables); + + // Get Versioned Transaction + const vtx = new VersionedTransaction(message); + provider.wallet.signAllTransactions([vtx]); + const sig = await connection.sendRawTransaction(vtx.serialize(), {skipPreflight: true}); + await connection.confirmTransaction(sig, 'confirmed'); + }); + + it("parses obligation in both formats", async function () { + const connection = new Connection("https://api.mainnet-beta.solana.com"); + const testKey = [] + if (testKey.length === 0) { + throw Error('Best tested with a throwaway mainnet test account.') + } + const priceServiceConnection = new PriceServiceConnection("https://hermes.pyth.network"); + const pythSolanaReceiver = new PythSolanaReceiver({ + connection: connection, + wallet: new NodeWallet(Keypair.fromSecretKey(new Uint8Array( + testKey + ))) + }); + const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({ + closeUpdateAccounts: true, + }); + + let priceFeedUpdateData; + priceFeedUpdateData = await priceServiceConnection.getLatestVaas( + [ + '0x93c3def9b169f49eed14c9d73ed0e942c666cf0e1290657ec82038ebb792c2a8', // BLZE + '0xf2fc1dfcf51867abfa70874c929e920edc649e4997cbac88f280094df8c72bcd', // EUROE + ] + ); + + await transactionBuilder.addUpdatePriceFeed( + priceFeedUpdateData, + 0 // shardId of 0 + ); + + const transactionsWithSigners = await transactionBuilder.buildVersionedTransactions({ + tightComputeBudget: true, + }); + + const pullPriceTxns = [] as Array; + + for (const transaction of transactionsWithSigners) { + const signers = transaction.signers; + let tx = transaction.tx; + + if (signers) { + tx.sign(signers); + pullPriceTxns.push(tx); + } + } + + pythSolanaReceiver.wallet.signAllTransactions(pullPriceTxns) + + for (const tx of pullPriceTxns) { + const serializedTransaction = tx.serialize(); + const sig = await connection.sendRawTransaction(serializedTransaction, {skipPreflight: true}); + await connection.confirmTransaction(sig, 'confirmed'); + } + + }); + }); + \ No newline at end of file diff --git a/solend-sdk/package.json b/solend-sdk/package.json index 8d4b40f9..a02d9aef 100644 --- a/solend-sdk/package.json +++ b/solend-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@solendprotocol/solend-sdk", - "version": "0.10.9", + "version": "0.10.11", "private": true, "main": "src/index.ts", "module": "src/index.ts", @@ -21,10 +21,13 @@ "dependencies": { "@project-serum/anchor": "^0.24.2", "@pythnetwork/client": "^2.12.0", + "@pythnetwork/price-service-client": "^1.9.0", + "@pythnetwork/pyth-solana-receiver": "^0.8.0", "@solana/buffer-layout": "=4.0.1", "@solana/spl-token": "^0.3.7", "@solana/web3.js": "=1.92.3", "@solflare-wallet/utl-sdk": "^1.4.0", + "@switchboard-xyz/on-demand": "^1.1.39", "@switchboard-xyz/sbv2-lite": "^0.2.4", "axios": "^0.24.0", "bignumber.js": "^9.0.2", diff --git a/solend-sdk/src/core/actions.ts b/solend-sdk/src/core/actions.ts index 704b9327..a5c848d4 100644 --- a/solend-sdk/src/core/actions.ts +++ b/solend-sdk/src/core/actions.ts @@ -1,7 +1,9 @@ import { AddressLookupTableAccount, BlockhashWithExpiryBlockHeight, + ComputeBudgetProgram, Connection, + Keypair, PublicKey, SystemProgram, Transaction, @@ -18,6 +20,7 @@ import { } from "@solana/spl-token"; import BN from "bn.js"; import BigNumber from "bignumber.js"; +import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver"; import { Obligation, OBLIGATION_SIZE, @@ -45,6 +48,10 @@ import { import { POSITION_LIMIT } from "./constants"; import { EnvironmentType, PoolType, ReserveType } from "./types"; import { getProgramId, U64_MAX, WAD } from "./constants"; +import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet"; +import { PriceServiceConnection } from "@pythnetwork/price-service-client"; +import { AnchorProvider, Program } from "@coral-xyz/anchor"; +import { CrossbarClient, loadLookupTables, PullFeed, SB_ON_DEMAND_PID } from "@switchboard-xyz/on-demand"; const SOL_PADDING_FOR_INTEREST = "1000000"; @@ -86,6 +93,9 @@ export class SolendActionCore { hostAta?: PublicKey; + // TODO: potentially don't need to keep signers + pullPriceTxns: Array; + setupIxs: Array; lendingIxs: Array; @@ -136,6 +146,7 @@ export class SolendActionCore { this.obligationAddress = obligationAddress; this.userTokenAccountAddress = userTokenAccountAddress; this.userCollateralAccountAddress = userCollateralAccountAddress; + this.pullPriceTxns = [] as Array; this.setupIxs = []; this.lendingIxs = []; this.cleanupIxs = []; @@ -567,10 +578,12 @@ export class SolendActionCore { preLendingTxn: VersionedTransaction | null; lendingTxn: VersionedTransaction | null; postLendingTxn: VersionedTransaction | null; + pullPriceTxns: VersionedTransaction[] | null } = { preLendingTxn: null, lendingTxn: null, postLendingTxn: null, + pullPriceTxns: null, }; if (this.preTxnIxs.length) { @@ -607,6 +620,10 @@ export class SolendActionCore { ); } + if (this.pullPriceTxns.length) { + txns.pullPriceTxns = this.pullPriceTxns; + } + return txns; } @@ -831,6 +848,93 @@ export class SolendActionCore { } } + private async buildPullPriceTxns(oracleKeys: Array) { + const oracleAccounts = await this.connection.getMultipleAccountsInfo(oracleKeys.map((o) => new PublicKey(o)), 'processed') + const priceServiceConnection = new PriceServiceConnection("https://hermes.pyth.network"); + const pythSolanaReceiver = new PythSolanaReceiver({ + connection: this.connection, + wallet: new NodeWallet(Keypair.fromSeed(new Uint8Array(32).fill(1))) + }); + const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({ + closeUpdateAccounts: true, + }); + + const provider = new AnchorProvider(this.connection, new NodeWallet(Keypair.fromSeed(new Uint8Array(32).fill(1))), {}); + const idl = (await Program.fetchIdl(SB_ON_DEMAND_PID, provider))!; + const sbod = new Program(idl, SB_ON_DEMAND_PID, provider); + + const pythPulledOracles = oracleAccounts.filter(o => o?.owner.toBase58() === pythSolanaReceiver.receiver.programId.toBase58()); + + const shuffledPriceIds = pythPulledOracles + .map((pythOracleData, index) => { + if (!pythOracleData) { + throw new Error(`Could not find oracle data at index ${index}`); + } + const priceUpdate = pythSolanaReceiver.receiver.account.priceUpdateV2.coder.accounts.decode( + 'priceUpdateV2', + pythOracleData.data, + ); + + return { key: Math.random() , priceFeedId: priceUpdate.priceMessage.feedId }; + }) + .sort((a, b) => a.key - b.key) + .map((x) => x.priceFeedId); + + let priceFeedUpdateData; + priceFeedUpdateData = await priceServiceConnection.getLatestVaas( + shuffledPriceIds + ); + + await transactionBuilder.addUpdatePriceFeed( + priceFeedUpdateData, + 0 // shardId of 0 + ); + + const transactionsWithSigners = await transactionBuilder.buildVersionedTransactions({ + tightComputeBudget: true, + }); + + for (const transaction of transactionsWithSigners) { + const signers = transaction.signers; + let tx = transaction.tx; + + if (signers) { + tx.sign(signers); + this.pullPriceTxns.push(tx); + } + } + + const sbPulledOracles = oracleKeys.filter((_o, index) => oracleAccounts[index]?.owner.toBase58() === sbod.programId.toBase58()) + const feedAccounts = sbPulledOracles.map((oracleKey) => new PullFeed(sbod as any, oracleKey)); + const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz"); + + // Responses is Array<[pullIx, responses, success]> + const responses = await Promise.all(feedAccounts.map((feedAccount) => feedAccount.fetchUpdateIx({ numSignatures: 1, crossbarClient: crossbar }))); + const oracles = responses.flatMap((x) => x[1].map(y => y.oracle)); + const lookupTables = await loadLookupTables([...oracles, ...feedAccounts]); + + const priorityFeeIx = ComputeBudgetProgram.setComputeUnitPrice({ + microLamports: 100_000, + }); + + // Get the latest context + const { + value: { blockhash }, + } = await this.connection.getLatestBlockhashAndContext(); + + // Get Transaction Message + const message = new TransactionMessage({ + payerKey: this.publicKey, + recentBlockhash: blockhash, + instructions: [priorityFeeIx, ...responses.map(r => r[0]!)], + }).compileToV0Message(lookupTables); + + // Get Versioned Transaction + const vtx = new VersionedTransaction(message); + + this.pullPriceTxns.push(vtx);; + } + private async addRefreshIxs(action: ActionType) { // Union of addresses const allReserveAddresses = Array.from(new Set([ @@ -840,6 +944,8 @@ export class SolendActionCore { ]), ); + await this.buildPullPriceTxns(allReserveAddresses); + allReserveAddresses.forEach((reserveAddress) => { const reserveInfo = this.pool.reserves.find( (reserve) => reserve.address === reserveAddress diff --git a/yarn.lock b/yarn.lock index cbcdab27..db5fb442 100644 --- a/yarn.lock +++ b/yarn.lock @@ -969,7 +969,7 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.24.7": +"@babel/runtime@^7.15.4", "@babel/runtime@^7.24.7": version "7.24.8" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.8.tgz#5d958c3827b13cc6d05e038c07fb2e5e3420d82e" integrity sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA== @@ -1861,6 +1861,32 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@coral-xyz/anchor-30@npm:@coral-xyz/anchor@0.30.1": + version "0.30.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.30.1.tgz#17f3e9134c28cd0ea83574c6bab4e410bcecec5d" + integrity sha512-gDXFoF5oHgpriXAaLpxyWBHdCs8Awgf/gLHIo6crv7Aqm937CNdY+x+6hoj7QR5vaJV7MxWSQ0NGFzL3kPbWEQ== + dependencies: + "@coral-xyz/anchor-errors" "^0.30.1" + "@coral-xyz/borsh" "^0.30.1" + "@noble/hashes" "^1.3.1" + "@solana/web3.js" "^1.68.0" + bn.js "^5.1.2" + bs58 "^4.0.1" + buffer-layout "^1.2.2" + camelcase "^6.3.0" + cross-fetch "^3.1.5" + crypto-hash "^1.3.0" + eventemitter3 "^4.0.7" + pako "^2.0.3" + snake-case "^3.0.4" + superstruct "^0.15.4" + toml "^3.0.0" + +"@coral-xyz/anchor-errors@^0.30.1": + version "0.30.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/anchor-errors/-/anchor-errors-0.30.1.tgz#bdfd3a353131345244546876eb4afc0e125bec30" + integrity sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ== + "@coral-xyz/anchor@^0.28.0": version "0.28.0" resolved "https://registry.yarnpkg.com/@coral-xyz/anchor/-/anchor-0.28.0.tgz#8345c3c9186a91f095f704d7b90cd256f7e8b2dc" @@ -1918,6 +1944,14 @@ bn.js "^5.1.2" buffer-layout "^1.2.0" +"@coral-xyz/borsh@^0.30.1": + version "0.30.1" + resolved "https://registry.yarnpkg.com/@coral-xyz/borsh/-/borsh-0.30.1.tgz#869d8833abe65685c72e9199b8688477a4f6b0e3" + integrity sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ== + dependencies: + bn.js "^5.1.2" + buffer-layout "^1.2.0" + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -4219,7 +4253,20 @@ "@coral-xyz/borsh" "^0.28.0" buffer "^6.0.1" -"@pythnetwork/price-service-sdk@>=1.6.0": +"@pythnetwork/price-service-client@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@pythnetwork/price-service-client/-/price-service-client-1.9.0.tgz#1503d67b1a7c14386d30bb420502df4857027e76" + integrity sha512-SLm3IFcfmy9iMqHeT4Ih6qMNZhJEefY14T9yTlpsH2D/FE5+BaGGnfcexUifVlfH6M7mwRC4hEFdNvZ6ebZjJg== + dependencies: + "@pythnetwork/price-service-sdk" "*" + "@types/ws" "^8.5.3" + axios "^1.5.1" + axios-retry "^3.8.0" + isomorphic-ws "^4.0.1" + ts-log "^2.2.4" + ws "^8.6.0" + +"@pythnetwork/price-service-sdk@*", "@pythnetwork/price-service-sdk@>=1.6.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@pythnetwork/price-service-sdk/-/price-service-sdk-1.7.1.tgz#dbfc8a8c2189f526346c1f79ec3995e89b690700" integrity sha512-xr2boVXTyv1KUt/c6llUTfbv2jpud99pWlMJbFaHGUBoygQsByuy7WbjIJKZ+0Blg1itLZl0Lp/pJGGg8SdJoQ== @@ -5051,7 +5098,7 @@ buffer-layout "^1.2.0" dotenv "10.0.0" -"@solana/spl-token@^0.3.5", "@solana/spl-token@^0.3.6", "@solana/spl-token@^0.3.7": +"@solana/spl-token@^0.3.4", "@solana/spl-token@^0.3.5", "@solana/spl-token@^0.3.6", "@solana/spl-token@^0.3.7": version "0.3.11" resolved "https://registry.yarnpkg.com/@solana/spl-token/-/spl-token-0.3.11.tgz#cdc10f9472b29b39c8983c92592cadd06627fb9a" integrity sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ== @@ -5555,7 +5602,7 @@ rpc-websockets "^8.0.1" superstruct "^1.0.4" -"@solana/web3.js@^1.90.0": +"@solana/web3.js@^1.54.0", "@solana/web3.js@^1.90.0", "@solana/web3.js@^1.93.0", "@solana/web3.js@^1.95.0": version "1.95.0" resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.95.0.tgz#9cf08383e7dcba212a73d78349cf9b25bc34764f" integrity sha512-iHwJ/HcWrF9qbnI1ctwI1UXHJ0vZXRpnt+lI5UcQIk8WvJNuQ5gV06icxzM6B7ojUES85Q1/FM4jZ49UQ8yZZQ== @@ -5649,6 +5696,21 @@ eventemitter3 "^5.0.0" lodash "^4.17.21" +"@solworks/soltoolkit-sdk@^0.0.23": + version "0.0.23" + resolved "https://registry.yarnpkg.com/@solworks/soltoolkit-sdk/-/soltoolkit-sdk-0.0.23.tgz#ef32d0aa79f888bcf0f639d280005b2e97cdc624" + integrity sha512-O6lXT3EBR4gmcjt0/33i97VMHVEImwXGi+4TNrDDdifn3tyOUB7V6PR1VGxlavQb9hqmVai3xhedg/rmbQzX7w== + dependencies: + "@solana/buffer-layout" "^4.0.0" + "@solana/spl-token" "^0.3.4" + "@solana/web3.js" "^1.54.0" + "@types/bn.js" "^5.1.0" + "@types/node" "^18.7.13" + "@types/node-fetch" "^2.6.2" + bn.js "^5.2.1" + decimal.js "^10.4.0" + typescript "^4.8.2" + "@stablelib/aead@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" @@ -5802,6 +5864,39 @@ dependencies: tslib "^2.4.0" +"@switchboard-xyz/common@^2.4.2": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@switchboard-xyz/common/-/common-2.4.3.tgz#3411374cafa230c010b03a5669ddace8a46f3e17" + integrity sha512-0Ucvk753Co48qcWBRRME28zcYIhQgZgIuFUE5kXxq7zSf1k9dFVUOwgcoQVr6LhsK3YAvJdGo1n8JzcxEzCBZQ== + dependencies: + "@solana/web3.js" "^1.93.0" + axios "^1.7.2" + big.js "^6.2.1" + bn.js "^5.2.1" + bs58 "^5.0.0" + cron-validator "^1.3.1" + decimal.js "^10.4.3" + form-data "^4.0.0" + lodash "^4.17.21" + protobufjs "^7.2.6" + yaml "^2.2.1" + +"@switchboard-xyz/on-demand@^1.1.39": + version "1.1.39" + resolved "https://registry.yarnpkg.com/@switchboard-xyz/on-demand/-/on-demand-1.1.39.tgz#dc78de9b3f0f6a45525c7a172b7faaccf0a5ab72" + integrity sha512-P/3CfCgDUiOrarkkU+xE5nMin0Sd8d9ghn5KT7/yKrLeLAd7R51Ybj5tt4D1G5m0EnEiC88yX3PyY0cttllFbw== + dependencies: + "@coral-xyz/anchor-30" "npm:@coral-xyz/anchor@0.30.1" + "@solana/web3.js" "^1.95.0" + "@solworks/soltoolkit-sdk" "^0.0.23" + "@switchboard-xyz/common" "^2.4.2" + axios "^1.2.0" + big.js "^6.2.1" + bs58 "^5.0.0" + js-yaml "^4.1.0" + node-cache "^5.1.2" + protobufjs "^7.2.6" + "@switchboard-xyz/sbv2-lite@^0.1.0": version "0.1.6" resolved "https://registry.yarnpkg.com/@switchboard-xyz/sbv2-lite/-/sbv2-lite-0.1.6.tgz#dc3fbb5b3b028dbd3c688b991bcc48a670131ddb" @@ -6382,6 +6477,14 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== +"@types/node-fetch@^2.6.2": + version "2.6.11" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" + integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== + dependencies: + "@types/node" "*" + form-data "^4.0.0" + "@types/node@*", "@types/node@>=13.7.0": version "20.14.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.2.tgz#a5f4d2bcb4b6a87bffcaa717718c5a0f208f4a18" @@ -6409,6 +6512,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.63.tgz#1788fa8da838dbb5f9ea994b834278205db6ca2b" integrity sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ== +"@types/node@^18.7.13": + version "18.19.39" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.39.tgz#c316340a5b4adca3aee9dcbf05de385978590593" + integrity sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ== + dependencies: + undici-types "~5.26.4" + "@types/node@^20.14.10": version "20.14.10" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.10.tgz#a1a218290f1b6428682e3af044785e5874db469a" @@ -6502,7 +6612,7 @@ dependencies: "@types/node" "*" -"@types/ws@^8.2.2": +"@types/ws@^8.2.2", "@types/ws@^8.5.3": version "8.5.11" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.11.tgz#90ad17b3df7719ce3e6bc32f83ff954d38656508" integrity sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w== @@ -7514,6 +7624,14 @@ axe-core@=4.7.0: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== +axios-retry@^3.8.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.9.1.tgz#c8924a8781c8e0a2c5244abf773deb7566b3830d" + integrity sha512-8PJDLJv7qTTMMwdnbMvrLYuvB47M81wRtxQmEdV5w4rgbTXTt+vtPkXwajOfOdSyv/wZICJOC+/UhXH4aQ/R+w== + dependencies: + "@babel/runtime" "^7.15.4" + is-retry-allowed "^2.2.0" + axios@^0.21.3: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -7543,6 +7661,15 @@ axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" +axios@^1.2.0, axios@^1.5.1, axios@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.2.tgz#b625db8a7051fbea61c35a3cbb3a1daa7b9c7621" + integrity sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" @@ -8398,6 +8525,11 @@ clone-response@^1.0.2: dependencies: mimic-response "^1.0.0" +clone@2.x: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -8650,6 +8782,11 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cron-validator@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/cron-validator/-/cron-validator-1.3.1.tgz#8f2fe430f92140df77f91178ae31fc1e3a48a20e" + integrity sha512-C1HsxuPCY/5opR55G5/WNzyEGDWFVG+6GLrA+fW/sCTcP6A6NTjUP2AK7B8n2PyFs90kDG2qzwm8LMheADku6A== + cross-fetch@3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" @@ -8941,7 +9078,7 @@ decimal.js-light@^2.4.1, decimal.js-light@^2.5.1: resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== -decimal.js@^10.2.0, decimal.js@^10.2.1, decimal.js@^10.3.0, decimal.js@^10.3.1: +decimal.js@^10.2.0, decimal.js@^10.2.1, decimal.js@^10.3.0, decimal.js@^10.3.1, decimal.js@^10.4.0, decimal.js@^10.4.3: version "10.4.3" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== @@ -10304,7 +10441,7 @@ focus-lock@^1.3.5: dependencies: tslib "^2.0.3" -follow-redirects@^1.14.0, follow-redirects@^1.14.4, follow-redirects@^1.14.7, follow-redirects@^1.14.9: +follow-redirects@^1.14.0, follow-redirects@^1.14.4, follow-redirects@^1.14.7, follow-redirects@^1.14.9, follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== @@ -11398,6 +11535,11 @@ is-retry-allowed@^1.0.0: resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== +is-retry-allowed@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz#88f34cbd236e043e71b6932d09b0c65fb7b4d71d" + integrity sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg== + is-set@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" @@ -13398,6 +13540,13 @@ node-addon-api@^8.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.0.0.tgz#5453b7ad59dd040d12e0f1a97a6fa1c765c5c9d2" integrity sha512-ipO7rsHEBqa9STO5C5T10fj732ml+5kLN1cAG8/jdHd56ldQeGj3Q7+scUS+VHK/qy1zLEwC4wMK5+yM0btPvw== +node-cache@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d" + integrity sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg== + dependencies: + clone "2.x" + node-fetch-native@^1.6.1, node-fetch-native@^1.6.2, node-fetch-native@^1.6.3: version "1.6.4" resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.4.tgz#679fc8fd8111266d47d7e72c379f1bed9acff06e" @@ -14128,7 +14277,7 @@ protobufjs@^6.10.2: "@types/node" ">=13.7.0" long "^4.0.0" -protobufjs@^7.2.5: +protobufjs@^7.2.5, protobufjs@^7.2.6: version "7.3.2" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.3.2.tgz#60f3b7624968868f6f739430cfbc8c9370e26df4" integrity sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg== @@ -14146,6 +14295,11 @@ protobufjs@^7.2.5: "@types/node" ">=13.7.0" long "^5.0.0" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + ps-tree@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd" @@ -14826,9 +14980,9 @@ rpc-websockets@7.11.0, rpc-websockets@^7.4.12, rpc-websockets@^7.4.2, rpc-websoc utf-8-validate "^5.0.2" rpc-websockets@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-8.0.2.tgz#c91cb680d6806101bdf7862897bcc43732e20da6" - integrity sha512-QZ8lneJTtIZTf9JBcdUn/im2qDynWRYPKtmF6P9DqtdzqSLebcllYWVQr5aQacAp7LBYPReOW9Ses98dNfO7cA== + version "8.0.1" + resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-8.0.1.tgz#fa76db08badc0b2f5cd66b5496debd2c404c94b1" + integrity sha512-PptrPRK40uQvifq5sCcObmqInVcZXhy+RRrirzdE5KUPvDI47y1wPvfckD2QzqngOU9xaPW/dT+G+b+wj6M1MQ== dependencies: eventemitter3 "^4.0.7" uuid "^8.3.2" @@ -15980,6 +16134,11 @@ ts-jest@^28.0.7: semver "7.x" yargs-parser "^21.0.1" +ts-log@^2.2.4: + version "2.2.5" + resolved "https://registry.yarnpkg.com/ts-log/-/ts-log-2.2.5.tgz#aef3252f1143d11047e2cb6f7cfaac7408d96623" + integrity sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA== + ts-mixer@^6.0.3: version "6.0.4" resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.4.tgz#1da39ceabc09d947a82140d9f09db0f84919ca28" @@ -16138,7 +16297,7 @@ typeforce@^1.18.0: resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== -typescript@^4.3.2, typescript@^4.6.2: +typescript@^4.3.2, typescript@^4.6.2, typescript@^4.8.2: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== @@ -16823,6 +16982,11 @@ ws@^8.16.0, ws@^8.5.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.0.tgz#d145d18eca2ed25aaf791a183903f7be5e295fea" integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow== +ws@^8.6.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + ws@~8.11.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" @@ -16878,6 +17042,11 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.2.1: + version "2.4.5" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.4.5.tgz#60630b206dd6d84df97003d33fc1ddf6296cca5e" + integrity sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg== + yargs-parser@20.x: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"