diff --git a/apps/price_pusher/README.md b/apps/price_pusher/README.md index a2279dd479..4c7cc5745d 100644 --- a/apps/price_pusher/README.md +++ b/apps/price_pusher/README.md @@ -83,14 +83,14 @@ To run the price pusher, please run the following commands, replacing the comman ```sh # Please run the two following commands once from the root of the repo to build the code. -npm install +pnpm install pnpm exec lerna run build --scope @pythnetwork/price-pusher --include-dependencies # Navigate to the price_pusher folder cd apps/price_pusher # For EVM -npm run start -- evm --endpoint wss://example-rpc.com \ +pnpm run start evm --endpoint wss://example-rpc.com \ --pyth-contract-address 0xff1a0f4744e8582DF...... \ --price-service-endpoint https://example-hermes-rpc.com \ --price-config-file "path/to/price-config.beta.sample.yaml" \ @@ -100,7 +100,7 @@ npm run start -- evm --endpoint wss://example-rpc.com \ [--override-gas-price-multiplier 1.1] # For Injective -npm run start -- injective --grpc-endpoint https://grpc-endpoint.com \ +pnpm run start injective --grpc-endpoint https://grpc-endpoint.com \ --pyth-contract-address inj1z60tg0... --price-service-endpoint "https://example-hermes-rpc.com" \ --price-config-file "path/to/price-config.beta.sample.yaml" \ --mnemonic-file "path/to/mnemonic.txt" \ @@ -110,7 +110,7 @@ npm run start -- injective --grpc-endpoint https://grpc-endpoint.com \ [--polling-frequency 5] # For Aptos -npm run start -- aptos --endpoint https://fullnode.testnet.aptoslabs.com/v1 \ +pnpm run start aptos --endpoint https://fullnode.testnet.aptoslabs.com/v1 \ --pyth-contract-address 0x7e783b349d3e89cf5931af376ebeadbfab855b3fa239b7ada8f5a92fbea6b387 \ --price-service-endpoint "https://example-hermes-rpc.com" \ --price-config-file "path/to/price-config.beta.sample.yaml" \ @@ -119,7 +119,7 @@ npm run start -- aptos --endpoint https://fullnode.testnet.aptoslabs.com/v1 \ [--polling-frequency 5] # For Sui -npm run start -- sui \ +pnpm run start sui \ --endpoint https://sui-testnet-rpc.allthatnode.com \ --pyth-package-id 0x975e063f398f720af4f33ec06a927f14ea76ca24f7f8dd544aa62ab9d5d15f44 \ --pyth-state-id 0xd8afde3a48b4ff7212bd6829a150f43f59043221200d63504d981f62bff2e27a \ @@ -134,7 +134,7 @@ npm run start -- sui \ [--num-gas-objects 30] # For Near -npm run start -- near \ +pnpm run start near \ --node-url https://rpc.testnet.near.org \ --network testnet \ --account-id payer.testnet \ @@ -146,7 +146,7 @@ npm run start -- near \ [--polling-frequency 5] # For Solana, using Jito (recommended) -npm run start -- solana \ +pnpm run start solana \ --endpoint https://api.mainnet-beta.solana.com \ --keypair-file ./id.json \ --shard-id 1 \ @@ -161,7 +161,7 @@ npm run start -- solana \ [--polling-frequency 5] # For Solana, using Solana RPC -npm run start -- solana \ +pnpm run start solana \ --endpoint https://api.devnet.solana.com \ --keypair-file ./id.json \ --shard-id 1 \ @@ -184,23 +184,35 @@ docker run public.ecr.aws/pyth-network/xc-price-pusher:v -- { @@ -46,7 +48,7 @@ export class AptosPriceListener extends ChainPriceListener { const price = multiplier * Number(priceItemRes.price_feed.price.price.magnitude); - console.log( + this.logger.debug( `Polled an Aptos on-chain price for feed ${this.priceIdToAlias.get( priceId )} (${priceId}).` @@ -57,11 +59,11 @@ export class AptosPriceListener extends ChainPriceListener { conf: priceItemRes.price_feed.price.conf, publishTime: Number(priceItemRes.price_feed.price.timestamp), }; - } catch (e) { - console.error( - `Polling Aptos on-chain price for ${priceId} failed. Error:` + } catch (err) { + this.logger.error( + err, + `Polling Aptos on-chain price for ${priceId} failed.` ); - console.error(e); return undefined; } } @@ -88,6 +90,7 @@ export class AptosPricePusher implements IPricePusher { constructor( private priceServiceConnection: PriceServiceConnection, + private logger: Logger, private pythContractAddress: string, private endpoint: string, private mnemonic: string, @@ -126,9 +129,8 @@ export class AptosPricePusher implements IPricePusher { try { // get the latest VAAs for updatePriceFeed and then push them priceFeedUpdateData = await this.getPriceFeedsUpdateData(priceIds); - } catch (e) { - console.error("Error fetching the latest vaas to push"); - console.error(e); + } catch (err) { + this.logger.error(err, "Error fetching the latest vaas to push."); return; } @@ -158,7 +160,10 @@ export class AptosPricePusher implements IPricePusher { const signedTx = await client.signTransaction(account, rawTx); const pendingTx = await client.submitTransaction(signedTx); - console.log("Successfully broadcasted txHash:", pendingTx.hash); + this.logger.debug( + { hash: pendingTx.hash }, + "Successfully broadcasted tx." + ); // Sometimes broadcasted txs don't make it on-chain and they cause our sequence number // to go out of sync. Missing transactions are rare and we don't want this check to block @@ -167,9 +172,8 @@ export class AptosPricePusher implements IPricePusher { this.waitForTransactionConfirmation(client, pendingTx.hash); return; - } catch (e: any) { - console.error("Error executing messages"); - console.error(e); + } catch (err: any) { + this.logger.error(err, "Error executing messages"); // Reset the sequence number to re-sync it (in case that was the issue) this.lastSequenceNumber = undefined; @@ -189,10 +193,12 @@ export class AptosPricePusher implements IPricePusher { timeoutSecs: 10, }); - console.log(`Transaction with txHash "${txHash}" confirmed.`); - } catch (e) { - console.error(`Transaction with txHash "${txHash}" failed to confirm.`); - console.error(e); + this.logger.info({ hash: txHash }, `Transaction confirmed.`); + } catch (err) { + this.logger.error( + { err, hash: txHash }, + `Transaction failed to confirm.` + ); this.lastSequenceNumber = undefined; } @@ -218,7 +224,7 @@ export class AptosPricePusher implements IPricePusher { this.lastSequenceNumber = Number( (await client.getAccount(account.address())).sequence_number ); - console.log( + this.logger.debug( `Fetched account sequence number: ${this.lastSequenceNumber}` ); return this.lastSequenceNumber; diff --git a/apps/price_pusher/src/aptos/command.ts b/apps/price_pusher/src/aptos/command.ts index b154d47196..a5e6e89a1a 100644 --- a/apps/price_pusher/src/aptos/command.ts +++ b/apps/price_pusher/src/aptos/command.ts @@ -11,6 +11,7 @@ import { APTOS_ACCOUNT_HD_PATH, } from "./aptos"; import { AptosAccount } from "aptos"; +import pino from "pino"; export default { command: "aptos", @@ -37,6 +38,9 @@ export default { ...options.pythContractAddress, ...options.pollingFrequency, ...options.pushingFrequency, + ...options.logLevel, + ...options.priceServiceConnectionLogLevel, + ...options.controllerLogLevel, }, handler: function (argv: any) { // FIXME: type checks for this @@ -49,44 +53,50 @@ export default { pushingFrequency, pollingFrequency, overrideGasPriceMultiplier, + logLevel, + priceServiceConnectionLogLevel, + controllerLogLevel, } = argv; + const logger = pino({ level: logLevel }); + const priceConfigs = readPriceConfigFile(priceConfigFile); const priceServiceConnection = new PriceServiceConnection( priceServiceEndpoint, { - logger: { - // Log only warnings and errors from the price service client - info: () => undefined, - warn: console.warn, - error: console.error, - debug: () => undefined, - trace: () => undefined, - }, + logger: logger.child( + { module: "PriceServiceConnection" }, + { level: priceServiceConnectionLogLevel } + ), } ); + const mnemonic = fs.readFileSync(mnemonicFile, "utf-8").trim(); const account = AptosAccount.fromDerivePath( APTOS_ACCOUNT_HD_PATH, mnemonic ); - console.log(`Pushing from account address: ${account.address()}`); + logger.info(`Pushing from account address: ${account.address()}`); const priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias })); const pythListener = new PythPriceListener( priceServiceConnection, - priceItems + priceItems, + logger.child({ module: "PythPriceListener" }) ); const aptosListener = new AptosPriceListener( pythContractAddress, endpoint, priceItems, + logger.child({ module: "AptosPriceListener" }), { pollingFrequency } ); + const aptosPusher = new AptosPricePusher( priceServiceConnection, + logger.child({ module: "AptosPricePusher" }), pythContractAddress, endpoint, mnemonic, @@ -98,6 +108,7 @@ export default { pythListener, aptosListener, aptosPusher, + logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency } ); diff --git a/apps/price_pusher/src/controller.ts b/apps/price_pusher/src/controller.ts index 13fc733e71..1632b0e92f 100644 --- a/apps/price_pusher/src/controller.ts +++ b/apps/price_pusher/src/controller.ts @@ -2,6 +2,7 @@ import { UnixTimestamp } from "@pythnetwork/price-service-client"; import { DurationInSeconds, sleep } from "./utils"; import { IPriceListener, IPricePusher } from "./interface"; import { PriceConfig, shouldUpdate, UpdateCondition } from "./price-config"; +import { Logger } from "pino"; export class Controller { private pushingFrequency: DurationInSeconds; @@ -10,6 +11,7 @@ export class Controller { private sourcePriceListener: IPriceListener, private targetPriceListener: IPriceListener, private targetChainPricePusher: IPricePusher, + private logger: Logger, config: { pushingFrequency: DurationInSeconds; } @@ -45,7 +47,8 @@ export class Controller { const priceShouldUpdate = shouldUpdate( priceConfig, sourceLatestPrice, - targetLatestPrice + targetLatestPrice, + this.logger ); if (priceShouldUpdate == UpdateCondition.YES) { pushThresholdMet = true; @@ -60,17 +63,21 @@ export class Controller { } } if (pushThresholdMet) { - console.log( - "Some of the above values passed the threshold. Will push the price." + this.logger.info( + { + priceIds: pricesToPush.map((priceConfig) => ({ + id: priceConfig.id, + alias: priceConfig.alias, + })), + }, + "Some of the checks triggered pushing update. Will push the updates for some feeds." ); // note that the priceIds are without leading "0x" const priceIds = pricesToPush.map((priceConfig) => priceConfig.id); this.targetChainPricePusher.updatePriceFeed(priceIds, pubTimesToPush); } else { - console.log( - "None of the above values passed the threshold. No push needed." - ); + this.logger.info("None of the checks were triggered. No push needed."); } await sleep(this.pushingFrequency * 1000); diff --git a/apps/price_pusher/src/evm/command.ts b/apps/price_pusher/src/evm/command.ts index 0164add9ed..6d3c82b126 100644 --- a/apps/price_pusher/src/evm/command.ts +++ b/apps/price_pusher/src/evm/command.ts @@ -1,12 +1,13 @@ import { PriceServiceConnection } from "@pythnetwork/price-service-client"; +import fs from "fs"; +import { Options } from "yargs"; import * as options from "../options"; import { readPriceConfigFile } from "../price-config"; -import fs from "fs"; import { PythPriceListener } from "../pyth-price-listener"; import { Controller } from "../controller"; -import { Options } from "yargs"; import { EvmPriceListener, EvmPricePusher, PythContractFactory } from "./evm"; import { getCustomGasStation } from "./custom-gas-station"; +import pino from "pino"; export default { command: "evm", @@ -72,6 +73,9 @@ export default { ...options.pythContractAddress, ...options.pollingFrequency, ...options.pushingFrequency, + ...options.logLevel, + ...options.priceServiceConnectionLogLevel, + ...options.controllerLogLevel, }, handler: function (argv: any) { // FIXME: type checks for this @@ -89,29 +93,32 @@ export default { overrideGasPriceMultiplierCap, gasLimit, updateFeeMultiplier, + logLevel, + priceServiceConnectionLogLevel, + controllerLogLevel, } = argv; + const logger = pino({ level: logLevel }); + const priceConfigs = readPriceConfigFile(priceConfigFile); const priceServiceConnection = new PriceServiceConnection( priceServiceEndpoint, { - logger: { - // Log only warnings and errors from the price service client - info: () => undefined, - warn: console.warn, - error: console.error, - debug: () => undefined, - trace: () => undefined, - }, + logger: logger.child( + { module: "PriceServiceConnection" }, + { level: priceServiceConnectionLogLevel } + ), } ); + const mnemonic = fs.readFileSync(mnemonicFile, "utf-8").trim(); const priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias })); const pythListener = new PythPriceListener( priceServiceConnection, - priceItems + priceItems, + logger.child({ module: "PythPriceListener" }) ); const pythContractFactory = new PythContractFactory( @@ -119,20 +126,30 @@ export default { mnemonic, pythContractAddress ); - console.log( + logger.info( `Pushing updates from wallet address: ${pythContractFactory .createWeb3PayerProvider() .getAddress()}` ); - const evmListener = new EvmPriceListener(pythContractFactory, priceItems, { - pollingFrequency, - }); + const evmListener = new EvmPriceListener( + pythContractFactory, + priceItems, + logger.child({ module: "EvmPriceListener" }), + { + pollingFrequency, + } + ); - const gasStation = getCustomGasStation(customGasStation, txSpeed); + const gasStation = getCustomGasStation( + logger.child({ module: "CustomGasStation" }), + customGasStation, + txSpeed + ); const evmPusher = new EvmPricePusher( priceServiceConnection, pythContractFactory, + logger.child({ module: "EvmPricePusher" }), overrideGasPriceMultiplier, overrideGasPriceMultiplierCap, updateFeeMultiplier, @@ -145,6 +162,7 @@ export default { pythListener, evmListener, evmPusher, + logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency } ); diff --git a/apps/price_pusher/src/evm/custom-gas-station.ts b/apps/price_pusher/src/evm/custom-gas-station.ts index 42a289f029..05f95e1f8a 100644 --- a/apps/price_pusher/src/evm/custom-gas-station.ts +++ b/apps/price_pusher/src/evm/custom-gas-station.ts @@ -6,6 +6,7 @@ import { txSpeeds, customGasChainIds, } from "../utils"; +import { Logger } from "pino"; type chainMethods = Record Promise>; @@ -15,7 +16,9 @@ export class CustomGasStation { private chainMethods: chainMethods = { 137: this.fetchMaticMainnetGasPrice.bind(this), }; - constructor(chain: number, speed: string) { + private logger: Logger; + constructor(logger: Logger, chain: number, speed: string) { + this.logger = logger; this.speed = verifyValidOption(speed, txSpeeds); this.chain = verifyValidOption(chain, customGasChainIds); } @@ -31,21 +34,22 @@ export class CustomGasStation { const gasPrice = jsonRes[this.speed].maxFee; const gweiGasPrice = Web3.utils.toWei(gasPrice.toFixed(2), "Gwei"); return gweiGasPrice.toString(); - } catch (e) { - console.error( + } catch (err) { + this.logger.error( + err, "Failed to fetch gas price from Matic mainnet. Returning undefined" ); - console.error(e); return undefined; } } } export function getCustomGasStation( + logger: Logger, customGasStation?: number, txSpeed?: string ) { if (customGasStation && txSpeed) { - return new CustomGasStation(customGasStation, txSpeed); + return new CustomGasStation(logger, customGasStation, txSpeed); } } diff --git a/apps/price_pusher/src/evm/evm.ts b/apps/price_pusher/src/evm/evm.ts index 1dc65203d8..3fc50e29ab 100644 --- a/apps/price_pusher/src/evm/evm.ts +++ b/apps/price_pusher/src/evm/evm.ts @@ -11,6 +11,7 @@ import AbstractPythAbi from "@pythnetwork/pyth-sdk-solidity/abis/AbstractPyth.js import HDWalletProvider from "@truffle/hdwallet-provider"; import Web3 from "web3"; import { HttpProvider, WebsocketProvider } from "web3-core"; +import { Logger } from "pino"; import { isWsEndpoint } from "../utils"; import { PriceServiceConnection, @@ -24,28 +25,33 @@ import { ProviderOrUrl } from "@truffle/hdwallet-provider/dist/constructor/types export class EvmPriceListener extends ChainPriceListener { private pythContractFactory: PythContractFactory; private pythContract: Contract; + private logger: Logger; constructor( pythContractFactory: PythContractFactory, priceItems: PriceItem[], + logger: Logger, config: { pollingFrequency: DurationInSeconds; } ) { - super("Evm", config.pollingFrequency, priceItems); + super(config.pollingFrequency, priceItems); this.pythContractFactory = pythContractFactory; this.pythContract = this.pythContractFactory.createPythContract(); + this.logger = logger; } // This method should be awaited on and once it finishes it has the latest value // for the given price feeds (if they exist). async start() { if (this.pythContractFactory.hasWebsocketProvider()) { - console.log("Subscribing to the target network pyth contract events..."); + this.logger.info( + "Subscribing to the target network pyth contract events..." + ); this.startSubscription(); } else { - console.log( + this.logger.info( "The target network RPC endpoint is not Websocket. " + "Listening for updates only via polling...." ); @@ -71,12 +77,15 @@ export class EvmPriceListener extends ChainPriceListener { private onPriceFeedUpdate(err: Error | null, event: EventData) { if (err !== null) { - console.error("PriceFeedUpdate EventEmitter received an error.."); + this.logger.error( + err, + "PriceFeedUpdate EventEmitter received an error.." + ); throw err; } const priceId = removeLeading0x(event.returnValues.id); - console.log( + this.logger.debug( `Received a new Evm PriceFeedUpdate event for price feed ${this.priceIdToAlias.get( priceId )} (${priceId}).` @@ -99,13 +108,12 @@ export class EvmPriceListener extends ChainPriceListener { priceRaw = await this.pythContract.methods .getPriceUnsafe(addLeading0x(priceId)) .call(); - } catch (e) { - console.error(`Polling on-chain price for ${priceId} failed. Error:`); - console.error(e); + } catch (err) { + this.logger.error(err, `Polling on-chain price for ${priceId} failed.`); return undefined; } - console.log( + this.logger.debug( `Polled an EVM on chain price for feed ${this.priceIdToAlias.get( priceId )} (${priceId}).` @@ -129,6 +137,7 @@ export class EvmPricePusher implements IPricePusher { constructor( private connection: PriceServiceConnection, pythContractFactory: PythContractFactory, + private logger: Logger, private overrideGasPriceMultiplier: number, private overrideGasPriceMultiplierCap: number, private updateFeeMultiplier: number, @@ -163,8 +172,6 @@ export class EvmPricePusher implements IPricePusher { priceIdsWith0x ); - console.log("Pushing ", priceIdsWith0x); - let updateFee; try { @@ -172,10 +179,11 @@ export class EvmPricePusher implements IPricePusher { .getUpdateFee(priceFeedUpdateData) .call(); updateFee = Number(updateFee) * (this.updateFeeMultiplier || 1); - console.log(`Update fee: ${updateFee}`); + this.logger.debug(`Update fee: ${updateFee}`); } catch (e: any) { - console.error( - "An unidentified error has occured when getting the update fee:" + this.logger.error( + e, + "An unidentified error has occured when getting the update fee." ); throw e; } @@ -213,7 +221,7 @@ export class EvmPricePusher implements IPricePusher { const txNonce = lastExecutedNonce + 1; - console.log(`Using gas price: ${gasPrice} and nonce: ${txNonce}`); + this.logger.debug(`Using gas price: ${gasPrice} and nonce: ${txNonce}`); this.pythContract.methods .updatePriceFeedsIfNecessary( @@ -228,7 +236,7 @@ export class EvmPricePusher implements IPricePusher { gasLimit: this.gasLimit, }) .on("transactionHash", (hash: string) => { - console.log(`Successful. Tx hash: ${hash}`); + this.logger.info({ hash }, "Price update successful"); }) .on("error", (err: Error, receipt?: TransactionReceipt) => { if (err.message.includes("revert")) { @@ -236,7 +244,8 @@ export class EvmPricePusher implements IPricePusher { // doesn't return any information why the call has reverted. Assuming that // the update data is valid there is no possible rejection cause other than // the target chain price being already updated. - console.log( + this.logger.info( + { err, receipt }, "Execution reverted. With high probability, the target chain price " + "has already updated, Skipping this push." ); @@ -248,7 +257,8 @@ export class EvmPricePusher implements IPricePusher { err.message.includes("nonce too low") || err.message.includes("invalid nonce") ) { - console.log( + this.logger.info( + { err, receipt }, "The nonce is incorrect (are multiple users using this account?). Skipping this push." ); return; @@ -259,7 +269,8 @@ export class EvmPricePusher implements IPricePusher { // LastPushAttempt was stored with the class // Next time the update will be executing, it will check the last attempt // and increase the gas price accordingly. - console.log( + this.logger.info( + { err, receipt }, "The transaction failed with error: max fee per gas less than block base fee " ); return; @@ -268,12 +279,16 @@ export class EvmPricePusher implements IPricePusher { if ( err.message.includes("sender doesn't have enough funds to send tx.") ) { - console.error("Payer is out of balance, please top it up."); + this.logger.error( + { err, receipt }, + "Payer is out of balance, please top it up." + ); throw err; } if (err.message.includes("transaction underpriced")) { - console.error( + this.logger.error( + { err, receipt }, "The gas price of the transaction is too low. Skipping this push. " + "You might want to use a custom gas station or increase the override gas price " + "multiplier to increase the likelihood of the transaction landing on-chain." @@ -282,14 +297,17 @@ export class EvmPricePusher implements IPricePusher { } if (err.message.includes("could not replace existing tx")) { - console.log( + this.logger.error( + { err, receipt }, "A transaction with the same nonce has been mined and this one is no longer needed." ); return; } - console.error("An unidentified error has occured:"); - console.error(receipt); + this.logger.error( + { err, receipt }, + "An unidentified error has occured." + ); throw err; }); diff --git a/apps/price_pusher/src/injective/command.ts b/apps/price_pusher/src/injective/command.ts index 3c20186d12..911e075417 100644 --- a/apps/price_pusher/src/injective/command.ts +++ b/apps/price_pusher/src/injective/command.ts @@ -7,6 +7,7 @@ import { PythPriceListener } from "../pyth-price-listener"; import { Controller } from "../controller"; import { Options } from "yargs"; import { getNetworkInfo } from "@injectivelabs/networks"; +import pino from "pino"; export default { command: "injective", @@ -35,6 +36,9 @@ export default { ...options.pythContractAddress, ...options.pollingFrequency, ...options.pushingFrequency, + ...options.logLevel, + ...options.priceServiceConnectionLogLevel, + ...options.controllerLogLevel, }, handler: function (argv: any) { // FIXME: type checks for this @@ -48,8 +52,13 @@ export default { pushingFrequency, pollingFrequency, network, + logLevel, + priceServiceConnectionLogLevel, + controllerLogLevel, } = argv; + const logger = pino({ level: logLevel }); + if (network !== "testnet" && network !== "mainnet") { throw new Error("Please specify network. One of [testnet, mainnet]"); } @@ -58,14 +67,10 @@ export default { const priceServiceConnection = new PriceServiceConnection( priceServiceEndpoint, { - logger: { - // Log only warnings and errors from the price service client - info: () => undefined, - warn: console.warn, - error: console.error, - debug: () => undefined, - trace: () => undefined, - }, + logger: logger.child( + { module: "PriceServiceConnection" }, + { level: priceServiceConnectionLogLevel } + ), } ); const mnemonic = fs.readFileSync(mnemonicFile, "utf-8").trim(); @@ -74,13 +79,15 @@ export default { const pythListener = new PythPriceListener( priceServiceConnection, - priceItems + priceItems, + logger.child({ module: "PythPriceListener" }) ); const injectiveListener = new InjectivePriceListener( pythContractAddress, grpcEndpoint, priceItems, + logger.child({ module: "InjectivePriceListener" }), { pollingFrequency, } @@ -89,6 +96,7 @@ export default { priceServiceConnection, pythContractAddress, grpcEndpoint, + logger.child({ module: "InjectivePricePusher" }), mnemonic, { chainId: getNetworkInfo(network).chainId, @@ -101,6 +109,7 @@ export default { pythListener, injectiveListener, injectivePusher, + logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency } ); diff --git a/apps/price_pusher/src/injective/injective.ts b/apps/price_pusher/src/injective/injective.ts index d524ee1e03..d648131841 100644 --- a/apps/price_pusher/src/injective/injective.ts +++ b/apps/price_pusher/src/injective/injective.ts @@ -19,6 +19,7 @@ import { TxResponse, createTransactionFromMsg, } from "@injectivelabs/sdk-ts"; +import { Logger } from "pino"; import { Account } from "@injectivelabs/sdk-ts/dist/cjs/client/chain/types/auth"; const DEFAULT_GAS_PRICE = 500000000; @@ -46,11 +47,12 @@ export class InjectivePriceListener extends ChainPriceListener { private pythContractAddress: string, private grpcEndpoint: string, priceItems: PriceItem[], + private logger: Logger, config: { pollingFrequency: DurationInSeconds; } ) { - super("Injective", config.pollingFrequency, priceItems); + super(config.pollingFrequency, priceItems); } async getOnChainPriceInfo( @@ -66,13 +68,12 @@ export class InjectivePriceListener extends ChainPriceListener { const json = Buffer.from(data).toString(); priceQueryResponse = JSON.parse(json); - } catch (e) { - console.error(`Polling on-chain price for ${priceId} failed. Error:`); - console.error(e); + } catch (err) { + this.logger.error(err, `Polling on-chain price for ${priceId} failed.`); return undefined; } - console.log( + this.logger.debug( `Polled an Injective on chain price for feed ${this.priceIdToAlias.get( priceId )} (${priceId}).` @@ -100,6 +101,7 @@ export class InjectivePricePusher implements IPricePusher { private priceServiceConnection: PriceServiceConnection, private pythContractAddress: string, private grpcEndpoint: string, + private logger: Logger, mnemonic: string, chainConfig?: Partial ) { @@ -207,9 +209,8 @@ export class InjectivePricePusher implements IPricePusher { try { // get the latest VAAs for updatePriceFeed and then push them priceFeedUpdateObject = await this.getPriceFeedUpdateObject(priceIds); - } catch (e) { - console.error("Error fetching the latest vaas to push"); - console.error(e); + } catch (err) { + this.logger.error(err, "Error fetching the latest vaas to push"); return; } @@ -229,9 +230,8 @@ export class InjectivePricePusher implements IPricePusher { const json = Buffer.from(data).toString(); updateFeeQueryResponse = JSON.parse(json); - } catch (e) { - console.error("Error fetching update fee"); - console.error(e); + } catch (err) { + this.logger.error(err, "Error fetching update fee"); return; } @@ -244,22 +244,21 @@ export class InjectivePricePusher implements IPricePusher { }); const rs = await this.signAndBroadcastMsg(executeMsg); - console.log("Succesfully broadcasted txHash:", rs.txHash); - } catch (e: any) { - if (e.message.match(/account inj[a-zA-Z0-9]+ not found/) !== null) { - console.error(e); + this.logger.info({ hash: rs.txHash }, "Succesfully broadcasted txHash"); + } catch (err: any) { + if (err.message.match(/account inj[a-zA-Z0-9]+ not found/) !== null) { + this.logger.error(err, "Account not found"); throw new Error("Please check the mnemonic"); } if ( - e.message.match(/insufficient/) !== null && - e.message.match(/funds/) !== null + err.message.match(/insufficient/) !== null && + err.message.match(/funds/) !== null ) { - console.error(e); + this.logger.error(err, "Insufficient funds"); throw new Error("Insufficient funds"); } - console.error("Error executing messages"); - console.log(e); + this.logger.error(err, "Error executing messages"); } } } diff --git a/apps/price_pusher/src/interface.ts b/apps/price_pusher/src/interface.ts index 077b1580e8..a126da7025 100644 --- a/apps/price_pusher/src/interface.ts +++ b/apps/price_pusher/src/interface.ts @@ -23,7 +23,6 @@ export abstract class ChainPriceListener implements IPriceListener { protected priceIdToAlias: Map; constructor( - private chain: string, private pollingFrequency: DurationInSeconds, protected priceItems: PriceItem[] ) { @@ -34,9 +33,6 @@ export abstract class ChainPriceListener implements IPriceListener { } async start() { - console.log( - `Polling the prices on ${this.chain} every ${this.pollingFrequency} seconds...` - ); setInterval(this.pollPrices.bind(this), this.pollingFrequency * 1000); await this.pollPrices(); diff --git a/apps/price_pusher/src/near/command.ts b/apps/price_pusher/src/near/command.ts index 7d4a854e96..da93c14cfe 100644 --- a/apps/price_pusher/src/near/command.ts +++ b/apps/price_pusher/src/near/command.ts @@ -5,6 +5,7 @@ import { PythPriceListener } from "../pyth-price-listener"; import { Controller } from "../controller"; import { Options } from "yargs"; import { NearAccount, NearPriceListener, NearPricePusher } from "./near"; +import pino from "pino"; export default { command: "near", @@ -36,6 +37,9 @@ export default { ...options.pythContractAddress, ...options.pollingFrequency, ...options.pushingFrequency, + ...options.logLevel, + ...options.priceServiceConnectionLogLevel, + ...options.controllerLogLevel, }, handler: function (argv: any) { // FIXME: type checks for this @@ -49,20 +53,21 @@ export default { pythContractAddress, pushingFrequency, pollingFrequency, + logLevel, + priceServiceConnectionLogLevel, + controllerLogLevel, } = argv; + const logger = pino({ level: logLevel }); + const priceConfigs = readPriceConfigFile(priceConfigFile); const priceServiceConnection = new PriceServiceConnection( priceServiceEndpoint, { - logger: { - // Log only warnings and errors from the price service client - info: () => undefined, - warn: console.warn, - error: console.error, - debug: () => undefined, - trace: () => undefined, - }, + logger: logger.child( + { module: "PriceServiceConnection" }, + { level: priceServiceConnectionLogLevel } + ), } ); @@ -70,7 +75,8 @@ export default { const pythListener = new PythPriceListener( priceServiceConnection, - priceItems + priceItems, + logger ); const nearAccount = new NearAccount( @@ -81,17 +87,27 @@ export default { pythContractAddress ); - const nearListener = new NearPriceListener(nearAccount, priceItems, { - pollingFrequency, - }); + const nearListener = new NearPriceListener( + nearAccount, + priceItems, + logger.child({ module: "NearPriceListener" }), + { + pollingFrequency, + } + ); - const nearPusher = new NearPricePusher(nearAccount, priceServiceConnection); + const nearPusher = new NearPricePusher( + nearAccount, + priceServiceConnection, + logger.child({ module: "NearPricePusher" }) + ); const controller = new Controller( priceConfigs, pythListener, nearListener, nearPusher, + logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency } ); diff --git a/apps/price_pusher/src/near/near.ts b/apps/price_pusher/src/near/near.ts index dc304779df..d805ff38c2 100644 --- a/apps/price_pusher/src/near/near.ts +++ b/apps/price_pusher/src/near/near.ts @@ -21,23 +21,25 @@ import { FinalExecutionOutcome, } from "near-api-js/lib/providers/provider"; import { InMemoryKeyStore } from "near-api-js/lib/key_stores"; +import { Logger } from "pino"; export class NearPriceListener extends ChainPriceListener { constructor( private account: NearAccount, priceItems: PriceItem[], + private logger: Logger, config: { pollingFrequency: DurationInSeconds; } ) { - super("near", config.pollingFrequency, priceItems); + super(config.pollingFrequency, priceItems); } async getOnChainPriceInfo(priceId: string): Promise { try { const priceRaw = await this.account.getPriceUnsafe(priceId); - console.log( + this.logger.debug( `Polled a NEAR on chain price for feed ${this.priceIdToAlias.get( priceId )} (${priceId}) ${JSON.stringify(priceRaw)}.` @@ -52,9 +54,8 @@ export class NearPriceListener extends ChainPriceListener { } else { return undefined; } - } catch (e) { - console.error(`Polling on-chain price for ${priceId} failed. Error:`); - console.error(e); + } catch (err) { + this.logger.error(err, `Polling on-chain price for ${priceId} failed.:`); return undefined; } } @@ -63,7 +64,8 @@ export class NearPriceListener extends ChainPriceListener { export class NearPricePusher implements IPricePusher { constructor( private account: NearAccount, - private connection: PriceServiceConnection + private connection: PriceServiceConnection, + private logger: Logger ) {} async updatePriceFeed( @@ -80,20 +82,18 @@ export class NearPricePusher implements IPricePusher { let priceFeedUpdateData; try { priceFeedUpdateData = await this.getPriceFeedsUpdateData(priceIds); - } catch (e: any) { - console.error(new Date(), "getPriceFeedsUpdateData failed:", e); + } catch (err: any) { + this.logger.error(err, "getPriceFeedsUpdateData failed"); return; } - console.log("Pushing ", priceIds); - for (const data of priceFeedUpdateData) { let updateFee; try { updateFee = await this.account.getUpdateFeeEstimate(data); - console.log(`Update fee: ${updateFee}`); - } catch (e: any) { - console.error(new Date(), "getUpdateFeeEstimate failed:", e); + this.logger.debug(`Update fee: ${updateFee}`); + } catch (err: any) { + this.logger.error(err, "getUpdateFeeEstimate failed"); continue; } @@ -116,20 +116,15 @@ export class NearPricePusher implements IPricePusher { true ); if (is_success) { - console.log( - new Date(), - "updatePriceFeeds successful. Tx hash: ", - outcome["transaction"]["hash"] + this.logger.info( + { hash: outcome["transaction"]["hash"] }, + "updatePriceFeeds successful." ); } else { - console.error( - new Date(), - "updatePriceFeeds failed:", - JSON.stringify(failureMessages, undefined, 2) - ); + this.logger.error({ failureMessages }, "updatePriceFeeds failed"); } - } catch (e: any) { - console.error(new Date(), "updatePriceFeeds failed:", e); + } catch (err: any) { + this.logger.error(err, "updatePriceFeeds failed"); } } } diff --git a/apps/price_pusher/src/options.ts b/apps/price_pusher/src/options.ts index 126ccced07..95c6497389 100644 --- a/apps/price_pusher/src/options.ts +++ b/apps/price_pusher/src/options.ts @@ -56,3 +56,33 @@ export const mnemonicFile = { required: true, } as Options, }; + +export const logLevel = { + "log-level": { + description: "Log level", + type: "string", + required: false, + default: "info", + choices: ["trace", "debug", "info", "warn", "error"], + } as Options, +}; + +export const priceServiceConnectionLogLevel = { + "price-service-connection-log-level": { + description: "Log level for the price service connection.", + type: "string", + required: false, + default: "warn", + choices: ["trace", "debug", "info", "warn", "error"], + } as Options, +}; + +export const controllerLogLevel = { + "controller-log-level": { + description: "Log level for the controller.", + type: "string", + required: false, + default: "info", + choices: ["trace", "debug", "info", "warn", "error"], + } as Options, +}; diff --git a/apps/price_pusher/src/price-config.ts b/apps/price_pusher/src/price-config.ts index 5f0f515e55..76a6cbc6ac 100644 --- a/apps/price_pusher/src/price-config.ts +++ b/apps/price_pusher/src/price-config.ts @@ -2,6 +2,7 @@ import { HexString } from "@pythnetwork/price-service-client"; import Joi from "joi"; import YAML from "yaml"; import fs from "fs"; +import { Logger } from "pino"; import { DurationInSeconds, PctNumber, removeLeading0x } from "./utils"; import { PriceInfo } from "./interface"; @@ -90,7 +91,8 @@ export enum UpdateCondition { export function shouldUpdate( priceConfig: PriceConfig, sourceLatestPrice: PriceInfo | undefined, - targetLatestPrice: PriceInfo | undefined + targetLatestPrice: PriceInfo | undefined, + logger: Logger ): UpdateCondition { const priceId = priceConfig.id; @@ -101,7 +103,7 @@ export function shouldUpdate( // It means that price never existed there. So we should push the latest price feed. if (targetLatestPrice === undefined) { - console.log( + logger.info( `${priceConfig.alias} (${priceId}) is not available on the target network. Pushing the price.` ); return UpdateCondition.YES; @@ -125,13 +127,10 @@ export function shouldUpdate( (Number(sourceLatestPrice.conf) / Number(sourceLatestPrice.price)) * 100 ); - console.log(`Analyzing price ${priceConfig.alias} (${priceId})`); - - console.log("Source latest price: ", sourceLatestPrice); - console.log("Target latest price: ", targetLatestPrice); - - console.log( - `Time difference: ${timeDifference} (< ${priceConfig.timeDifference}? / early: < ${priceConfig.earlyUpdateTimeDifference}) OR ` + + logger.info( + { sourcePrice: sourceLatestPrice, targetPrice: targetLatestPrice }, + `Analyzing price ${priceConfig.alias} (${priceId}). ` + + `Time difference: ${timeDifference} (< ${priceConfig.timeDifference}? / early: < ${priceConfig.earlyUpdateTimeDifference}) OR ` + `Price deviation: ${priceDeviationPct.toFixed(5)}% (< ${ priceConfig.priceDeviation }%? / early: < ${priceConfig.earlyUpdatePriceDeviation}%?) OR ` + diff --git a/apps/price_pusher/src/pyth-price-listener.ts b/apps/price_pusher/src/pyth-price-listener.ts index 5cd734ff12..c69a98077e 100644 --- a/apps/price_pusher/src/pyth-price-listener.ts +++ b/apps/price_pusher/src/pyth-price-listener.ts @@ -4,20 +4,27 @@ import { PriceServiceConnection, } from "@pythnetwork/price-service-client"; import { PriceInfo, IPriceListener, PriceItem } from "./interface"; +import { Logger } from "pino"; export class PythPriceListener implements IPriceListener { private connection: PriceServiceConnection; private priceIds: HexString[]; private priceIdToAlias: Map; private latestPriceInfo: Map; + private logger: Logger; - constructor(connection: PriceServiceConnection, priceItems: PriceItem[]) { + constructor( + connection: PriceServiceConnection, + priceItems: PriceItem[], + logger: Logger + ) { this.connection = connection; this.priceIds = priceItems.map((priceItem) => priceItem.id); this.priceIdToAlias = new Map( priceItems.map((priceItem) => [priceItem.id, priceItem.alias]) ); this.latestPriceInfo = new Map(); + this.logger = logger; } // This method should be awaited on and once it finishes it has the latest value @@ -42,7 +49,7 @@ export class PythPriceListener implements IPriceListener { } private onNewPriceFeed(priceFeed: PriceFeed) { - console.log( + this.logger.debug( `Received new price feed update from Pyth price service: ${this.priceIdToAlias.get( priceFeed.id )} ${priceFeed.id}` diff --git a/apps/price_pusher/src/solana/command.ts b/apps/price_pusher/src/solana/command.ts index 6ad4584790..6b972c1622 100644 --- a/apps/price_pusher/src/solana/command.ts +++ b/apps/price_pusher/src/solana/command.ts @@ -18,6 +18,8 @@ import { SearcherClient, searcherClient, } from "jito-ts/dist/sdk/block-engine/searcher"; +import pino from "pino"; +import { Logger } from "pino"; export default { command: "solana", @@ -69,6 +71,9 @@ export default { ...options.pythContractAddress, ...options.pollingFrequency, ...options.pushingFrequency, + ...options.logLevel, + ...options.priceServiceConnectionLogLevel, + ...options.controllerLogLevel, }, handler: function (argv: any) { const { @@ -85,21 +90,22 @@ export default { jitoKeypairFile, jitoTipLamports, jitoBundleSize, + logLevel, + priceServiceConnectionLogLevel, + controllerLogLevel, } = argv; + const logger = pino({ level: logLevel }); + const priceConfigs = readPriceConfigFile(priceConfigFile); const priceServiceConnection = new PriceServiceConnection( priceServiceEndpoint, { - logger: { - // Log only warnings and errors from the price service client - info: () => undefined, - warn: console.warn, - error: console.error, - debug: () => undefined, - trace: () => undefined, - }, + logger: logger.child( + { module: "PriceServiceConnection" }, + { level: priceServiceConnectionLogLevel } + ), } ); @@ -107,7 +113,8 @@ export default { const pythListener = new PythPriceListener( priceServiceConnection, - priceItems + priceItems, + logger.child({ module: "PythPriceListener" }) ); const wallet = new NodeWallet( @@ -132,17 +139,19 @@ export default { solanaPricePusher = new SolanaPricePusherJito( pythSolanaReceiver, priceServiceConnection, + logger.child({ module: "SolanaPricePusherJito" }), shardId, jitoTipLamports, jitoClient, jitoBundleSize ); - onBundleResult(jitoClient); + onBundleResult(jitoClient, logger.child({ module: "JitoClient" })); } else { solanaPricePusher = new SolanaPricePusher( pythSolanaReceiver, priceServiceConnection, + logger.child({ module: "SolanaPricePusher" }), shardId, computeUnitPriceMicroLamports ); @@ -152,6 +161,7 @@ export default { pythSolanaReceiver, shardId, priceItems, + logger.child({ module: "SolanaPriceListener" }), { pollingFrequency } ); @@ -160,6 +170,7 @@ export default { pythListener, solanaPriceListener, solanaPricePusher, + logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency } ); @@ -167,11 +178,11 @@ export default { }, }; -export const onBundleResult = (c: SearcherClient) => { +export const onBundleResult = (c: SearcherClient, logger: Logger) => { c.onBundleResult( () => undefined, - (e) => { - console.log("Error in bundle result: ", e); + (err) => { + logger.error(err, "Error in bundle result"); } ); }; diff --git a/apps/price_pusher/src/solana/solana.ts b/apps/price_pusher/src/solana/solana.ts index da213bd1c0..911d3e24ef 100644 --- a/apps/price_pusher/src/solana/solana.ts +++ b/apps/price_pusher/src/solana/solana.ts @@ -13,17 +13,19 @@ import { } from "@pythnetwork/solana-utils"; import { SearcherClient } from "jito-ts/dist/sdk/block-engine/searcher"; import { sliceAccumulatorUpdateData } from "@pythnetwork/price-service-sdk"; +import { Logger } from "pino"; export class SolanaPriceListener extends ChainPriceListener { constructor( private pythSolanaReceiver: PythSolanaReceiver, private shardId: number, priceItems: PriceItem[], + private logger: Logger, config: { pollingFrequency: DurationInSeconds; } ) { - super("solana", config.pollingFrequency, priceItems); + super(config.pollingFrequency, priceItems); } async getOnChainPriceInfo(priceId: string): Promise { @@ -33,7 +35,7 @@ export class SolanaPriceListener extends ChainPriceListener { this.shardId, Buffer.from(priceId, "hex") ); - console.log( + this.logger.debug( `Polled a Solana on chain price for feed ${this.priceIdToAlias.get( priceId )} (${priceId}).` @@ -47,9 +49,8 @@ export class SolanaPriceListener extends ChainPriceListener { } else { return undefined; } - } catch (e) { - console.error(`Polling on-chain price for ${priceId} failed. Error:`); - console.error(e); + } catch (err) { + this.logger.error({ err, priceId }, `Polling on-chain price failed.`); return undefined; } } @@ -59,6 +60,7 @@ export class SolanaPricePusher implements IPricePusher { constructor( private pythSolanaReceiver: PythSolanaReceiver, private priceServiceConnection: PriceServiceConnection, + private logger: Logger, private shardId: number, private computeUnitPriceMicroLamports: number ) {} @@ -77,8 +79,8 @@ export class SolanaPricePusher implements IPricePusher { priceFeedUpdateData = await this.priceServiceConnection.getLatestVaas( priceIds ); - } catch (e: any) { - console.error(new Date(), "getPriceFeedsUpdateData failed:", e); + } catch (err: any) { + this.logger.error(err, "getPriceFeedsUpdateData failed:"); return; } @@ -96,14 +98,14 @@ export class SolanaPricePusher implements IPricePusher { }); try { - await sendTransactions( + const signatures = await sendTransactions( transactions, this.pythSolanaReceiver.connection, this.pythSolanaReceiver.wallet ); - console.log(new Date(), "updatePriceFeed successful"); - } catch (e: any) { - console.error(new Date(), "updatePriceFeed failed", e); + this.logger.info({ signatures }, "updatePriceFeed successful"); + } catch (err: any) { + this.logger.error(err, "updatePriceFeed failed"); return; } } @@ -115,6 +117,7 @@ export class SolanaPricePusherJito implements IPricePusher { constructor( private pythSolanaReceiver: PythSolanaReceiver, private priceServiceConnection: PriceServiceConnection, + private logger: Logger, private shardId: number, private jitoTipLamports: number, private searcherClient: SearcherClient, @@ -131,8 +134,8 @@ export class SolanaPricePusherJito implements IPricePusher { priceFeedUpdateData = await this.priceServiceConnection.getLatestVaas( priceIds ); - } catch (e: any) { - console.error(new Date(), "getPriceFeedsUpdateData failed:", e); + } catch (err: any) { + this.logger.error(err, "getPriceFeedsUpdateData failed"); return; } diff --git a/apps/price_pusher/src/sui/command.ts b/apps/price_pusher/src/sui/command.ts index 52f2cfe009..ea57034c94 100644 --- a/apps/price_pusher/src/sui/command.ts +++ b/apps/price_pusher/src/sui/command.ts @@ -7,6 +7,7 @@ import { Controller } from "../controller"; import { Options } from "yargs"; import { SuiPriceListener, SuiPricePusher } from "./sui"; import { Ed25519Keypair } from "@mysten/sui.js/keypairs/ed25519"; +import pino from "pino"; export default { command: "sui", @@ -68,6 +69,9 @@ export default { ...options.mnemonicFile, ...options.pollingFrequency, ...options.pushingFrequency, + ...options.logLevel, + ...options.priceServiceConnectionLogLevel, + ...options.controllerLogLevel, }, handler: async function (argv: any) { const { @@ -83,20 +87,21 @@ export default { ignoreGasObjects, gasBudget, accountIndex, + logLevel, + priceServiceConnectionLogLevel, + controllerLogLevel, } = argv; + const logger = pino({ level: logLevel }); + const priceConfigs = readPriceConfigFile(priceConfigFile); const priceServiceConnection = new PriceServiceConnection( priceServiceEndpoint, { - logger: { - // Log only warnings and errors from the price service client - info: () => undefined, - warn: console.warn, - error: console.error, - debug: () => undefined, - trace: () => undefined, - }, + logger: logger.child( + { module: "PriceServiceConnection" }, + { level: priceServiceConnectionLogLevel } + ), priceFeedRequestConfig: { binary: true, }, @@ -107,7 +112,7 @@ export default { mnemonic, `m/44'/784'/${accountIndex}'/0'/0'` ); - console.log( + logger.info( `Pushing updates from wallet address: ${keypair .getPublicKey() .toSuiAddress()}` @@ -117,7 +122,8 @@ export default { const pythListener = new PythPriceListener( priceServiceConnection, - priceItems + priceItems, + logger.child({ module: "PythPriceListener" }) ); const suiListener = new SuiPriceListener( @@ -125,10 +131,12 @@ export default { wormholeStateId, endpoint, priceItems, + logger.child({ module: "SuiPriceListener" }), { pollingFrequency } ); const suiPusher = await SuiPricePusher.createWithAutomaticGasPool( priceServiceConnection, + logger.child({ module: "SuiPricePusher" }), pythStateId, wormholeStateId, endpoint, @@ -143,6 +151,7 @@ export default { pythListener, suiListener, suiPusher, + logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency } ); diff --git a/apps/price_pusher/src/sui/sui.ts b/apps/price_pusher/src/sui/sui.ts index 71bf4359cb..2e341c9832 100644 --- a/apps/price_pusher/src/sui/sui.ts +++ b/apps/price_pusher/src/sui/sui.ts @@ -10,6 +10,7 @@ import { SuiPythClient } from "@pythnetwork/pyth-sui-js"; import { Ed25519Keypair } from "@mysten/sui.js/keypairs/ed25519"; import { TransactionBlock } from "@mysten/sui.js/transactions"; import { SuiClient, SuiObjectRef, PaginatedCoins } from "@mysten/sui.js/client"; +import { Logger } from "pino"; const GAS_FEE_FOR_SPLIT = 2_000_000_000; // TODO: read this from on chain config @@ -22,23 +23,26 @@ type SuiAddress = string; export class SuiPriceListener extends ChainPriceListener { private pythClient: SuiPythClient; private provider: SuiClient; + private logger: Logger; constructor( pythStateId: ObjectId, wormholeStateId: ObjectId, endpoint: string, priceItems: PriceItem[], + logger: Logger, config: { pollingFrequency: DurationInSeconds; } ) { - super("sui", config.pollingFrequency, priceItems); + super(config.pollingFrequency, priceItems); this.provider = new SuiClient({ url: endpoint }); this.pythClient = new SuiPythClient( this.provider, pythStateId, wormholeStateId ); + this.logger = logger; } async getOnChainPriceInfo(priceId: string): Promise { @@ -78,9 +82,11 @@ export class SuiPriceListener extends ChainPriceListener { conf, publishTime: Number(timestamp), }; - } catch (e) { - console.error(`Polling Sui on-chain price for ${priceId} failed. Error:`); - console.error(e); + } catch (err) { + this.logger.error( + err, + `Polling Sui on-chain price for ${priceId} failed.` + ); return undefined; } } @@ -104,6 +110,7 @@ export class SuiPricePusher implements IPricePusher { constructor( private readonly signer: Ed25519Keypair, private readonly provider: SuiClient, + private logger: Logger, private priceServiceConnection: PriceServiceConnection, private pythPackageId: string, private pythStateId: string, @@ -157,6 +164,7 @@ export class SuiPricePusher implements IPricePusher { */ static async createWithAutomaticGasPool( priceServiceConnection: PriceServiceConnection, + logger: Logger, pythStateId: string, wormholeStateId: string, endpoint: string, @@ -185,7 +193,8 @@ export class SuiPricePusher implements IPricePusher { keypair, provider, numGasObjects, - ignoreGasObjects + ignoreGasObjects, + logger ); const pythClient = new SuiPythClient( @@ -197,6 +206,7 @@ export class SuiPricePusher implements IPricePusher { return new SuiPricePusher( keypair, provider, + logger, priceServiceConnection, pythPackageId, pythStateId, @@ -222,7 +232,7 @@ export class SuiPricePusher implements IPricePusher { throw new Error("Invalid arguments"); if (this.gasPool.length === 0) { - console.warn("Skipping update: no available gas coin."); + this.logger.warn("Skipping update: no available gas coin."); return; } @@ -266,7 +276,7 @@ export class SuiPricePusher implements IPricePusher { private async sendTransactionBlock(tx: TransactionBlock): Promise { const gasObject = this.gasPool.shift(); if (gasObject === undefined) { - console.warn("No available gas coin. Skipping push."); + this.logger.warn("No available gas coin. Skipping push."); return; } @@ -286,31 +296,29 @@ export class SuiPricePusher implements IPricePusher { ?.map((obj) => obj.reference) .find((ref) => ref.objectId === gasObject.objectId); - console.log( - "Successfully updated price with transaction digest ", - result.digest + this.logger.info( + { hash: result.digest }, + "Successfully updated price with transaction digest" ); - } catch (e: any) { - console.log("Error when signAndExecuteTransactionBlock"); + } catch (err: any) { if ( - String(e).includes("Balance of gas object") || - String(e).includes("GasBalanceTooLow") + String(err).includes("Balance of gas object") || + String(err).includes("GasBalanceTooLow") ) { + this.logger.error(err, "Insufficient gas balance"); // If the error is caused by insufficient gas, we should panic - throw e; + throw err; } else { + this.logger.error( + err, + "Failed to update price. Trying to refresh gas object references." + ); // Refresh the coin object here in case the error is caused by an object version mismatch. nextGasObject = await SuiPricePusher.tryRefreshObjectReference( this.provider, gasObject ); } - console.error(e); - - if ("data" in e) { - console.error("Error has .data field:"); - console.error(JSON.stringify(e.data)); - } } if (nextGasObject !== undefined) { @@ -326,20 +334,24 @@ export class SuiPricePusher implements IPricePusher { signer: Ed25519Keypair, provider: SuiClient, numGasObjects: number, - ignoreGasObjects: string[] + ignoreGasObjects: string[], + logger: Logger ): Promise { const signerAddress = await signer.toSuiAddress(); if (ignoreGasObjects.length > 0) { - console.log("Ignoring some gas objects for coin merging:"); - console.log(ignoreGasObjects); + logger.info( + { ignoreGasObjects }, + "Ignoring some gas objects for coin merging" + ); } const consolidatedCoin = await SuiPricePusher.mergeGasCoinsIntoOne( signer, provider, signerAddress, - ignoreGasObjects + ignoreGasObjects, + logger ); const coinResult = await provider.getObject({ id: consolidatedCoin.objectId, @@ -366,7 +378,7 @@ export class SuiPricePusher implements IPricePusher { numGasObjects, consolidatedCoin ); - console.log("Gas pool is filled with coins: ", gasPool); + logger.info({ gasPool }, "Gas pool is filled with coins"); return gasPool; } @@ -470,7 +482,8 @@ export class SuiPricePusher implements IPricePusher { signer: Ed25519Keypair, provider: SuiClient, owner: SuiAddress, - initialLockedAddresses: string[] + initialLockedAddresses: string[], + logger: Logger ): Promise { const gasCoins = await SuiPricePusher.getAllGasCoins(provider, owner); // skip merging if there is only one coin @@ -500,17 +513,15 @@ export class SuiPricePusher implements IPricePusher { transactionBlock: mergeTx, options: { showEffects: true }, }); - } catch (e) { - console.log("Merge transaction failed with error:"); - console.log(e); - console.log((e as any).data); - console.log(JSON.stringify(e)); + } catch (err) { + logger.error(err, "Merge transaction failed with error"); + if ( - String(e).includes( + String(err).includes( "quorum of validators because of locked objects. Retried a conflicting transaction" ) ) { - Object.values((e as any).data).forEach((lockedObjects: any) => { + Object.values((err as any).data).forEach((lockedObjects: any) => { lockedObjects.forEach((lockedObject: [string, number, string]) => { lockedAddresses.add(lockedObject[0]); }); @@ -519,7 +530,7 @@ export class SuiPricePusher implements IPricePusher { i--; continue; } - throw e; + throw err; } const error = mergeResult?.effects?.status.error; if (error) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f4c2825a8..f68b59dbf8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -235,9 +235,15 @@ importers: '@pythnetwork/solana-utils': specifier: workspace:* version: link:../../target_chains/solana/sdk/js/solana_utils + '@solana/web3.js': + specifier: ^1.93.0 + version: 1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) '@truffle/hdwallet-provider': specifier: ^2.1.3 version: 2.1.5(@babel/core@7.24.7)(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@types/pino': + specifier: ^7.0.5 + version: 7.0.5 aptos: specifier: ^1.8.5 version: 1.8.5 @@ -250,6 +256,9 @@ importers: near-api-js: specifier: ^3.0.2 version: 3.0.4(encoding@0.1.13) + pino: + specifier: ^9.2.0 + version: 9.2.0 web3: specifier: ^1.8.1 version: 1.8.2(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -287,6 +296,9 @@ importers: jest: specifier: ^29.7.0 version: 29.7.0(@types/node@20.14.2)(ts-node@10.9.1(@types/node@20.14.2)(typescript@5.4.5)) + pino-pretty: + specifier: ^11.2.1 + version: 11.2.1 prettier: specifier: ^2.6.2 version: 2.8.8 @@ -322,7 +334,7 @@ importers: version: 0.49.1 '@pythnetwork/client': specifier: ^2.21.0 - version: 2.21.0(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + version: 2.21.0(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) '@pythnetwork/contract-manager': specifier: workspace:* version: 'link:' @@ -944,7 +956,7 @@ importers: version: 0.0.12(eslint@9.5.0)(typescript@4.9.5)(webpack@5.91.0) '@pythnetwork/client': specifier: ^2.17.0 - version: 2.21.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + version: 2.21.0(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) dotenv: specifier: ^16.0.3 version: 16.4.5 @@ -1575,7 +1587,7 @@ importers: version: 0.49.1 '@pythnetwork/client': specifier: ^2.17.0 - version: 2.21.0(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + version: 2.21.0(@solana/web3.js@1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) '@pythnetwork/contract-manager': specifier: workspace:* version: link:../../../contract_manager @@ -5943,6 +5955,9 @@ packages: '@solana/web3.js@1.92.3': resolution: {integrity: sha512-NVBWvb9zdJIAx6X+caXaIICCEQfQaQ8ygykCjJW4u2z/sIKcvPj3ZIIllnx0MWMc3IxGq15ozGYDOQIMbwUcHw==} + '@solana/web3.js@1.93.0': + resolution: {integrity: sha512-suf4VYwWxERz4tKoPpXCRHFRNst7jmcFUaD65kII+zg9urpy5PeeqgLV6G5eWGzcVzA9tZeXOju1A1Y+0ojEVw==} + '@solflare-wallet/metamask-sdk@1.0.3': resolution: {integrity: sha512-os5Px5PTMYKGS5tzOoyjDxtOtj0jZKnbI1Uwt8+Jsw1HHIA+Ib2UACCGNhQ/un2f8sIbTfLD1WuucNMOy8KZpQ==} peerDependencies: @@ -6181,6 +6196,9 @@ packages: '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + '@swc/helpers@0.5.11': + resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==} + '@swc/helpers@0.5.5': resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} @@ -6685,6 +6703,10 @@ packages: '@types/pbkdf2@3.1.0': resolution: {integrity: sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==} + '@types/pino@7.0.5': + resolution: {integrity: sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==} + deprecated: This is a stub types definition. pino provides its own type definitions, so you do not need this installed. + '@types/prettier@2.7.2': resolution: {integrity: sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==} @@ -8651,6 +8673,9 @@ packages: colorette@1.4.0: resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + colors@1.0.3: resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} engines: {node: '>=0.1.90'} @@ -9059,6 +9084,9 @@ packages: dateformat@3.0.3: resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dayjs@1.11.11: resolution: {integrity: sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==} @@ -10301,6 +10329,9 @@ packages: resolution: {integrity: sha512-I2FldZwnCbcY6iL+H0rp9m4D+O3PotuFu9FasWjMCzUedYHMP89/37JbSt6/n7Yq/IZmJDW0B2h30sPYdzrfzw==} engines: {node: '>=8.0.0'} + fast-copy@3.0.2: + resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -10929,6 +10960,9 @@ packages: header-case@1.0.1: resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} + help-me@5.0.0: + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + hermes-estree@0.19.1: resolution: {integrity: sha512-daLGV3Q2MKk8w4evNMKwS8zBE/rcpA800nu1Q5kM08IKijoSnPe9Uo1iIxzPKRkn95IxxsgBMPeYHt3VG4ej2g==} @@ -13788,6 +13822,10 @@ packages: pino-abstract-transport@1.2.0: resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} + pino-pretty@11.2.1: + resolution: {integrity: sha512-O05NuD9tkRasFRWVaF/uHLOvoRDFD7tb5VMertr78rbsYFjYp48Vg3477EshVAF5eZaEw+OpDl/tu+B0R5o+7g==} + hasBin: true + pino-std-serializers@4.0.0: resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} @@ -14724,6 +14762,9 @@ packages: rpc-websockets@8.0.1: resolution: {integrity: sha512-PptrPRK40uQvifq5sCcObmqInVcZXhy+RRrirzdE5KUPvDI47y1wPvfckD2QzqngOU9xaPW/dT+G+b+wj6M1MQ==} + rpc-websockets@9.0.2: + resolution: {integrity: sha512-YzggvfItxMY3Lwuax5rC18inhbjJv9Py7JXRHxTIi94JOLrqBsSsUUc5bbl5W6c11tXhdfpDPK0KzBhoGe8jjw==} + rtcpeerconnection-shim@1.2.15: resolution: {integrity: sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==} engines: {node: '>=6.0.0', npm: '>=3.10.0'} @@ -14827,6 +14868,9 @@ packages: resolution: {integrity: sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==} engines: {node: '>=14.0.0'} + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + selfsigned@2.4.1: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} @@ -19786,7 +19830,7 @@ snapshots: '@censo-custody/solana-wallet-adapter@0.1.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bs58: 4.0.1 eventemitter3: 4.0.7 uuid: 8.3.2 @@ -19820,11 +19864,11 @@ snapshots: dependencies: '@certusone/wormhole-sdk-proto-web': 0.0.7(google-protobuf@3.21.2) '@certusone/wormhole-sdk-wasm': 0.0.1 - '@coral-xyz/borsh': 0.2.6(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.2.6(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@mysten/sui.js': 0.32.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@project-serum/anchor': 0.25.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/spl-token': 0.3.7(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.3.7(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) '@terra-money/terra.js': 3.1.9 '@xpla/xpla.js': 0.2.3 algosdk: 2.7.0 @@ -19855,11 +19899,11 @@ snapshots: dependencies: '@certusone/wormhole-sdk-proto-web': 0.0.6(google-protobuf@3.21.2) '@certusone/wormhole-sdk-wasm': 0.0.1 - '@coral-xyz/borsh': 0.2.6(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.2.6(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@mysten/sui.js': 0.32.2(bufferutil@4.0.7)(utf-8-validate@5.0.10) '@project-serum/anchor': 0.25.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/spl-token': 0.3.7(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.3.7(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) '@terra-money/terra.js': 3.1.9 '@xpla/xpla.js': 0.2.3 algosdk: 2.7.0 @@ -19890,11 +19934,11 @@ snapshots: dependencies: '@certusone/wormhole-sdk-proto-web': 0.0.6(google-protobuf@3.21.2) '@certusone/wormhole-sdk-wasm': 0.0.1 - '@coral-xyz/borsh': 0.2.6(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.2.6(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@mysten/sui.js': 0.32.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@project-serum/anchor': 0.25.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/spl-token': 0.3.7(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.3.7(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) '@terra-money/terra.js': 3.1.9 '@xpla/xpla.js': 0.2.3 algosdk: 2.7.0 @@ -19939,8 +19983,8 @@ snapshots: '@coral-xyz/anchor@0.27.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.27.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': 0.27.0(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) base64-js: 1.5.1 bn.js: 5.2.1 bs58: 4.0.1 @@ -19961,9 +20005,9 @@ snapshots: '@coral-xyz/anchor@0.29.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@noble/hashes': 1.4.0 - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -19982,9 +20026,9 @@ snapshots: '@coral-xyz/anchor@0.29.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@noble/hashes': 1.4.0 - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -20003,9 +20047,9 @@ snapshots: '@coral-xyz/anchor@0.30.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.30.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.30.0(@solana/web3.js@1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@noble/hashes': 1.4.0 - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -20022,33 +20066,33 @@ snapshots: - encoding - utf-8-validate - '@coral-xyz/borsh@0.2.6(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.2.6(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.2.6(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.2.6(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.27.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.27.0(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.28.0(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.28.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.28.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.28.0(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 @@ -20058,21 +20102,27 @@ snapshots: bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.28.0(@solana/web3.js@1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.30.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + bn.js: 5.2.1 + buffer-layout: 1.2.2 + + '@coral-xyz/borsh@0.30.0(@solana/web3.js@1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + dependencies: + '@solana/web3.js': 1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 @@ -20578,7 +20628,7 @@ snapshots: '@ensdomains/ensjs@2.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 '@ensdomains/address-encoder': 0.1.9 '@ensdomains/ens': 0.4.5 '@ensdomains/resolver': 0.2.4 @@ -22609,7 +22659,7 @@ snapshots: '@keystonehq/bc-ur-registry': 0.5.5 '@keystonehq/bc-ur-registry-sol': 0.3.1 '@keystonehq/sdk': 0.13.1 - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bs58: 5.0.0 uuid: 8.3.2 transitivePeerDependencies: @@ -24179,8 +24229,8 @@ snapshots: '@project-serum/anchor@0.25.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@project-serum/borsh': 0.2.5(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@project-serum/borsh': 0.2.5(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) base64-js: 1.5.1 bn.js: 5.2.1 bs58: 4.0.1 @@ -24201,8 +24251,8 @@ snapshots: '@project-serum/anchor@0.25.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@project-serum/borsh': 0.2.5(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@project-serum/borsh': 0.2.5(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) base64-js: 1.5.1 bn.js: 5.2.1 bs58: 4.0.1 @@ -24221,15 +24271,15 @@ snapshots: - encoding - utf-8-validate - '@project-serum/borsh@0.2.5(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@project-serum/borsh@0.2.5(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@project-serum/borsh@0.2.5(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@project-serum/borsh@0.2.5(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 @@ -24262,22 +24312,22 @@ snapshots: '@protobufjs/utf8@1.1.0': {} - '@pythnetwork/client@2.21.0(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@pythnetwork/client@2.21.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor': 0.29.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@coral-xyz/anchor': 0.29.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil - encoding - utf-8-validate - '@pythnetwork/client@2.21.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@pythnetwork/client@2.21.0(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/anchor': 0.29.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@coral-xyz/anchor': 0.29.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -24295,6 +24345,17 @@ snapshots: - encoding - utf-8-validate + '@pythnetwork/client@2.21.0(@solana/web3.js@1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@coral-xyz/anchor': 0.29.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + '@pythnetwork/price-service-client@1.9.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: '@pythnetwork/price-service-sdk': 1.7.1 @@ -24321,7 +24382,7 @@ snapshots: '@radix-ui/react-arrow@1.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 '@radix-ui/react-primitive': 1.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -24428,7 +24489,7 @@ snapshots: '@radix-ui/react-use-callback-ref@1.0.0(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 react: 18.3.1 '@radix-ui/react-use-controllable-state@1.0.0(react@18.3.1)': @@ -24439,24 +24500,24 @@ snapshots: '@radix-ui/react-use-escape-keydown@1.0.2(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 '@radix-ui/react-use-callback-ref': 1.0.0(react@18.3.1) react: 18.3.1 '@radix-ui/react-use-layout-effect@1.0.0(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 react: 18.3.1 '@radix-ui/react-use-rect@1.0.0(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 '@radix-ui/rect': 1.0.0 react: 18.3.1 '@radix-ui/react-use-size@1.0.0(react@18.3.1)': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 '@radix-ui/react-use-layout-effect': 1.0.0(react@18.3.1) react: 18.3.1 @@ -24469,7 +24530,7 @@ snapshots: '@radix-ui/rect@1.0.0': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 '@react-aria/focus@3.17.1(react@18.3.1)': dependencies: @@ -25017,7 +25078,7 @@ snapshots: '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) bigint-buffer: 1.1.5 bignumber.js: 9.1.2 transitivePeerDependencies: @@ -25028,7 +25089,7 @@ snapshots: '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bigint-buffer: 1.1.5 bignumber.js: 9.1.2 transitivePeerDependencies: @@ -25040,22 +25101,33 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/spl-token@0.3.7(@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.3.7(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + '@solana/spl-token@0.3.7(@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil - encoding - utf-8-validate - '@solana/spl-token@0.3.7(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.3.7(@solana/web3.js@1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -25561,7 +25633,7 @@ snapshots: - encoding - utf-8-validate - '@solana/web3.js@1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.23.9 '@noble/curves': 1.4.0 @@ -25574,7 +25646,7 @@ snapshots: bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.1.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + jayson: 4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) node-fetch: 2.7.0(encoding@0.1.13) rpc-websockets: 7.5.1 superstruct: 0.14.2 @@ -25583,9 +25655,9 @@ snapshots: - encoding - utf-8-validate - '@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@solana/web3.js@1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 '@noble/curves': 1.4.0 '@noble/hashes': 1.4.0 '@solana/buffer-layout': 4.0.1 @@ -25596,10 +25668,10 @@ snapshots: bs58: 4.0.1 buffer: 6.0.3 fast-stable-stringify: 1.0.0 - jayson: 4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + jayson: 4.1.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) node-fetch: 2.7.0(encoding@0.1.13) - rpc-websockets: 7.5.1 - superstruct: 0.14.2 + rpc-websockets: 8.0.1 + superstruct: 1.0.4 transitivePeerDependencies: - bufferutil - encoding @@ -25627,6 +25699,28 @@ snapshots: - encoding - utf-8-validate + '@solana/web3.js@1.93.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.24.7 + '@noble/curves': 1.4.0 + '@noble/hashes': 1.4.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + node-fetch: 2.7.0(encoding@0.1.13) + rpc-websockets: 9.0.2 + superstruct: 1.0.4 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + '@solflare-wallet/metamask-sdk@1.0.3(@solana/web3.js@1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: '@solana/wallet-standard-features': 1.2.0 @@ -25650,7 +25744,7 @@ snapshots: '@sqds/mesh@1.0.6(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@project-serum/anchor': 0.25.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.90.0(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 transitivePeerDependencies: - bufferutil @@ -25660,7 +25754,7 @@ snapshots: '@sqds/mesh@1.0.6(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@project-serum/anchor': 0.25.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bn.js: 5.2.1 transitivePeerDependencies: - bufferutil @@ -25753,7 +25847,7 @@ snapshots: '@strike-protocols/solana-wallet-adapter@0.1.8(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) bs58: 4.0.1 eventemitter3: 4.0.7 uuid: 8.3.2 @@ -25948,6 +26042,10 @@ snapshots: '@swc/counter@0.1.3': {} + '@swc/helpers@0.5.11': + dependencies: + tslib: 2.6.3 + '@swc/helpers@0.5.5': dependencies: '@swc/counter': 0.1.3 @@ -26150,7 +26248,7 @@ snapshots: '@toruslabs/solana-embed@0.3.4(@babel/runtime@7.24.7)(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.24.7 - '@solana/web3.js': 1.90.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.92.3(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10) '@toruslabs/base-controllers': 2.9.0(@babel/runtime@7.24.7)(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@toruslabs/http-helpers': 3.4.0(@babel/runtime@7.24.7) '@toruslabs/openlogin-jrpc': 3.2.0(@babel/runtime@7.24.7) @@ -26768,6 +26866,10 @@ snapshots: dependencies: '@types/node': 20.14.2 + '@types/pino@7.0.5': + dependencies: + pino: 9.2.0 + '@types/prettier@2.7.2': {} '@types/prop-types@15.7.12': {} @@ -26906,7 +27008,7 @@ snapshots: '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -27006,7 +27108,7 @@ snapshots: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.57.0 optionalDependencies: typescript: 5.4.5 @@ -27110,7 +27212,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.4.5) '@typescript-eslint/utils': 6.21.0(eslint@8.57.0)(typescript@5.4.5) - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.5) optionalDependencies: @@ -27186,7 +27288,7 @@ snapshots: dependencies: '@typescript-eslint/types': 6.21.0 '@typescript-eslint/visitor-keys': 6.21.0 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 @@ -28587,7 +28689,7 @@ snapshots: axios@0.21.4: dependencies: - follow-redirects: 1.15.6(debug@4.3.4) + follow-redirects: 1.15.6 transitivePeerDependencies: - debug @@ -28605,7 +28707,7 @@ snapshots: axios@0.27.2: dependencies: - follow-redirects: 1.15.6(debug@4.3.4) + follow-redirects: 1.15.6 form-data: 4.0.0 transitivePeerDependencies: - debug @@ -29586,6 +29688,8 @@ snapshots: colorette@1.4.0: {} + colorette@2.0.20: {} + colors@1.0.3: {} colors@1.4.0: {} @@ -30206,6 +30310,8 @@ snapshots: dateformat@3.0.3: {} + dateformat@4.6.3: {} + dayjs@1.11.11: {} debounce-fn@4.0.0: @@ -30242,6 +30348,10 @@ snapshots: optionalDependencies: supports-color: 8.1.1 + debug@4.3.4: + dependencies: + ms: 2.1.2 + debug@4.3.4(supports-color@8.1.1): dependencies: ms: 2.1.2 @@ -31384,7 +31494,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.3.4 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -31516,7 +31626,7 @@ snapshots: eth-block-tracker@4.4.3(@babel/core@7.24.7): dependencies: '@babel/plugin-transform-runtime': 7.19.6(@babel/core@7.24.7) - '@babel/runtime': 7.23.9 + '@babel/runtime': 7.24.7 eth-query: 2.1.2 json-rpc-random-id: 1.0.1 pify: 3.0.0 @@ -32022,6 +32132,8 @@ snapshots: dependencies: pure-rand: 6.0.4 + fast-copy@3.0.2: {} + fast-deep-equal@3.1.3: {} fast-glob@3.2.7: @@ -32178,6 +32290,8 @@ snapshots: flow-parser@0.237.2: {} + follow-redirects@1.15.6: {} + follow-redirects@1.15.6(debug@4.3.4): optionalDependencies: debug: 4.3.4(supports-color@8.1.1) @@ -32878,6 +32992,8 @@ snapshots: no-case: 2.3.2 upper-case: 1.1.3 + help-me@5.0.0: {} + hermes-estree@0.19.1: {} hermes-estree@0.20.1: {} @@ -37417,6 +37533,23 @@ snapshots: readable-stream: 4.5.2 split2: 4.2.0 + pino-pretty@11.2.1: + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 3.0.2 + fast-safe-stringify: 2.1.1 + help-me: 5.0.0 + joycon: 3.1.1 + minimist: 1.2.7 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + pump: 3.0.0 + readable-stream: 4.5.2 + secure-json-parse: 2.7.0 + sonic-boom: 4.0.1 + strip-json-comments: 3.1.1 + pino-std-serializers@4.0.0: {} pino-std-serializers@7.0.0: {} @@ -38647,6 +38780,19 @@ snapshots: bufferutil: 4.0.8 utf-8-validate: 5.0.10 + rpc-websockets@9.0.2: + dependencies: + '@swc/helpers': 0.5.11 + '@types/uuid': 8.3.4 + '@types/ws': 8.5.4 + buffer: 6.0.3 + eventemitter3: 5.0.1 + uuid: 8.3.2 + ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + rtcpeerconnection-shim@1.2.15: dependencies: sdp: 2.12.0 @@ -38767,6 +38913,8 @@ snapshots: node-addon-api: 5.1.0 node-gyp-build: 4.6.0 + secure-json-parse@2.7.0: {} + selfsigned@2.4.1: dependencies: '@types/node-forge': 1.3.11