From b62d84d56ca49d9c2ec80b585dfb2347c257eb7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20B=C3=A9k=C3=A9si?= Date: Fri, 10 Jul 2026 13:37:12 +0200 Subject: [PATCH 1/5] chore: strip down eslint to essential --- .eslintrc.js | 75 +++++++-------------------------------------------- package.json | 1 - tsconfig.json | 10 +++++++ 3 files changed, 20 insertions(+), 66 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 86b072c4..31208d0c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,6 +3,9 @@ module.exports = { parserOptions: { sourceType: 'module', ecmaVersion: 2018, + // required for the type-aware rules below (no-floating-promises / no-misused-promises) + project: ['./tsconfig.json', './tsconfig.test.json'], + tsconfigRootDir: __dirname, }, env: { jest: true, @@ -13,78 +16,20 @@ module.exports = { }, plugins: ['jest'], rules: { - 'array-bracket-newline': ['error', 'consistent'], - strict: ['error', 'safe'], - curly: 'error', - 'block-scoped-var': 'error', - complexity: 'warn', - 'default-case': 'error', - 'dot-notation': 'warn', + // --- real bug protection only; formatting is left to Prettier and correctness to tsc --- + curly: ['error', 'multi-line'], eqeqeq: 'error', - 'guard-for-in': 'warn', - 'linebreak-style': ['warn', 'unix'], - 'no-alert': 'error', + 'default-case': 'error', + 'guard-for-in': 'error', 'no-case-declarations': 'error', 'no-console': 'error', 'no-constant-condition': 'error', - 'no-div-regex': 'error', - 'no-empty': 'warn', 'no-empty-pattern': 'error', - 'no-implicit-coercion': 'error', - 'prefer-arrow-callback': 'warn', - 'no-labels': 'error', 'no-loop-func': 'error', - 'no-nested-ternary': 'warn', - 'no-script-url': 'error', - 'no-warning-comments': 'warn', - 'quote-props': ['error', 'as-needed'], 'require-yield': 'error', - 'max-nested-callbacks': ['error', 4], - 'max-depth': ['error', 4], - 'require-await': 'error', - 'space-before-function-paren': [ - 'error', - { - anonymous: 'never', - named: 'never', - asyncArrow: 'always', - }, - ], - 'padding-line-between-statements': [ - 'error', - { blankLine: 'always', prev: '*', next: 'if' }, - { blankLine: 'always', prev: '*', next: 'function' }, - { blankLine: 'always', prev: '*', next: 'return' }, - ], - 'no-useless-constructor': 'off', - 'no-dupe-class-members': 'off', - 'no-unused-expressions': 'off', - curly: ['error', 'multi-line'], - 'object-curly-spacing': ['error', 'always'], - 'comma-dangle': ['error', 'always-multiline'], - '@typescript-eslint/no-useless-constructor': 'error', '@typescript-eslint/no-unused-expressions': 'error', - '@typescript-eslint/member-delimiter-style': [ - 'error', - { - multiline: { - delimiter: 'none', - requireLast: true, - }, - singleline: { - delimiter: 'comma', - requireLast: false, - }, - }, - ], + // the headline reason to keep ESLint: tsc cannot catch these + '@typescript-eslint/no-floating-promises': 'error', + '@typescript-eslint/no-misused-promises': 'error', }, - overrides: [ - { - files: ['*.spec.ts'], - rules: { - // '@typescript-eslint/ban-ts-ignore': 'off', - 'max-nested-callbacks': ['error', 10], // allow describe/it nesting - }, - }, - ], } diff --git a/package.json b/package.json index 0c9dfc29..fff1ce3f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,6 @@ "eslint-config-prettier": "^8.5.0", "eslint-plugin-jest": "^27.1.5", "eslint-plugin-prettier": "^4.2.1", - "eslint-plugin-unused-imports": "^2.0.0", "husky": "^4.3.6", "jest": "^29.3.1", "prettier": "^2.7.1", diff --git a/tsconfig.json b/tsconfig.json index e42387d3..4eebbf53 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,6 +12,16 @@ "module": "commonjs", "outDir": "dist", "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "allowUnusedLabels": false, + "allowUnreachableCode": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true, + "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, From 111400cdf3cda8ef45b4dac5b6919976a649303b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20B=C3=A9k=C3=A9si?= Date: Fri, 10 Jul 2026 14:08:07 +0200 Subject: [PATCH 2/5] fix: violations according to new ruleset --- .eslintignore | 2 ++ .eslintrc.js | 9 +++++++++ src/command/access/history.ts | 5 +++-- src/command/download.ts | 4 ++++ src/command/feed/feed-command.ts | 11 +++++++++-- src/command/pinning/pinning-command.ts | 2 +- src/command/pss/pss-command.ts | 2 +- src/command/root-command/index.ts | 3 ++- src/command/upload.ts | 2 +- src/index.ts | 3 ++- src/service/access/index.ts | 2 +- src/service/identity/index.ts | 4 ++-- src/service/stamp/index.ts | 2 +- src/utils/bzz-address.ts | 2 +- src/utils/text.ts | 5 ++--- test/command/addresses.spec.ts | 12 ++++++------ test/command/feed.spec.ts | 2 +- test/command/manifest.spec.ts | 2 +- test/command/pss.spec.ts | 4 +++- test/command/upload.spec.ts | 8 ++++---- test/custom-matcher.ts | 2 +- test/utility/index.ts | 4 ++-- test/utility/stamp.ts | 6 ++++-- tsconfig.test.json | 1 + 24 files changed, 64 insertions(+), 35 deletions(-) diff --git a/.eslintignore b/.eslintignore index 06c5e168..8052eefa 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,3 @@ dist/** +# upload fixtures — sample project trees used as test payloads, not real source +test/data/** diff --git a/.eslintrc.js b/.eslintrc.js index 31208d0c..60e11e51 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -32,4 +32,13 @@ module.exports = { '@typescript-eslint/no-floating-promises': 'error', '@typescript-eslint/no-misused-promises': 'error', }, + overrides: [ + { + // tests legitimately assert on values they have set up + files: ['test/**/*.ts'], + rules: { + '@typescript-eslint/no-non-null-assertion': 'off', + }, + }, + ], } diff --git a/src/command/access/history.ts b/src/command/access/history.ts index 78fe8852..e2f2b368 100644 --- a/src/command/access/history.ts +++ b/src/command/access/history.ts @@ -20,13 +20,14 @@ export class History extends AccessCommand implements LeafCommand { const accessHistory = new AccessHistory(this.commandConfig, this.console) const events = accessHistory.getEvents(this.listName).sort((a, b) => b.createdAt - a.createdAt) - if (events.length === 0) { + const lastEvent = events[0] + + if (!lastEvent) { this.console.error(errorText(`Grantee list with name '${this.listName}' does not exist!`)) exit(1) } - const lastEvent = events[0] this.console.log(createKeyValue('Latest history address', lastEvent.historyAddress)) this.console.log(createKeyValue('Latest grantee list reference', lastEvent.granteeListRef)) diff --git a/src/command/download.ts b/src/command/download.ts index 774ce23b..6c2d115e 100644 --- a/src/command/download.ts +++ b/src/command/download.ts @@ -34,6 +34,10 @@ export class Download extends RootCommand implements LeafCommand { if (this.manifestDownload.access) { const [publisher, historyAddress] = this.manifestDownload.access.split(':') + if (!publisher || !historyAddress) { + this.console.error('Invalid access format. Expected format: publisher:historyAddress') + process.exit(1) + } const responseAct = await this.bee.downloadFile(this.address.hash, this.manifestDownload.destination, { actPublisher: publisher, actHistoryAddress: historyAddress, diff --git a/src/command/feed/feed-command.ts b/src/command/feed/feed-command.ts index bbbe26aa..34274a42 100644 --- a/src/command/feed/feed-command.ts +++ b/src/command/feed/feed-command.ts @@ -58,7 +58,7 @@ export class FeedCommand extends RootCommand { this.console.log(createKeyValue('Feed Manifest URL', manifestUrl)) if (this.qr) { - printQRCodeWithLabel(publicUrl(manifestUrl), 'QR for Manifest URL', this.console) + await printQRCodeWithLabel(publicUrl(manifestUrl), 'QR for Manifest URL', this.console) } this.console.quiet(manifest.toHex()) @@ -92,7 +92,14 @@ export class FeedCommand extends RootCommand { this.identity = await pickIdentity(this.commandConfig, this.console) } - return identities[this.identity] + const identity = identities[this.identity] + + if (!identity) { + this.console.error('The provided identity does not exist.') + exit(1) + } + + return identity } private async writeFeed(stamp: string, wallet: Wallet, topic: Topic, chunkReference: Reference): Promise { diff --git a/src/command/pinning/pinning-command.ts b/src/command/pinning/pinning-command.ts index 2179191e..0dffbd2e 100644 --- a/src/command/pinning/pinning-command.ts +++ b/src/command/pinning/pinning-command.ts @@ -2,7 +2,7 @@ import { exit } from 'process' import { RootCommand } from '../root-command' export class PinningCommand extends RootCommand { - protected async init(): Promise { + protected override async init(): Promise { super.init() if (await this.bee.isGateway()) { diff --git a/src/command/pss/pss-command.ts b/src/command/pss/pss-command.ts index 34b49a52..b02db657 100644 --- a/src/command/pss/pss-command.ts +++ b/src/command/pss/pss-command.ts @@ -14,7 +14,7 @@ export class PssCommand extends RootCommand { }) public topicString!: string - public init(): void { + public override init(): void { super.init() this.topic = Topic.fromString(this.topicString).toHex() diff --git a/src/command/root-command/index.ts b/src/command/root-command/index.ts index 42d9758d..e9325d50 100644 --- a/src/command/root-command/index.ts +++ b/src/command/root-command/index.ts @@ -84,7 +84,8 @@ export class RootCommand { const latestVersionCheck = getLatestVersionCheck(this.commandConfig) if (latestVersionCheck === null) { - checkForUpdates(this.commandConfig) + // fire-and-forget: a version check must not block CLI startup; it swallows its own errors + void checkForUpdates(this.commandConfig) } else if (latestVersionCheck.latestVersion !== PackageJson.version) { this.console.log( warningText( diff --git a/src/command/upload.ts b/src/command/upload.ts index b63d0500..80deeaa1 100644 --- a/src/command/upload.ts +++ b/src/command/upload.ts @@ -213,7 +213,7 @@ export class Upload extends RootCommand implements LeafCommand { } if (this.qr) { - printQRCodeWithLabel(publicUrl(url), 'QR for URL', this.console) + await printQRCodeWithLabel(publicUrl(url), 'QR for URL', this.console) } if (this.usingACT()) { diff --git a/src/index.ts b/src/index.ts index 740be82d..d105cac3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,7 +13,8 @@ if (setDefaultResultOrder) { setDefaultResultOrder('ipv4first') } -cli({ +// fire-and-forget entry point: cli() reports its own failures via the errorHandler above +void cli({ rootCommandClasses, optionParameters, printer, diff --git a/src/service/access/index.ts b/src/service/access/index.ts index 5979be67..bbfe9496 100644 --- a/src/service/access/index.ts +++ b/src/service/access/index.ts @@ -44,7 +44,7 @@ export class AccessHistory { public getLatestEvent(granteeListName: string): AccessHistoryEvent | null { const events = this.getEvents(granteeListName).sort((a, b) => b.createdAt - a.createdAt) - return events.length > 0 ? events[0] : null + return events[0] ?? null } public getEventsByType(granteeListName: string, eventType: AccessHistoryOperation): AccessHistoryEvent[] { diff --git a/src/service/identity/index.ts b/src/service/identity/index.ts index 0d24aeeb..27693936 100644 --- a/src/service/identity/index.ts +++ b/src/service/identity/index.ts @@ -17,11 +17,11 @@ export function getPrintableIdentityType(type: IdentityType): string { } } -export function isSimpleWallet(wallet: IdentityWallet, identityType: IdentityType): wallet is SimpleWallet { +export function isSimpleWallet(_wallet: IdentityWallet, identityType: IdentityType): _wallet is SimpleWallet { return identityType === IdentityType.simple } -export function isV3Wallet(wallet: IdentityWallet, identityType: IdentityType): wallet is V3Keystore { +export function isV3Wallet(_wallet: IdentityWallet, identityType: IdentityType): _wallet is V3Keystore { return identityType === IdentityType.v3 } diff --git a/src/service/stamp/index.ts b/src/service/stamp/index.ts index 188c64b1..6d707144 100644 --- a/src/service/stamp/index.ts +++ b/src/service/stamp/index.ts @@ -34,7 +34,7 @@ export async function pickStamp(bee: Bee, console: CommandLog): Promise const value = await console.promptList(choices, 'Please select a stamp for this action') const [hex] = value.split(' ') - return hex + return hex ?? value } interface PrintStampSettings { diff --git a/src/utils/bzz-address.ts b/src/utils/bzz-address.ts index b7d31a3b..a210bfb4 100644 --- a/src/utils/bzz-address.ts +++ b/src/utils/bzz-address.ts @@ -15,7 +15,7 @@ export class BzzAddress { throw new CommandLineError('Invalid BZZ path: cannot contain multiple continuous slashes') } const parts = url.split('/') - this.hash = parts[0].toLowerCase() + this.hash = (parts[0] ?? '').toLowerCase() if (this.hash.startsWith('0x')) { this.hash = this.hash.slice(2) diff --git a/src/utils/text.ts b/src/utils/text.ts index ac3ce77e..39f3821f 100644 --- a/src/utils/text.ts +++ b/src/utils/text.ts @@ -50,12 +50,11 @@ export function printDivided( printFn: (item: T, console: CommandLog) => void, console: CommandLog, ): void { - for (let i = 0; i < items.length; i++) { - const item = items[i] + items.forEach((item, i) => { printFn(item, console) if (i !== items.length - 1) { console.divider() } - } + }) } diff --git a/test/command/addresses.spec.ts b/test/command/addresses.spec.ts index 28e94c29..34aba69e 100644 --- a/test/command/addresses.spec.ts +++ b/test/command/addresses.spec.ts @@ -15,12 +15,12 @@ describeCommand( it('should be splittable in quiet mode', async () => { await invokeTestCli(['addresses', '-q']) - expect(consoleMessages[0].split(' ')[1]).toMatch(/[0-9a-f]{20}/i) - expect(consoleMessages[1].split(' ')[1]).toMatch(/[0-9a-f]{20}/i) - expect(consoleMessages[2].split(' ')[1]).toMatch(/[0-9a-f]{20}/i) - expect(consoleMessages[3].split(' ')[1]).toMatch(/[0-9a-f]{20}/i) - expect(consoleMessages[4].split(' ')[1]).toContain('/ip4/') - expect(consoleMessages[5].split(' ')[1]).toMatch(/[0-9a-f]{20}/i) + expect(consoleMessages[0]!.split(' ')[1]).toMatch(/[0-9a-f]{20}/i) + expect(consoleMessages[1]!.split(' ')[1]).toMatch(/[0-9a-f]{20}/i) + expect(consoleMessages[2]!.split(' ')[1]).toMatch(/[0-9a-f]{20}/i) + expect(consoleMessages[3]!.split(' ')[1]).toMatch(/[0-9a-f]{20}/i) + expect(consoleMessages[4]!.split(' ')[1]).toContain('/ip4/') + expect(consoleMessages[5]!.split(' ')[1]).toMatch(/[0-9a-f]{20}/i) }) }, { configFileName: 'addresses' }, diff --git a/test/command/feed.spec.ts b/test/command/feed.spec.ts index f01a0bcb..ac6c0dda 100644 --- a/test/command/feed.spec.ts +++ b/test/command/feed.spec.ts @@ -48,7 +48,7 @@ describeCommand( it('should print feed using address only', async () => { // create identity await invokeTestCli(['identity', 'create', 'test2', '--password', 'test']) - const address = getLastMessage().split(' ')[1] + const address = getLastMessage().split(' ')[1] ?? '' // upload await invokeTestCli([ 'feed', diff --git a/test/command/manifest.spec.ts b/test/command/manifest.spec.ts index 99242943..c7676827 100644 --- a/test/command/manifest.spec.ts +++ b/test/command/manifest.spec.ts @@ -15,7 +15,7 @@ expect.extend({ }) async function runAndGetManifest(argv: string[]): Promise { - if (['create', 'add', 'sync', 'merge', 'remove'].includes(argv[1])) { + if (['create', 'add', 'sync', 'merge', 'remove'].includes(argv[1] ?? '')) { argv = [...argv, ...getStampOption()] } const commandBuilder = await invokeTestCli(argv) diff --git a/test/command/pss.spec.ts b/test/command/pss.spec.ts index 6884b4c3..8d8c3d49 100644 --- a/test/command/pss.spec.ts +++ b/test/command/pss.spec.ts @@ -45,7 +45,8 @@ describeCommand('Test PSS command', ({ getNthLastMessage, getLastMessage }) => { unlinkSync('test/testconfig/out.txt') } writeFileSync('test/testconfig/in.txt', 'Message in a file') - invokeTestCli([ + // start the receiver listening, then send to trigger it, then await the receiver + const receivePromise = invokeTestCli([ 'pss', 'receive', '--topic-string', @@ -68,6 +69,7 @@ describeCommand('Test PSS command', ({ getNthLastMessage, getLastMessage }) => { 'test/testconfig/in.txt', ...getStampOption(), ]) + await receivePromise await System.sleepMillis(4000) expect(existsSync('test/testconfig/out.txt')).toBeTruthy() const messageFromFile = readFileSync('test/testconfig/out.txt', 'ascii') diff --git a/test/command/upload.spec.ts b/test/command/upload.spec.ts index 51802b7f..d15e768e 100644 --- a/test/command/upload.spec.ts +++ b/test/command/upload.spec.ts @@ -41,8 +41,8 @@ describeCommand( const uploadFolderPath = `${__dirname}/../testpage` const commandBuilder = await invokeTestCli([commandKey, uploadFolderPath, ...getStampOption()]) - expect(commandBuilder.initedCommands[0].command.name).toBe('upload') - const command = commandBuilder.initedCommands[0].command as Upload + expect(commandBuilder.initedCommands[0]!.command.name).toBe('upload') + const command = commandBuilder.initedCommands[0]!.command as Upload expect(command.result.getOrThrow().toHex().length).toBe(64) }) @@ -51,8 +51,8 @@ describeCommand( const uploadFolderPath = `${__dirname}/../testpage/images/swarm.png` const commandBuilder = await invokeTestCli([commandKey, uploadFolderPath, ...getStampOption()]) - expect(commandBuilder.initedCommands[0].command.name).toBe('upload') - const command = commandBuilder.initedCommands[0].command as Upload + expect(commandBuilder.initedCommands[0]!.command.name).toBe('upload') + const command = commandBuilder.initedCommands[0]!.command as Upload expect(command.result.getOrThrow().toHex().length).toBe(64) }) diff --git a/test/custom-matcher.ts b/test/custom-matcher.ts index f2b76d57..0dd5cafb 100644 --- a/test/custom-matcher.ts +++ b/test/custom-matcher.ts @@ -23,7 +23,7 @@ export function toMatchLinesInOrder(received: string[], pattern: string[][]) { export function toMatchLinesInAnyOrder(received: string[], pattern: string[][]) { for (const p of pattern) { - if (received.some(r => r.includes(p[0]))) { + if (received.some(r => r.includes(p[0] ?? ''))) { continue } diff --git a/test/utility/index.ts b/test/utility/index.ts index c4736629..d7085802 100644 --- a/test/utility/index.ts +++ b/test/utility/index.ts @@ -31,8 +31,8 @@ export function describeCommand( describe(description, () => { const consoleMessages: string[] = [] const configFileName = options?.configFileName - const getNthLastMessage = (n: number) => consoleMessages[consoleMessages.length - n] - const getLastMessage = () => consoleMessages[consoleMessages.length - 1] + const getNthLastMessage = (n: number) => consoleMessages[consoleMessages.length - n] ?? '' + const getLastMessage = () => consoleMessages[consoleMessages.length - 1] ?? '' const hasMessageContaining = (substring: string) => Boolean(consoleMessages.find(consoleMessage => consoleMessage.includes(substring))) const configFolderPath = join(__dirname, '..', 'testconfig') diff --git a/test/utility/stamp.ts b/test/utility/stamp.ts index 6ff8740c..4be58693 100644 --- a/test/utility/stamp.ts +++ b/test/utility/stamp.ts @@ -6,8 +6,10 @@ export const getOrBuyStamp = async (): Promise => { const bee = new Bee('http://localhost:1633') const availableStamps = await bee.getAllPostageBatch() - if (availableStamps.length > 0) { - const usedStamp = availableStamps[0].batchID + const [existingStamp] = availableStamps + + if (existingStamp) { + const usedStamp = existingStamp.batchID console.log('Using existing stamp: ', usedStamp.toHex()) return usedStamp diff --git a/tsconfig.test.json b/tsconfig.test.json index 24887d62..385c7282 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -5,6 +5,7 @@ "test", "jest.config.ts", ], + "exclude": ["node_modules", "dist", "test/data"], "compilerOptions": { "noEmit": true, "skipLibCheck": true From 527928de1db269b426153567765c195372903d77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20B=C3=A9k=C3=A9si?= Date: Fri, 10 Jul 2026 14:29:26 +0200 Subject: [PATCH 3/5] fix: more violations --- src/command/stake/recover.ts | 4 ++-- src/command/utility/create-batch.ts | 4 ++-- src/utils/rpc.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/command/stake/recover.ts b/src/command/stake/recover.ts index 68950140..2ad7087e 100644 --- a/src/command/stake/recover.ts +++ b/src/command/stake/recover.ts @@ -56,7 +56,7 @@ export class Recover extends RootCommand implements LeafCommand { const { signer } = await makeReadySigner(wallet.getPrivateKeyString(), this.jsonRpcUrl) const contract = new Contract(address, abi, signer) - const isPaused = await contract.paused() + const isPaused = await contract.paused!() if (!isPaused) { this.console.error('The contract is not paused. No need to recover xBZZ.') @@ -65,6 +65,6 @@ export class Recover extends RootCommand implements LeafCommand { } this.console.log('Recovering xBZZ from paused staking contract...') - await contract.migrateStake() + await contract.migrateStake!() } } diff --git a/src/command/utility/create-batch.ts b/src/command/utility/create-batch.ts index be5a16cf..3b58c849 100644 --- a/src/command/utility/create-batch.ts +++ b/src/command/utility/create-batch.ts @@ -65,7 +65,7 @@ export class CreateBatch extends RootCommand implements LeafCommand { this.console.log(`Approving spending of ${cost.toDecimalString()} BZZ to ${wallet.address}`) const tokenProxyContract = new Contract(Contracts.bzz, ABI.tokenProxy, signer) - const approve = await tokenProxyContract.approve(Contracts.postageStamp, cost.toPLURBigInt().toString(), { + const approve = await tokenProxyContract.approve!(Contracts.postageStamp, cost.toPLURBigInt().toString(), { gasLimit: 130_000, type: 2, maxFeePerGas: Numbers.make('2gwei'), @@ -77,7 +77,7 @@ export class CreateBatch extends RootCommand implements LeafCommand { this.console.log(`Creating postage batch for ${wallet.address} with depth ${this.depth} and amount ${this.amount}`) const postageStampContract = new Contract(Contracts.postageStamp, ABI.postageStamp, signer) const createBatchArgs = [signer.address, this.amount, this.depth, 16, `0x${Strings.randomHex(64)}`, false] - const createBatch = await postageStampContract.createBatch(...createBatchArgs, { + const createBatch = await postageStampContract.createBatch!(...createBatchArgs, { gasLimit: 1_000_000, type: 2, maxFeePerGas: Numbers.make('3gwei'), diff --git a/src/utils/rpc.ts b/src/utils/rpc.ts index b30b604a..de8a4701 100644 --- a/src/utils/rpc.ts +++ b/src/utils/rpc.ts @@ -19,7 +19,7 @@ export async function eth_getBalanceERC20( address = `0x${address}` } const contract = new Contract(tokenAddress, ABI.bzz, provider) - const balance = await contract.balanceOf(address) + const balance = await contract.balanceOf!(address) return balance.toString() } @@ -99,7 +99,7 @@ export async function sendBzzTransaction( } const bzz = new Contract(Contracts.bzz, ABI.bzz, signer) - const transaction = await bzz.transfer(to, value, { gasPrice }) + const transaction = await bzz.transfer!(to, value, { gasPrice }) const receipt = await transaction.wait(1) if (receipt === null) { From ced09f7b4020aefa0ef34795035670d50d933e5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20B=C3=A9k=C3=A9si?= Date: Fri, 10 Jul 2026 14:47:21 +0200 Subject: [PATCH 4/5] fix: remove unnecessary sleep --- test/command/pss.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/command/pss.spec.ts b/test/command/pss.spec.ts index 8d8c3d49..9a2307cf 100644 --- a/test/command/pss.spec.ts +++ b/test/command/pss.spec.ts @@ -70,7 +70,6 @@ describeCommand('Test PSS command', ({ getNthLastMessage, getLastMessage }) => { ...getStampOption(), ]) await receivePromise - await System.sleepMillis(4000) expect(existsSync('test/testconfig/out.txt')).toBeTruthy() const messageFromFile = readFileSync('test/testconfig/out.txt', 'ascii') expect(messageFromFile).toBe('Message in a file') From 0f17af1ca2c6c131c7db2fb06ef28dba2480f340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gergely=20B=C3=A9k=C3=A9si?= Date: Fri, 10 Jul 2026 14:56:15 +0200 Subject: [PATCH 5/5] fix: custom matcher --- test/custom-matcher.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/custom-matcher.ts b/test/custom-matcher.ts index 0dd5cafb..ac26d544 100644 --- a/test/custom-matcher.ts +++ b/test/custom-matcher.ts @@ -23,7 +23,7 @@ export function toMatchLinesInOrder(received: string[], pattern: string[][]) { export function toMatchLinesInAnyOrder(received: string[], pattern: string[][]) { for (const p of pattern) { - if (received.some(r => r.includes(p[0] ?? ''))) { + if (received.some(r => p.every(substring => r.includes(substring)))) { continue }