From a8453283f1c2a3acdae33310a9d454562c928118 Mon Sep 17 00:00:00 2001 From: Connor Prussin Date: Tue, 8 Apr 2025 22:45:57 -0700 Subject: [PATCH] fix(staking-sdk): more staking-sdk improvements - Don't disable eslint rules unnecessarily - Ensure we handle `Uint8Array`s in the response body too - Throw an explicit error if we reach the end of the stream without finding a result --- governance/pyth_staking_sdk/eslint.config.js | 13 +---- governance/pyth_staking_sdk/package.json | 2 +- .../src/pyth-staking-client.ts | 54 ++++++++++++++----- governance/pyth_staking_sdk/src/utils/pool.ts | 2 +- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/governance/pyth_staking_sdk/eslint.config.js b/governance/pyth_staking_sdk/eslint.config.js index 058fdf9e01..9058bfef8c 100644 --- a/governance/pyth_staking_sdk/eslint.config.js +++ b/governance/pyth_staking_sdk/eslint.config.js @@ -1,12 +1 @@ -import { base } from "@cprussin/eslint-config"; - -export default [ - ...base, - { - rules: { - "n/no-unpublished-import": "off", - "unicorn/no-null": "off", - "unicorn/prefer-node-protocol": "off", - }, - }, -]; +export { base as default } from "@cprussin/eslint-config"; diff --git a/governance/pyth_staking_sdk/package.json b/governance/pyth_staking_sdk/package.json index 76bf1a5364..ec3b721f16 100644 --- a/governance/pyth_staking_sdk/package.json +++ b/governance/pyth_staking_sdk/package.json @@ -1,6 +1,6 @@ { "name": "@pythnetwork/staking-sdk", - "version": "0.2.0", + "version": "0.2.1", "description": "Pyth staking SDK", "type": "module", "exports": { diff --git a/governance/pyth_staking_sdk/src/pyth-staking-client.ts b/governance/pyth_staking_sdk/src/pyth-staking-client.ts index 8020279fb3..809c7ba53a 100644 --- a/governance/pyth_staking_sdk/src/pyth-staking-client.ts +++ b/governance/pyth_staking_sdk/src/pyth-staking-client.ts @@ -1,4 +1,4 @@ -import * as crypto from "crypto"; +import crypto from "crypto"; // eslint-disable-line unicorn/prefer-node-protocol import { AnchorProvider, BN, Program } from "@coral-xyz/anchor"; import { @@ -752,7 +752,7 @@ export class PythStakingClient { publisherStakeAccountPositions: stakeAccount, publisherStakeAccountCustody: stakeAccount ? getStakeAccountCustodyAddress(stakeAccount) - : null, + : null, // eslint-disable-line unicorn/no-null stakeAccountPositions, stakeAccountCustody: getStakeAccountCustodyAddress( stakeAccountPositions, @@ -839,6 +839,7 @@ export class PythStakingClient { .setPublisherStakeAccount() .accounts({ currentStakeAccountPositionsOption: stakeAccountPositions, + // eslint-disable-next-line unicorn/no-null newStakeAccountPositionsOption: newStakeAccountPositions ?? null, publisher, }) @@ -1088,22 +1089,25 @@ export class PythStakingClient { // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition while (true) { const res = await reader.read(); - if (res.done) break; - if (typeof res.value === "string") { + if (res.done) { + break; + } else if ( + typeof res.value === "string" || + res.value instanceof Uint8Array + ) { jsonparser.write(res.value); } } }; - parse().catch((error: unknown) => { - reject( - error instanceof Error - ? error - : new Error( - typeof error === "string" ? error : "Unknown Error", - ), - ); - }); + parse().then( + () => { + reject(new EndOfStreamError()); + }, + (error: unknown) => { + reject(intoError(error)); + }, + ); }); return accountSchema @@ -1140,6 +1144,16 @@ const accountSchema = z.array( }), ); +const intoError = (error: unknown): Error => { + if (error instanceof Error) { + return error; + } else if (typeof error === "string") { + return new Error(error); + } else { + return new UnknownError(); + } +}; + class NotOKError extends Error { constructor(result: Response) { super(`Received a ${result.status.toString()} response for ${result.url}`); @@ -1154,3 +1168,17 @@ class NoBodyError extends Error { this.name = "NoBodyError"; } } + +class EndOfStreamError extends Error { + constructor() { + super("Reached end of stream without finding accounts"); + this.name = "EndOfStreamError"; + } +} + +class UnknownError extends Error { + constructor() { + super("Unknown error"); + this.name = "UnknownError"; + } +} diff --git a/governance/pyth_staking_sdk/src/utils/pool.ts b/governance/pyth_staking_sdk/src/utils/pool.ts index 1ad14388cb..762822c42e 100644 --- a/governance/pyth_staking_sdk/src/utils/pool.ts +++ b/governance/pyth_staking_sdk/src/utils/pool.ts @@ -17,7 +17,7 @@ export const extractPublisherData = ( stakeAccount: poolData.publisherStakeAccounts[index] === undefined || poolData.publisherStakeAccounts[index].equals(PublicKey.default) - ? null + ? null // eslint-disable-line unicorn/no-null : poolData.publisherStakeAccounts[index], totalDelegation: (poolData.delState[index]?.totalDelegation ?? 0n) +