diff --git a/kraiken-lib/package-lock.json b/kraiken-lib/package-lock.json index 2c47f7c..58c0c9e 100644 --- a/kraiken-lib/package-lock.json +++ b/kraiken-lib/package-lock.json @@ -226,7 +226,6 @@ "integrity": "sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.2", @@ -2743,7 +2742,6 @@ "integrity": "sha512-F1CBxgqwOMc4GKJ7eY22hWhBVQuMYTtqI8L0FcszYcpYX0fzfDGpez22Xau8Mgm7O9fI+zA/TYIdq3tGWfweBA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.13.0" } @@ -2804,7 +2802,6 @@ "integrity": "sha512-TGf22kon8KW+DeKaUmOibKWktRY8b2NSAZNdtWh798COm1NWx8+xJ6iFBtk3IvLdv6+LGLJLRlyhrhEDZWargQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.45.0", "@typescript-eslint/types": "8.45.0", @@ -3416,7 +3413,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3741,7 +3737,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", @@ -4530,7 +4525,6 @@ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -5228,7 +5222,6 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz", "integrity": "sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw==", "license": "MIT", - "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -5311,9 +5304,8 @@ "version": "5.16.0", "resolved": "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz", "integrity": "sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A==", - "devOptional": true, + "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -7220,7 +7212,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -8155,9 +8146,8 @@ "version": "5.4.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8364,7 +8354,6 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -8463,7 +8452,6 @@ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", @@ -8679,7 +8667,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.0.0" }, diff --git a/kraiken-lib/src/subgraph.ts b/kraiken-lib/src/subgraph.ts index fe7fe23..e8e73f8 100644 --- a/kraiken-lib/src/subgraph.ts +++ b/kraiken-lib/src/subgraph.ts @@ -9,8 +9,8 @@ export function bytesToUint256LittleEndian(bytes: Uint8Array): bigint { } export function uint256ToBytesLittleEndian(value: bigint): Uint8Array { - const bytes = new Uint8Array(4); - for (let i = 0; i < 4; i++) { + const bytes = new Uint8Array(32); + for (let i = 0; i < 32; i++) { bytes[i] = Number((value >> (8n * BigInt(i))) & 0xffn); } return bytes; diff --git a/kraiken-lib/src/tests/functions.test.ts b/kraiken-lib/src/tests/functions.test.ts index c2adc01..cc6e74a 100644 --- a/kraiken-lib/src/tests/functions.test.ts +++ b/kraiken-lib/src/tests/functions.test.ts @@ -4,7 +4,9 @@ import { bytesToUint256LittleEndian, uint256ToBytesLittleEndian } from '../subgr describe('BigInt Conversion Functions', () => { test('converts uint256 to bytes and back (little endian)', () => { const mockId = uint256ToBytesLittleEndian(3n); - expect(mockId).toEqual(new Uint8Array([3, 0, 0, 0])); + const expected = new Uint8Array(32); + expected[0] = 3; + expect(mockId).toEqual(expected); expect(bytesToUint256LittleEndian(mockId)).toEqual(3n); }); }); diff --git a/kraiken-lib/src/tests/subgraph.test.ts b/kraiken-lib/src/tests/subgraph.test.ts index c17c9ad..647648c 100644 --- a/kraiken-lib/src/tests/subgraph.test.ts +++ b/kraiken-lib/src/tests/subgraph.test.ts @@ -2,39 +2,57 @@ import { describe, expect, test } from 'vitest'; import { bytesToUint256LittleEndian, uint256ToBytesLittleEndian } from '../subgraph.js'; describe('uint256ToBytesLittleEndian', () => { - test('converts zero to four zero bytes', () => { - expect(uint256ToBytesLittleEndian(0n)).toEqual(new Uint8Array([0, 0, 0, 0])); + test('converts zero to 32 zero bytes', () => { + expect(uint256ToBytesLittleEndian(0n)).toEqual(new Uint8Array(32)); }); - test('converts 1 to [1, 0, 0, 0]', () => { - expect(uint256ToBytesLittleEndian(1n)).toEqual(new Uint8Array([1, 0, 0, 0])); + test('converts 1 to [1, ...31 zeros]', () => { + const expected = new Uint8Array(32); + expected[0] = 1; + expect(uint256ToBytesLittleEndian(1n)).toEqual(expected); }); - test('converts 3 to [3, 0, 0, 0]', () => { + test('converts 3 to [3, ...31 zeros]', () => { const result = uint256ToBytesLittleEndian(3n); let hexString = '0x'; for (let i = 0; i < result.length; i++) { hexString += result[i].toString(16).padStart(2, '0'); } - expect(hexString).toEqual('0x03000000'); + expect(hexString).toEqual('0x03' + '00'.repeat(31)); }); - test('converts 256 to [0, 1, 0, 0] (second byte)', () => { - expect(uint256ToBytesLittleEndian(256n)).toEqual(new Uint8Array([0, 1, 0, 0])); + test('converts 256 to [0, 1, ...30 zeros] (second byte)', () => { + const expected = new Uint8Array(32); + expected[1] = 1; + expect(uint256ToBytesLittleEndian(256n)).toEqual(expected); }); - test('converts 65536 to [0, 0, 1, 0] (third byte)', () => { - expect(uint256ToBytesLittleEndian(65536n)).toEqual(new Uint8Array([0, 0, 1, 0])); + test('converts 65536 to [0, 0, 1, ...29 zeros] (third byte)', () => { + const expected = new Uint8Array(32); + expected[2] = 1; + expect(uint256ToBytesLittleEndian(65536n)).toEqual(expected); }); - test('converts 16777216 (2^24) to [0, 0, 0, 1] (fourth byte)', () => { - expect(uint256ToBytesLittleEndian(16777216n)).toEqual(new Uint8Array([0, 0, 0, 1])); + test('converts 16777216 (2^24) to [0, 0, 0, 1, ...28 zeros] (fourth byte)', () => { + const expected = new Uint8Array(32); + expected[3] = 1; + expect(uint256ToBytesLittleEndian(16777216n)).toEqual(expected); }); - test('returns a 4-byte Uint8Array', () => { + test('converts 2^32 to [0, 0, 0, 0, 1, ...27 zeros] (fifth byte)', () => { + const expected = new Uint8Array(32); + expected[4] = 1; + expect(uint256ToBytesLittleEndian(2n ** 32n)).toEqual(expected); + }); + + test('converts max uint256 to all 0xff bytes', () => { + expect(uint256ToBytesLittleEndian(2n ** 256n - 1n)).toEqual(new Uint8Array(32).fill(255)); + }); + + test('returns a 32-byte Uint8Array', () => { const result = uint256ToBytesLittleEndian(12345n); expect(result).toBeInstanceOf(Uint8Array); - expect(result.length).toBe(4); + expect(result.length).toBe(32); }); }); @@ -69,4 +87,12 @@ describe('roundtrip: uint256ToBytesLittleEndian -> bytesToUint256LittleEndian', expect(bytesToUint256LittleEndian(bytes)).toBe(val); } }); + + test('roundtrip preserves values >= 2^32', () => { + const values = [2n ** 32n, 2n ** 32n + 1n, 2n ** 128n, 2n ** 256n - 1n]; + for (const val of values) { + const bytes = uint256ToBytesLittleEndian(val); + expect(bytesToUint256LittleEndian(bytes)).toBe(val); + } + }); }); diff --git a/kraiken-lib/yarn.lock b/kraiken-lib/yarn.lock index 32881f1..d362fb5 100644 --- a/kraiken-lib/yarn.lock +++ b/kraiken-lib/yarn.lock @@ -78,7 +78,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.1.tgz" integrity sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.14.0", "@babel/core@^7.22.9": +"@babel/core@^7.14.0", "@babel/core@^7.22.9": version "7.24.3" resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.3.tgz" integrity sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ== @@ -1250,7 +1250,7 @@ resolved "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.36.tgz" integrity sha512-b7bq23s4fgBB76n34m2b3RBf6M369B0Z9uRR8aHTMd8kZISRkmDEpPD8hhpYvDFzr3bJCPES96cm3Q6qRNDbQw== -"@types/node@*", "@types/node@^18.0.0 || ^20.0.0 || >=22.0.0", "@types/node@^20.19.0 || >=22.12.0", "@types/node@^24.6.0", "@types/node@>=13": +"@types/node@*", "@types/node@^24.6.0": version "24.6.0" resolved "https://registry.npmjs.org/@types/node/-/node-24.6.0.tgz" integrity sha512-F1CBxgqwOMc4GKJ7eY22hWhBVQuMYTtqI8L0FcszYcpYX0fzfDGpez22Xau8Mgm7O9fI+zA/TYIdq3tGWfweBA== @@ -1538,7 +1538,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.15.0: +acorn@^8.15.0: version "8.15.0" resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -1755,7 +1755,7 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.22.2, "browserslist@>= 4.21.0": +browserslist@^4.22.2: version "4.23.0" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -2268,7 +2268,7 @@ eslint-visitor-keys@^4.2.1: resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz" integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== -"eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^8.57.0 || ^9.0.0", eslint@^9.36.0: +eslint@^9.36.0: version "9.36.0" resolved "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz" integrity sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ== @@ -2653,12 +2653,12 @@ graphql-tag@^2.11.0, graphql-tag@^2.12.6: dependencies: tslib "^2.1.0" -graphql-ws@^5.14.0, graphql-ws@^5.5.5: +graphql-ws@^5.14.0: version "5.16.0" resolved "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.16.0.tgz" integrity sha512-Ju2RCU2dQMgSKtArPbEtsK5gNLnsQyTNIo/T7cZNp96niC1x0KdJNZV0TIoilceBPQwfb5itrGl8pkFeOUMl4A== -graphql@*, "graphql@^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "graphql@^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "graphql@^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "graphql@^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", "graphql@^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "graphql@^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", "graphql@^15.0.0 || ^16.0.0", graphql@^16.8.1, "graphql@>=0.11 <=16", "graphql@14 - 16": +graphql@^16.8.1: version "16.8.1" resolved "https://registry.npmjs.org/graphql/-/graphql-16.8.1.tgz" integrity sha512-59LZHPdGZVh695Ud9lRzPBVTtlX9ZCV150Er2W43ro37wVof0ctenSaskPPjN7lVTIN8mSZt8PHUNKZuNQUuxw== @@ -2974,7 +2974,7 @@ jackspeak@^3.1.2: optionalDependencies: "@pkgjs/parseargs" "^0.11.0" -jiti@*, jiti@^1.17.1, jiti@^1.18.2, jiti@>=1.21.0: +jiti@^1.17.1, jiti@^1.18.2: version "1.21.0" resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz" integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== @@ -3614,7 +3614,7 @@ picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -"picomatch@^3 || ^4", picomatch@^4.0.2, picomatch@^4.0.3: +picomatch@^4.0.2, picomatch@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== @@ -4243,7 +4243,7 @@ type-fest@^0.21.3: resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -typescript@^5.4.3, typescript@>=4.8.4, "typescript@>=4.8.4 <6.0.0", typescript@>=4.9.5, typescript@>=5.0.4, typescript@>=5.4.0: +typescript@^5.4.3: version "5.4.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz" integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg== @@ -4358,7 +4358,7 @@ vite-node@3.2.4: optionalDependencies: fsevents "~2.3.3" -vitest@^3.0.0, vitest@3.2.4: +vitest@^3.0.0: version "3.2.4" resolved "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz" integrity sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A== @@ -4498,7 +4498,7 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@*, ws@^8.12.0, ws@^8.13.0, ws@^8.15.0, ws@8.18.3: +ws@^8.12.0, ws@^8.13.0, ws@^8.15.0, ws@8.18.3: version "8.18.3" resolved "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz" integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== @@ -4528,7 +4528,7 @@ yaml-ast-parser@^0.0.43: resolved "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz" integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== -yaml@^2.3.1, yaml@^2.4.2, yaml@^2.8.1: +yaml@^2.3.1, yaml@^2.8.1: version "2.8.1" resolved "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz" integrity sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==