From 58b0fa1d392fc91c6673879426b5616e5f09f704 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Tue, 17 Mar 2026 12:34:30 +0000 Subject: [PATCH] fix: packedaccounts in js should not turn bool to number --- js/compressed-token/rollup.config.js | 2 +- js/stateless.js/rollup.config.js | 2 +- js/stateless.js/src/utils/instruction.ts | 26 ++++++++++--- .../tests/unit/utils/packed-accounts.test.ts | 39 +++++++++++++++++++ 4 files changed, 62 insertions(+), 7 deletions(-) create mode 100644 js/stateless.js/tests/unit/utils/packed-accounts.test.ts diff --git a/js/compressed-token/rollup.config.js b/js/compressed-token/rollup.config.js index b478bd90e8..ece04a6462 100644 --- a/js/compressed-token/rollup.config.js +++ b/js/compressed-token/rollup.config.js @@ -64,7 +64,7 @@ const rolls = (fmt, env) => ({ drop_console: false, drop_debugger: true, passes: 3, - booleans_as_integers: true, + booleans_as_integers: false, keep_fargs: false, keep_fnames: false, keep_infinity: true, diff --git a/js/stateless.js/rollup.config.js b/js/stateless.js/rollup.config.js index 2f2b08652e..7f0f0ad20c 100644 --- a/js/stateless.js/rollup.config.js +++ b/js/stateless.js/rollup.config.js @@ -44,7 +44,7 @@ const rolls = (fmt, env) => ({ drop_console: false, drop_debugger: true, passes: 3, - booleans_as_integers: true, + booleans_as_integers: false, keep_fargs: false, keep_fnames: false, keep_infinity: true, diff --git a/js/stateless.js/src/utils/instruction.ts b/js/stateless.js/src/utils/instruction.ts index cb824ef4ec..02b1249e81 100644 --- a/js/stateless.js/src/utils/instruction.ts +++ b/js/stateless.js/src/utils/instruction.ts @@ -2,6 +2,9 @@ import { AccountMeta, PublicKey, SystemProgram } from '@solana/web3.js'; import { defaultStaticAccountsStruct, featureFlags } from '../constants'; import { LightSystemProgram } from '../programs'; +const toStrictBool = (value: unknown): boolean => + value === true || value === 1; + export class PackedAccounts { private preAccounts: AccountMeta[] = []; private systemAccounts: AccountMeta[] = []; @@ -40,7 +43,11 @@ export class PackedAccounts { } addPreAccountsMeta(accountMeta: AccountMeta): void { - this.preAccounts.push(accountMeta); + this.preAccounts.push({ + pubkey: accountMeta.pubkey, + isSigner: toStrictBool(accountMeta.isSigner), + isWritable: toStrictBool(accountMeta.isWritable), + }); } /** @@ -81,7 +88,11 @@ export class PackedAccounts { return entry[0]; } const index = this.nextIndex++; - const meta: AccountMeta = { pubkey, isSigner, isWritable }; + const meta: AccountMeta = { + pubkey, + isSigner: toStrictBool(isSigner), + isWritable: toStrictBool(isWritable), + }; this.map.set(pubkey, [index, meta]); return index; } @@ -105,11 +116,16 @@ export class PackedAccounts { } { const packed = this.hashSetAccountsToMetas(); const [systemStart, packedStart] = this.getOffsets(); + const normalize = (meta: AccountMeta): AccountMeta => ({ + pubkey: meta.pubkey, + isSigner: toStrictBool(meta.isSigner), + isWritable: toStrictBool(meta.isWritable), + }); return { remainingAccounts: [ - ...this.preAccounts, - ...this.systemAccounts, - ...packed, + ...this.preAccounts.map(normalize), + ...this.systemAccounts.map(normalize), + ...packed.map(normalize), ], systemStart, packedStart, diff --git a/js/stateless.js/tests/unit/utils/packed-accounts.test.ts b/js/stateless.js/tests/unit/utils/packed-accounts.test.ts new file mode 100644 index 0000000000..ae30bf1618 --- /dev/null +++ b/js/stateless.js/tests/unit/utils/packed-accounts.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from 'vitest'; +import { PublicKey } from '@solana/web3.js'; +import { PackedAccounts } from '../../../src/utils/instruction'; + +describe('PackedAccounts runtime boolean normalization', () => { + it('normalizes numeric AccountMeta flags from addPreAccountsMeta', () => { + const packedAccounts = new PackedAccounts(); + const pubkey = PublicKey.unique(); + + packedAccounts.addPreAccountsMeta({ + pubkey, + isSigner: 0 as unknown as boolean, + isWritable: 1 as unknown as boolean, + }); + + const [meta] = packedAccounts.toAccountMetas().remainingAccounts; + expect(typeof meta.isSigner).toBe('boolean'); + expect(typeof meta.isWritable).toBe('boolean'); + expect(meta.isSigner).toBe(false); + expect(meta.isWritable).toBe(true); + }); + + it('normalizes numeric flags from insertOrGetConfig', () => { + const packedAccounts = new PackedAccounts(); + const pubkey = PublicKey.unique(); + + packedAccounts.insertOrGetConfig( + pubkey, + 1 as unknown as boolean, + 0 as unknown as boolean, + ); + + const [meta] = packedAccounts.toAccountMetas().remainingAccounts; + expect(typeof meta.isSigner).toBe('boolean'); + expect(typeof meta.isWritable).toBe('boolean'); + expect(meta.isSigner).toBe(true); + expect(meta.isWritable).toBe(false); + }); +});