Skip to content

Add fixed-point codecs#1568

Merged
lorisleiva merged 1 commit into
mainfrom
04-24-add_fixed-point_codecs
May 5, 2026
Merged

Add fixed-point codecs#1568
lorisleiva merged 1 commit into
mainfrom
04-24-add_fixed-point_codecs

Conversation

@lorisleiva
Copy link
Copy Markdown
Member

This PR adds getBinaryFixedPointCodec, getDecimalFixedPointCodec, and their encoder/decoder counterparts to @solana/fixed-points. Each factory takes a signedness, total bits, scale, and an optional FixedPointCodecConfig ({ endian?: 'le' | 'be' }, defaults to little-endian), and produces a FixedSizeCodec whose byte-size literal is preserved for widths that are multiples of 8 from 8 to 256 bits. Non-byte-aligned total bits throw a SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED error.

The byte-level IO uses DataView.setBigUint64/getBigUint64 for every 64-bit chunk, then greedily consumes the remaining 0-7 bytes with at most one setUint32/setUint16 and a direct byte write. This matches @solana/codecs-numbers performance for common widths (u8/u16/u32/u64/u128) and stays efficient for non-standard widths like u24/u40/u72. The read path uses toArrayBuffer from @solana/codecs-core so it works in environments where SharedArrayBuffer is undefined (React Native, non-isolated browsers). In the future, the number codecs in @solana/codecs-numbers could delegate to these more generic fixed-point codecs under the hood.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 24, 2026

⚠️ No Changeset found

Latest commit: 6d87c49

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@bundlemon
Copy link
Copy Markdown

bundlemon Bot commented Apr 24, 2026

BundleMon

Files updated (4)
Status Path Size Limits
fixed-points/dist/index.browser.mjs
4.99KB (+1.11KB +28.58%) -
fixed-points/dist/index.native.mjs
4.99KB (+1.11KB +28.6%) -
fixed-points/dist/index.node.mjs
4.99KB (+1.11KB +28.6%) -
@solana/kit production bundle
kit/dist/index.production.min.js
51.21KB (+665B +1.28%) -
Unchanged files (143)
Status Path Size Limits
errors/dist/index.node.mjs
20.44KB -
errors/dist/index.browser.mjs
20.42KB -
errors/dist/index.native.mjs
20.41KB -
rpc-graphql/dist/index.browser.mjs
18.82KB -
rpc-graphql/dist/index.native.mjs
18.81KB -
rpc-graphql/dist/index.node.mjs
18.81KB -
wallet-account-signer/dist/index.node.mjs
17.29KB -
wallet-account-signer/dist/index.browser.mjs
17.27KB -
wallet-account-signer/dist/index.native.mjs
17.27KB -
transaction-messages/dist/index.browser.mjs
11.32KB -
transaction-messages/dist/index.native.mjs
11.32KB -
transaction-messages/dist/index.node.mjs
11.32KB -
instruction-plans/dist/index.browser.mjs
6.58KB -
instruction-plans/dist/index.native.mjs
6.58KB -
instruction-plans/dist/index.node.mjs
6.58KB -
codecs-data-structures/dist/index.browser.mjs
5.04KB -
codecs-data-structures/dist/index.native.mjs
5.03KB -
codecs-data-structures/dist/index.node.mjs
5.03KB -
offchain-messages/dist/index.browser.mjs
4.89KB -
offchain-messages/dist/index.native.mjs
4.89KB -
offchain-messages/dist/index.node.mjs
4.89KB -
transactions/dist/index.browser.mjs
4.07KB -
transactions/dist/index.native.mjs
4.07KB -
transactions/dist/index.node.mjs
4.07KB -
kit/dist/index.browser.mjs
3.72KB -
kit/dist/index.native.mjs
3.72KB -
kit/dist/index.node.mjs
3.72KB -
codecs-core/dist/index.browser.mjs
3.62KB -
codecs-core/dist/index.native.mjs
3.62KB -
codecs-core/dist/index.node.mjs
3.62KB -
webcrypto-ed25519-polyfill/dist/index.node.mj
s
3.61KB -
webcrypto-ed25519-polyfill/dist/index.browser
.mjs
3.59KB -
webcrypto-ed25519-polyfill/dist/index.native.
mjs
3.57KB -
rpc-subscriptions/dist/index.browser.mjs
3.37KB -
rpc-subscriptions/dist/index.node.mjs
3.34KB -
rpc-subscriptions/dist/index.native.mjs
3.31KB -
signers/dist/index.browser.mjs
3.26KB -
signers/dist/index.native.mjs
3.26KB -
signers/dist/index.node.mjs
3.26KB -
rpc-transformers/dist/index.browser.mjs
3.16KB -
rpc-transformers/dist/index.native.mjs
3.16KB -
rpc-transformers/dist/index.node.mjs
3.16KB -
react/dist/index.browser.mjs
3.09KB -
react/dist/index.native.mjs
3.09KB -
react/dist/index.node.mjs
3.09KB -
keys/dist/index.node.mjs
3.06KB -
addresses/dist/index.browser.mjs
2.93KB -
addresses/dist/index.native.mjs
2.92KB -
addresses/dist/index.node.mjs
2.92KB -
keys/dist/index.browser.mjs
2.85KB -
keys/dist/index.native.mjs
2.85KB -
codecs-strings/dist/index.browser.mjs
2.55KB -
codecs-strings/dist/index.node.mjs
2.51KB -
codecs-strings/dist/index.native.mjs
2.47KB -
transaction-confirmation/dist/index.node.mjs
2.41KB -
sysvars/dist/index.browser.mjs
2.37KB -
sysvars/dist/index.native.mjs
2.37KB -
sysvars/dist/index.node.mjs
2.37KB -
transaction-confirmation/dist/index.native.mj
s
2.36KB -
transaction-confirmation/dist/index.browser.m
js
2.35KB -
rpc-subscriptions-spec/dist/index.node.mjs
2.21KB -
rpc-subscriptions-spec/dist/index.native.mjs
2.17KB -
rpc-subscriptions-spec/dist/index.browser.mjs
2.16KB -
subscribable/dist/index.node.mjs
1.97KB -
rpc/dist/index.node.mjs
1.95KB -
codecs-numbers/dist/index.browser.mjs
1.95KB -
codecs-numbers/dist/index.native.mjs
1.95KB -
codecs-numbers/dist/index.node.mjs
1.94KB -
subscribable/dist/index.native.mjs
1.92KB -
subscribable/dist/index.browser.mjs
1.91KB -
rpc-transport-http/dist/index.browser.mjs
1.91KB -
rpc-transport-http/dist/index.native.mjs
1.9KB -
rpc/dist/index.native.mjs
1.81KB -
rpc/dist/index.browser.mjs
1.8KB -
rpc-transport-http/dist/index.node.mjs
1.72KB -
rpc-types/dist/index.browser.mjs
1.53KB -
rpc-types/dist/index.native.mjs
1.53KB -
rpc-types/dist/index.node.mjs
1.53KB -
rpc-subscriptions-channel-websocket/dist/inde
x.node.mjs
1.33KB -
rpc-subscriptions-channel-websocket/dist/inde
x.native.mjs
1.27KB -
rpc-subscriptions-channel-websocket/dist/inde
x.browser.mjs
1.26KB -
program-client-core/dist/index.browser.mjs
1.21KB -
program-client-core/dist/index.native.mjs
1.21KB -
program-client-core/dist/index.node.mjs
1.21KB -
options/dist/index.browser.mjs
1.18KB -
options/dist/index.native.mjs
1.18KB -
options/dist/index.node.mjs
1.17KB -
accounts/dist/index.browser.mjs
1.17KB -
accounts/dist/index.native.mjs
1.17KB -
accounts/dist/index.node.mjs
1.16KB -
rpc-api/dist/index.browser.mjs
976B -
rpc-api/dist/index.native.mjs
975B -
rpc-api/dist/index.node.mjs
973B -
compat/dist/index.browser.mjs
969B -
compat/dist/index.native.mjs
968B -
compat/dist/index.node.mjs
966B -
rpc-spec-types/dist/index.browser.mjs
962B -
rpc-spec-types/dist/index.native.mjs
961B -
rpc-spec-types/dist/index.node.mjs
959B -
rpc-subscriptions-api/dist/index.native.mjs
870B -
rpc-subscriptions-api/dist/index.node.mjs
869B -
rpc-subscriptions-api/dist/index.browser.mjs
868B -
rpc-spec/dist/index.browser.mjs
852B -
rpc-spec/dist/index.native.mjs
851B -
rpc-spec/dist/index.node.mjs
850B -
promises/dist/index.native.mjs
841B -
promises/dist/index.node.mjs
840B -
promises/dist/index.browser.mjs
839B -
plugin-core/dist/index.browser.mjs
820B -
plugin-core/dist/index.native.mjs
819B -
plugin-core/dist/index.node.mjs
817B -
assertions/dist/index.browser.mjs
783B -
instructions/dist/index.browser.mjs
771B -
instructions/dist/index.native.mjs
770B -
instructions/dist/index.node.mjs
768B -
fast-stable-stringify/dist/index.browser.mjs
726B -
fast-stable-stringify/dist/index.native.mjs
725B -
assertions/dist/index.native.mjs
724B -
fast-stable-stringify/dist/index.node.mjs
724B -
assertions/dist/index.node.mjs
723B -
programs/dist/index.browser.mjs
329B -
programs/dist/index.native.mjs
327B -
programs/dist/index.node.mjs
325B -
fs-impl/dist/index.browser.mjs
245B -
event-target-impl/dist/index.node.mjs
230B -
functional/dist/index.browser.mjs
154B -
functional/dist/index.native.mjs
152B -
text-encoding-impl/dist/index.native.mjs
152B -
functional/dist/index.node.mjs
151B -
codecs/dist/index.browser.mjs
145B -
codecs/dist/index.native.mjs
144B -
codecs/dist/index.node.mjs
142B -
event-target-impl/dist/index.browser.mjs
133B -
ws-impl/dist/index.node.mjs
131B -
text-encoding-impl/dist/index.browser.mjs
122B -
fs-impl/dist/index.node.mjs
120B -
text-encoding-impl/dist/index.node.mjs
119B -
ws-impl/dist/index.browser.mjs
113B -
crypto-impl/dist/index.node.mjs
111B -
crypto-impl/dist/index.browser.mjs
109B -
rpc-parsed-types/dist/index.browser.mjs
66B -
rpc-parsed-types/dist/index.native.mjs
65B -
rpc-parsed-types/dist/index.node.mjs
63B -

Total files change +3.98KB +0.77%

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 24, 2026

Documentation Preview: https://kit-docs-7aa2o4lfp-anza-tech.vercel.app

@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_codecs branch from 08d6604 to 9a22f6a Compare April 24, 2026 16:17
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_string_and_number_conversions branch from dec9bf6 to 8e377fb Compare April 24, 2026 16:17
@lorisleiva lorisleiva marked this pull request as ready for review April 24, 2026 16:41
@lorisleiva lorisleiva requested a review from mcintyre94 April 24, 2026 16:41
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_codecs branch from 9a22f6a to a6469c7 Compare April 29, 2026 00:30
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_string_and_number_conversions branch from 8e377fb to 89cd89f Compare April 29, 2026 00:30
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_string_and_number_conversions branch from 89cd89f to f97f875 Compare May 4, 2026 03:59
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_codecs branch from a6469c7 to 82550ec Compare May 4, 2026 03:59
Copy link
Copy Markdown
Member

@mcintyre94 mcintyre94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this implementation looks great!

@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_codecs branch from 82550ec to a49dee0 Compare May 5, 2026 11:17
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_string_and_number_conversions branch 2 times, most recently from 2031a98 to ec8d8d1 Compare May 5, 2026 13:51
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_codecs branch from a49dee0 to 6f5b036 Compare May 5, 2026 13:51
Copy link
Copy Markdown
Member Author

lorisleiva commented May 5, 2026

Merge activity

  • May 5, 8:27 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 5, 8:48 PM UTC: Graphite couldn't merge this pull request because a downstack PR Add fixed-point types #1560 failed to merge.
  • May 5, 9:18 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • May 5, 10:29 PM UTC: Graphite rebased this pull request as part of a merge.
  • May 5, 10:39 PM UTC: @lorisleiva merged this pull request with Graphite.

@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_codecs branch from 6f5b036 to e95504c Compare May 5, 2026 20:53
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_string_and_number_conversions branch from ec8d8d1 to 947f588 Compare May 5, 2026 20:53
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_codecs branch from e95504c to f15d69d Compare May 5, 2026 20:54
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_string_and_number_conversions branch from 947f588 to 9d7fc99 Compare May 5, 2026 20:54
@lorisleiva lorisleiva changed the base branch from 04-24-add_fixed-point_string_and_number_conversions to graphite-base/1568 May 5, 2026 22:17
@lorisleiva lorisleiva changed the base branch from graphite-base/1568 to main May 5, 2026 22:27
This PR adds `getBinaryFixedPointCodec`, `getDecimalFixedPointCodec`, and their encoder/decoder counterparts to `@solana/fixed-points`. Each factory takes a signedness, total bits, scale, and an optional `FixedPointCodecConfig` (`{ endian?: 'le' | 'be' }`, defaults to little-endian), and produces a `FixedSizeCodec` whose byte-size literal is preserved for widths that are multiples of 8 from 8 to 256 bits. Non-byte-aligned total bits throw a `SOLANA_ERROR__FIXED_POINTS__TOTAL_BITS_NOT_BYTE_ALIGNED` error.

The byte-level IO uses `DataView.setBigUint64`/`getBigUint64` for every 64-bit chunk, then greedily consumes the remaining 0-7 bytes with at most one `setUint32`/`setUint16` and a direct byte write. This matches `@solana/codecs-numbers` performance for common widths (u8/u16/u32/u64/u128) and stays efficient for non-standard widths like u24/u40/u72. The read path uses `toArrayBuffer` from `@solana/codecs-core` so it works in environments where `SharedArrayBuffer` is undefined (React Native, non-isolated browsers). In the future, the number codecs in `@solana/codecs-numbers` could delegate to these more generic fixed-point codecs under the hood.
@lorisleiva lorisleiva force-pushed the 04-24-add_fixed-point_codecs branch from f15d69d to 6d87c49 Compare May 5, 2026 22:29
// Full 64-bit chunks. LE lays chunks low-to-high; BE lays higher-order
// chunks at lower memory addresses.
for (let c = 0; c < fullChunks; c++) {
const chunk = (unsigned >> BigInt(c * 64)) & MASK_64;
let consumed = 0;

if (residual - consumed >= 4) {
const chunk = Number((residualChunk >> BigInt(consumed * 8)) & MASK_32);
consumed += 4;
}
if (residual - consumed >= 2) {
const chunk = Number((residualChunk >> BigInt(consumed * 8)) & MASK_16);
consumed += 2;
}
if (residual - consumed >= 1) {
const chunk = Number((residualChunk >> BigInt(consumed * 8)) & MASK_8);
@lorisleiva lorisleiva merged commit 73aa513 into main May 5, 2026
14 checks passed
@lorisleiva lorisleiva deleted the 04-24-add_fixed-point_codecs branch May 5, 2026 22:39
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

🔎💬 Inkeep AI search and chat service is syncing content for source 'Solana Kit Docs'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants