Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libraries/type-length-value/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Library with utilities for working with Type-Length-Value structures in js.
import { TlvState, SplDiscriminator } from '@solana/spl-type-length-value';

const tlv = new TlvState(tlvData, discriminatorSize, lengthSize);
const discriminator = splDiscriminate("<discriminator-hash-input>", discriminatorSize);
const discriminator = await splDiscriminate("<discriminator-hash-input>", discriminatorSize);

const firstValue = tlv.firstBytes(discriminator);

Expand Down
3 changes: 2 additions & 1 deletion libraries/type-length-value/js/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@solana/spl-type-length-value",
"description": "SPL Type Length Value Library",
"version": "0.1.0",
"version": "0.2.0",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Breaking change.

"author": "Solana Labs Maintainers <[email protected]>",
"repository": "https://github.com/solana-labs/solana-program-library",
"license": "Apache-2.0",
Expand Down Expand Up @@ -43,6 +43,7 @@
"watch": "tsc --build --verbose --watch tsconfig.all.json"
},
"dependencies": {
"@solana/assertions": "^2.0.0-rc.1",
"buffer": "^6.0.3"
},
"devDependencies": {
Expand Down
12 changes: 7 additions & 5 deletions libraries/type-length-value/js/src/splDiscriminate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { createHash } from 'crypto';
import { assertDigestCapabilityIsAvailable } from '@solana/assertions';

export const splDiscriminate = (discriminator: string, length = 8): Buffer => {
const digest = createHash('sha256').update(discriminator).digest();
return digest.subarray(0, length);
};
export async function splDiscriminate(discriminator: string, length = 8): Promise<Uint8Array> {
assertDigestCapabilityIsAvailable();
const bytes = new TextEncoder().encode(discriminator);
const digest = await crypto.subtle.digest('SHA-256', bytes);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ugh. crypto wasn't added as a global until Node 19. Node 20 is presently LTS.

Our choices are:

  1. Elevate the requirements to Node 19, or
  2. Introduce a dual-build Node/Browser system like we have in @solana/web3.js to solana-program-library.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can keep it simple and elevate the requirement for this package to Node 19. Considering it'll become a dev dependency for the two packages that use it, I can't see any drawbacks. Are there any other potential negative consequences that I'm missing?

Copy link
Contributor

Choose a reason for hiding this comment

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

As part of that change, can you also update CI to only run the 'libraries' step for node v20?

node-version: [16.x, 18.x, 20.x]
package:
[
account-compression,
libraries,
memo,
name-service,
stake-pool,
token,
token-group,
token-metadata,
token-swap,
]
include:
# Restrict single-pool and token-lending to supported Node.js versions.
- package: single-pool
node-version: 20.5
- package: token-lending
node-version: 18.5

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Totally.

return new Uint8Array(digest).subarray(0, length);
}
31 changes: 16 additions & 15 deletions libraries/type-length-value/js/test/splDiscriminate.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import { expect } from 'chai';
import { splDiscriminate } from '../src/splDiscriminate';
import { createHash } from 'crypto';

describe('splDiscrimintor', () => {
const testVectors = [
'hello',
'this-is-a-test',
'test-namespace:this-is-a-test',
'test-namespace:this-is-a-test:with-a-longer-name',
];
const testVectors = [
'hello',
'this-is-a-test',
'test-namespace:this-is-a-test',
'test-namespace:this-is-a-test:with-a-longer-name',
];

const testExpectedBytes = testVectors.map(x => {
return createHash('sha256').update(x).digest();
});
const testExpectedBytes = await Promise.all(
testVectors.map(x =>
crypto.subtle.digest('SHA-256', new TextEncoder().encode(x)).then(digest => new Uint8Array(digest)),
),
);

const testSplDiscriminator = (length: number) => {
describe('splDiscrimintor', () => {
const testSplDiscriminator = async (length: number) => {
for (let i = 0; i < testVectors.length; i++) {
const discriminator = splDiscriminate(testVectors[i], length);
const discriminator = await splDiscriminate(testVectors[i], length);
const expectedBytes = testExpectedBytes[i].subarray(0, length);
expect(discriminator).to.have.length(length);
expect(discriminator).to.deep.equal(expectedBytes);
Expand All @@ -29,9 +30,9 @@ describe('splDiscrimintor', () => {
testSplDiscriminator(2);
});

it('should produce the same bytes as rust library', () => {
it('should produce the same bytes as rust library', async () => {
const expectedBytes = Buffer.from([105, 37, 101, 197, 75, 251, 102, 26]);
const discriminator = splDiscriminate('spl-transfer-hook-interface:execute');
const discriminator = await splDiscriminate('spl-transfer-hook-interface:execute');
expect(discriminator).to.deep.equal(expectedBytes);
});
});
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading