@exponent-labs/i80f48-util 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [0.0.3](https://github.com/exponent-finance/exponent-core/compare/@exponent-labs/i80f48-util@0.0.2...@exponent-labs/i80f48-util@0.0.3) (2025-03-03)
7
+
8
+ **Note:** Version bump only for package @exponent-labs/i80f48-util
9
+
10
+
11
+
12
+
13
+
14
+ ## [0.0.2](https://github.com/exponent-finance/exponent-core/compare/@exponent-labs/i80f48-util@0.0.1...@exponent-labs/i80f48-util@0.0.2) (2025-03-03)
15
+
16
+ **Note:** Version bump only for package @exponent-labs/i80f48-util
@@ -0,0 +1,8 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import BigNumber from "bignumber.js";
4
+ import { Buffer } from "buffer";
5
+ export declare function decodeBufferLE(buffer: Buffer): string;
6
+ export declare function toI80f48(bigNum: BigNumber): BigNumber;
7
+ export declare function encodeI80f48ToBufferLE(bigNum: BigNumber): Buffer;
8
+ export declare function stringToI80f48Buffer(input: string): Buffer;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.stringToI80f48Buffer = exports.encodeI80f48ToBufferLE = exports.toI80f48 = exports.decodeBufferLE = void 0;
7
+ const bignumber_js_1 = __importDefault(require("bignumber.js"));
8
+ const bn_js_1 = __importDefault(require("bn.js"));
9
+ const buffer_1 = require("buffer");
10
+ const FRACTIONAL_BITS = 48;
11
+ const FRACTIONAL_MASK = new bn_js_1.default("FFFFFFFFFFFF", 16); // Mask for the lowest 48 bits
12
+ function decodeBufferLE(buffer) {
13
+ const h = buffer.reverse().toString("hex");
14
+ const bn = new bn_js_1.default(h, 16);
15
+ const integerPart = bn.shrn(FRACTIONAL_BITS); // Shift right to get the integer part
16
+ const fractionalPart = bn.and(FRACTIONAL_MASK);
17
+ const fractionalDecimal = new bignumber_js_1.default(fractionalPart.toString(10)).div(new bignumber_js_1.default(2).pow(FRACTIONAL_BITS));
18
+ const result = new bignumber_js_1.default(integerPart.toString(10)).plus(fractionalDecimal);
19
+ return result.toString();
20
+ }
21
+ exports.decodeBufferLE = decodeBufferLE;
22
+ // Function to convert a BigNumber to i80f48
23
+ function toI80f48(bigNum) {
24
+ const BIT_SHIFT = 48;
25
+ // Shift the fractional part to the integer part
26
+ const shiftedNum = bigNum.multipliedBy(new bignumber_js_1.default(2).pow(BIT_SHIFT)).integerValue();
27
+ return shiftedNum;
28
+ }
29
+ exports.toI80f48 = toI80f48;
30
+ // Function to encode an i80f48 BigNumber to a 128-bit buffer in little-endian format
31
+ function encodeI80f48ToBufferLE(bigNum) {
32
+ // Convert to i80f48 format
33
+ const i80f48Num = toI80f48(bigNum);
34
+ // Create a buffer of 128 bits (16 bytes)
35
+ const buffer = buffer_1.Buffer.alloc(16);
36
+ // Split the BigNumber into two 64-bit parts
37
+ const high = i80f48Num.dividedToIntegerBy(new bignumber_js_1.default(2).pow(64));
38
+ const low = i80f48Num.mod(new bignumber_js_1.default(2).pow(64));
39
+ // Write the low part (64 bits) in little-endian order
40
+ buffer.writeBigUInt64LE(BigInt(low.toFixed()), 0);
41
+ // Write the high part (64 bits) in little-endian order
42
+ buffer.writeBigUInt64LE(BigInt(high.toFixed()), 8);
43
+ return buffer;
44
+ }
45
+ exports.encodeI80f48ToBufferLE = encodeI80f48ToBufferLE;
46
+ // Function to convert a string to an i80f48 buffer
47
+ function stringToI80f48Buffer(input) {
48
+ // Convert the string to a BigNumber
49
+ const bigNum = new bignumber_js_1.default(input);
50
+ // Encode the BigNumber to an i80f48 buffer
51
+ return encodeI80f48ToBufferLE(bigNum);
52
+ }
53
+ exports.stringToI80f48Buffer = stringToI80f48Buffer;
54
+ //# sourceMappingURL=i80f48.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i80f48.js","sourceRoot":"","sources":["../src/i80f48.ts"],"names":[],"mappings":";;;;;;AAAA,gEAAoC;AACpC,kDAAsB;AACtB,mCAA+B;AAE/B,MAAM,eAAe,GAAG,EAAE,CAAA;AAC1B,MAAM,eAAe,GAAG,IAAI,eAAE,CAAC,cAAc,EAAE,EAAE,CAAC,CAAA,CAAC,8BAA8B;AAEjF,SAAgB,cAAc,CAAC,MAAc;IAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC1C,MAAM,EAAE,GAAG,IAAI,eAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACxB,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA,CAAC,sCAAsC;IACnF,MAAM,cAAc,GAAG,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;IAC9C,MAAM,iBAAiB,GAAG,IAAI,sBAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,sBAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAA;IAC/G,MAAM,MAAM,GAAG,IAAI,sBAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAE9E,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAA;AAC1B,CAAC;AATD,wCASC;AACD,4CAA4C;AAC5C,SAAgB,QAAQ,CAAC,MAAiB;IACxC,MAAM,SAAS,GAAG,EAAE,CAAA;IAEpB,gDAAgD;IAChD,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,sBAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,EAAE,CAAA;IAEtF,OAAO,UAAU,CAAA;AACnB,CAAC;AAPD,4BAOC;AAED,qFAAqF;AACrF,SAAgB,sBAAsB,CAAC,MAAiB;IACtD,2BAA2B;IAC3B,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAA;IAElC,yCAAyC;IACzC,MAAM,MAAM,GAAG,eAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAE/B,4CAA4C;IAC5C,MAAM,IAAI,GAAG,SAAS,CAAC,kBAAkB,CAAC,IAAI,sBAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;IACnE,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,sBAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;IAEnD,sDAAsD;IACtD,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAEjD,uDAAuD;IACvD,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAElD,OAAO,MAAM,CAAA;AACf,CAAC;AAlBD,wDAkBC;AAED,mDAAmD;AACnD,SAAgB,oBAAoB,CAAC,KAAa;IAChD,oCAAoC;IACpC,MAAM,MAAM,GAAG,IAAI,sBAAS,CAAC,KAAK,CAAC,CAAA;IAEnC,2CAA2C;IAC3C,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAA;AACvC,CAAC;AAND,oDAMC"}
@@ -0,0 +1 @@
1
+ export * from "./i80f48";
package/build/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./i80f48"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAwB"}
package/jest.config.ts ADDED
@@ -0,0 +1,10 @@
1
+ // jest.config.ts
2
+ import type { Config } from "@jest/types"
3
+
4
+ const config: Config.InitialOptions = {
5
+ preset: "ts-jest",
6
+ testEnvironment: "node",
7
+ testMatch: ["**/*.test.ts"], // Adjust the pattern if your test files have a different naming convention
8
+ }
9
+
10
+ export default config
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@exponent-labs/i80f48-util",
3
+ "version": "0.0.3",
4
+ "main": "build/index.js",
5
+ "types": "build/index.d.ts",
6
+ "license": "AGPL-3.0",
7
+ "scripts": {
8
+ "build": "tsc --build",
9
+ "test": "jest"
10
+ },
11
+ "dependencies": {
12
+ "bignumber.js": "9.1.2",
13
+ "bn.js": "5.2.0"
14
+ },
15
+ "devDependencies": {
16
+ "@types/jest": "^29.5.12",
17
+ "jest": "^29.7.0",
18
+ "ts-jest": "^29.1.2",
19
+ "ts-node": "10.9.2",
20
+ "typescript": "5.4.5"
21
+ },
22
+ "gitHead": "209b8847e9a0fadb5b5ec96b9b47f0ace4a3bf9d"
23
+ }
package/src/i80f48.ts ADDED
@@ -0,0 +1,56 @@
1
+ import BigNumber from "bignumber.js"
2
+ import BN from "bn.js"
3
+ import { Buffer } from "buffer"
4
+
5
+ const FRACTIONAL_BITS = 48
6
+ const FRACTIONAL_MASK = new BN("FFFFFFFFFFFF", 16) // Mask for the lowest 48 bits
7
+
8
+ export function decodeBufferLE(buffer: Buffer): string {
9
+ const h = buffer.reverse().toString("hex")
10
+ const bn = new BN(h, 16)
11
+ const integerPart = bn.shrn(FRACTIONAL_BITS) // Shift right to get the integer part
12
+ const fractionalPart = bn.and(FRACTIONAL_MASK)
13
+ const fractionalDecimal = new BigNumber(fractionalPart.toString(10)).div(new BigNumber(2).pow(FRACTIONAL_BITS))
14
+ const result = new BigNumber(integerPart.toString(10)).plus(fractionalDecimal)
15
+
16
+ return result.toString()
17
+ }
18
+ // Function to convert a BigNumber to i80f48
19
+ export function toI80f48(bigNum: BigNumber): BigNumber {
20
+ const BIT_SHIFT = 48
21
+
22
+ // Shift the fractional part to the integer part
23
+ const shiftedNum = bigNum.multipliedBy(new BigNumber(2).pow(BIT_SHIFT)).integerValue()
24
+
25
+ return shiftedNum
26
+ }
27
+
28
+ // Function to encode an i80f48 BigNumber to a 128-bit buffer in little-endian format
29
+ export function encodeI80f48ToBufferLE(bigNum: BigNumber): Buffer {
30
+ // Convert to i80f48 format
31
+ const i80f48Num = toI80f48(bigNum)
32
+
33
+ // Create a buffer of 128 bits (16 bytes)
34
+ const buffer = Buffer.alloc(16)
35
+
36
+ // Split the BigNumber into two 64-bit parts
37
+ const high = i80f48Num.dividedToIntegerBy(new BigNumber(2).pow(64))
38
+ const low = i80f48Num.mod(new BigNumber(2).pow(64))
39
+
40
+ // Write the low part (64 bits) in little-endian order
41
+ buffer.writeBigUInt64LE(BigInt(low.toFixed()), 0)
42
+
43
+ // Write the high part (64 bits) in little-endian order
44
+ buffer.writeBigUInt64LE(BigInt(high.toFixed()), 8)
45
+
46
+ return buffer
47
+ }
48
+
49
+ // Function to convert a string to an i80f48 buffer
50
+ export function stringToI80f48Buffer(input: string): Buffer {
51
+ // Convert the string to a BigNumber
52
+ const bigNum = new BigNumber(input)
53
+
54
+ // Encode the BigNumber to an i80f48 buffer
55
+ return encodeI80f48ToBufferLE(bigNum)
56
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./i80f48"
@@ -0,0 +1,16 @@
1
+ import { decodeBufferLE, stringToI80f48Buffer } from "./i80f48"
2
+ describe("i80f48-util", () => {
3
+ it("handles 0", () => {
4
+ const n = stringToI80f48Buffer("0")
5
+ expect(n.length).toEqual(16)
6
+ for (let i = 0; i < 16; i++) {
7
+ expect(n[i]).toEqual(0)
8
+ }
9
+ })
10
+
11
+ it("handles rational numbers", () => {
12
+ const n = stringToI80f48Buffer("1.001")
13
+ const s = decodeBufferLE(n)
14
+ expect(parseFloat(s)).toBeCloseTo(1.001)
15
+ })
16
+ })
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "rootDir": "src",
4
+ "sourceMap": true,
5
+ "incremental": true /* Save .tsbuildinfo files to allow for incremental compilation of projects. */,
6
+ "composite": true /* Enable constraints that allow a TypeScript project to be used with project references. */,
7
+ "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
8
+ "module": "CommonJS" /* Specify what module code is generated. */,
9
+ "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
10
+ "outDir": "./build" /* Specify an output folder for all emitted files. */,
11
+ "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
12
+ "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
13
+ "skipLibCheck": true /* Skip type checking all .d.ts files. */
14
+ },
15
+ "include": ["src"],
16
+ "exclude": ["build", "node_modules", "**/*.test.ts"]
17
+ }